diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
commit | dc74177b8c1a750d4108ed0b9b5099399672dbb3 (patch) | |
tree | f6472119ccb061b6fc5a63aa5d76f34e6dedd708 |
Initial revisionXORG-STABLE
-rw-r--r-- | DRI.txt | 407 | ||||
-rw-r--r-- | README.pm3 | 57 | ||||
-rw-r--r-- | man/glint.man | 110 | ||||
-rw-r--r-- | src/IBMramdac.c | 125 | ||||
-rw-r--r-- | src/TIramdac.c | 232 | ||||
-rw-r--r-- | src/glint.h | 365 | ||||
-rw-r--r-- | src/glint_common.h | 63 | ||||
-rw-r--r-- | src/glint_dga.c | 273 | ||||
-rw-r--r-- | src/glint_dri.c | 1955 | ||||
-rw-r--r-- | src/glint_dri.h | 123 | ||||
-rw-r--r-- | src/glint_dripriv.h | 296 | ||||
-rw-r--r-- | src/glint_driver.c | 3875 | ||||
-rw-r--r-- | src/glint_regs.h | 1361 | ||||
-rw-r--r-- | src/glint_shadow.c | 46 | ||||
-rw-r--r-- | src/pm2_accel.c | 1487 | ||||
-rw-r--r-- | src/pm2_dac.c | 506 | ||||
-rw-r--r-- | src/pm2_video.c | 3204 | ||||
-rw-r--r-- | src/pm2ramdac.c | 165 | ||||
-rw-r--r-- | src/pm2v_dac.c | 567 | ||||
-rw-r--r-- | src/pm2vramdac.c | 64 | ||||
-rw-r--r-- | src/pm3_accel.c | 1223 | ||||
-rw-r--r-- | src/pm3_dac.c | 842 | ||||
-rw-r--r-- | src/pm3_regs.h | 1111 | ||||
-rw-r--r-- | src/pm3_video.c | 1322 | ||||
-rw-r--r-- | src/pm_accel.c | 1199 | ||||
-rw-r--r-- | src/pm_dac.c | 251 | ||||
-rw-r--r-- | src/sx_accel.c | 872 | ||||
-rw-r--r-- | src/tx_accel.c | 961 | ||||
-rw-r--r-- | src/tx_dac.c | 397 |
29 files changed, 23459 insertions, 0 deletions
@@ -0,0 +1,407 @@ + + GLINT State Transition Strategy + + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is granted to make and distribute verbatim copies +of this document provided the copyright notice and this permission +notice are preserved on all copies. + +$XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt,v 1.2 2000/02/23 04:47:06 martin Exp $ + +GLINT State Transition Strategy + +Direct Rendering requires a coordinated method of state management +across all drivers accessing this device. This document defines the +expected behavior of all drivers participating in direct rendering with +this device. + +Currently only the GMX2000 supports direct rendering. + + +Section 1) State Transition Types + +The direct rendering document entitled "state-mgmt.txt" gives a device +independent overview on the different types of state transitions. This +section gives a more detailed description of GLINT specific hardware state. + +No context switch--no state saves or restores will be done for transitions, +however the device can be busy executing commands from previous accesses to +the device. + +X context switch--the intersection of 2D and 3D state will be saved +and restored. This is the state marked as DDX/3DClient in Appendix A. +The device will be synced and idle after this switch. + +3D context switch--all 3D state will be saved and restored. 3D state is +defined as all registered owned by the 3DClient driver. See Appendix A +for more details. The device will be synced and idle after this switch. + +The registers owned by the DRM kernel module and submodules are not +managed by context switches. + + +Section 2) VT Switching and DGA Access + +VT Switching away from the X Server or client access to the device +framebuffer via DGA require the device to be locked away from 3D direct +rendering accesses. The X Server will hold the lock on behalf of these +services until access is restored. + + +Section 3) Potential Optimizations + +Lighten the number of registers required for context switches by using a +mechanism to determine whether stipple or pattern registers need to be +saved/restored. This optimization has not been done for the initial +direct rendering infrastructure sample implementation. + + +Appendix A: GMX2000 Register Ownership + +driver column contains: + DDX - DDX driver manages register + DRM - DRM or DRM subdriver manages register + 3DClient - 3D Client Driver manges register + DDX/3DClient, DDX/DRM, 3DClient/DRM - register access is shared + +if the RO (read only) column is marked with a *, then no writes are +permitted to this register, and thus no drivers own it. + +primary and secondary columns contain the default values after +initialization. primary is the master rasterizer, secondary is the +slave rasterizer. + + +Name offset primary secondary RO driver +------------------------------------------------------------------------------ +ResetStatus o=0000 0x00000000 0x00000000 DDX/DRM +IntEnable o=0008 0x00000000 0x00000000 DRM +IntFlags o=0010 0x00000000 0x00000018 DRM +InFIFOSpace o=0018 0x00000000 0x00000021 * +OutFIFOWords o=0020 0x00000000 0x00000000 * +DMAAddress o=0028 0x00000000 0x00000000 DRM +DMACount o=0030 0x00000000 0x00000000 DRM +ErrorFlags o=0038 0x00000000 0x00000002 DRM +VClkCtl o=0040 0x00000000 0x00000000 DDX +TestRegister o=0048 0x00000000 0x00000000 DDX +Aperture0 o=0050 0x00000000 0x00000000 DDX +Aperture1 o=0058 0x00000000 0x00000000 DDX +DMAControl o=0060 0x00000000 0x00000000 DRM +FIFODis o=0068 0x00000000 0x00000001 DDX +LBMemoryCtl o=1000 0x00000000 0x770883ff DDX +LBMemoryEDO o=1008 0x00000000 0x77080000 DDX +FBMemoryCtl o=1800 0x00000000 0x63c00800 DDX +FBModeSel o=1808 0x00000000 0x00000907 DDX +FBGCWrMask o=1810 0x00000000 0xffffffff * +FBGCColorLower o=1818 0x00000000 0x00828282 * +FBTXMemCtl o=1820 0x00000000 0x00000002 DDX +FBWrMask o=1830 0x00000000 0xffffffff * +FBGCColorUpper o=1838 0x00000000 0x00828282 * +VTGHLimit o=3000 0x00000000 0x000000c8 DDX +VTGHSyncStart o=3008 0x00ffffff 0x00000006 DDX +VTGHSyncEnd o=3010 0x00000000 0x00000016 DDX +VTGHBlankEnd o=3018 0x00ffffff 0x00000028 DDX +VTGVLimit o=3020 0x00000000 0x000001fb DDX +VTGVSyncStart o=3028 0x00ffffff 0x00000004 DDX +VTGVSyncEnd o=3030 0x00000000 0x0000000a DDX +VTGVBlankEnd o=3038 0x00ffffff 0x0000001b DDX +VTGHGateStart o=3040 0x00000000 0x00000027 DDX +VTGHGateEnd o=3048 0x00ffffff 0x000000c7 DDX +VTGVGateStart o=3050 0x00000000 0x0000001a DDX +VTGVGateEnd o=3058 0x00ffffff 0x0000001b DDX +VTGPolarity o=3060 0x00000000 0x000000ba DDX +VTGFrameRowAddr o=3068 0x00ffffff 0x00000000 DDX +VTGVLineNumber o=3070 0x00000000 0x00000079 DDX +VTGSerialClk o=3078 0x00ffffff 0x00000002 DDX +VTGModeCtl o=3080 0x00000000 0x00000000 DDX +GInFIFOSpace o=0018 0x00000000 * +GDMAAddress o=0028 0x00000000 DRM +GDMACount o=0030 0x00000000 DRM +GDMAControl o=0060 0x00000000 DRM +GOutDMA o=0080 0x00000000 DRM +GOutDMACount o=0088 0x00000000 DRM +GResetStatus o=0800 0x00000000 DRM +GIntEnable o=0808 0x00000000 DRM +GIntFlags o=0810 0x00000000 DRM +GErrorFlags o=0838 0x00000000 DRM +GTestRegister o=0848 0x00000000 DDX +GFIFODis o=0868 0x00000000 DDX +GChipConfig o=0870 0x00000000 DDX +GCSRAperture o=0878 0x00000000 DDX +GPageTableAddr o=0c00 0x00000000 DRM +GPageTableLength o=0c08 0x00000000 DRM +GDelayTimer o=0c38 0x00000000 DRM +GCommandMode o=0c40 0x00000000 DRM +GCommandIntEnable o=0c48 0x00000000 DRM +GCommandIntFlags o=0c50 0x00000000 DRM +GCommandErrorFlags o=0c58 0x00000000 DRM +GCommandStatus o=0c60 0x00000000 * +GCommandFaultingAddr o=0c68 0x00000000 * +GVertexFaultingAddr o=0c70 0x00000000 * +GWriteFaultingAddr o=0c88 0x00000000 * +GFeedbackSelectCount o=0c98 0x00000000 * +GGammaProcessorMode o=0cb8 0x00000000 DDX +GVGAShadow o=0d00 0x00000000 DDX +GMultGLINTAperture o=0d08 0x00000000 DDX +GMultGLINT1 o=0d10 0x00000000 DDX +GMultGLINT2 o=0d18 0x00000000 DDX +StartXDom t=0000 undefined undefined DDX/3DClient +dXDom t=0001 undefined undefined DDX/3DClient +StartXSub t=0002 undefined undefined DDX/3DClient +dXSub t=0003 undefined undefined DDX/3DClient +StartY t=0004 undefined undefined DDX/3DClient +dY t=0005 undefined undefined DDX/3DClient +GLINTCount t=0006 undefined undefined DDX/3DClient +PointTable0 t=0010 undefined undefined DDX/3DClient +PointTable1 t=0011 undefined undefined DDX/3DClient +PointTable2 t=0012 undefined undefined DDX/3DClient +PointTable3 t=0013 undefined undefined DDX/3DClient +RasterizerMode t=0014 undefined undefined DDX/3DClient +YLimits t=0015 undefined undefined DDX/3DClient +ScanLineOwnership t=0016 0x00000001 0x00000005 DDX +PixelSize t=0018 undefined undefined DDX/3DClient +ScissorMode t=0030 undefined undefined DDX/3DClient +ScissorMinXY t=0031 undefined undefined DDX/3DClient +ScissorMaxXY t=0032 undefined undefined DDX/3DClient +ScreenSize t=0033 undefined undefined DDX/3DClient +AreaStippleMode t=0034 undefined undefined DDX/3DClient +LineStippleMode t=0035 undefined undefined DDX/3DClient +LoadLineStippleCounters t=0036 undefined undefined DDX/3DClient +WindowOrigin t=0039 undefined undefined DDX/3DClient +AreaStipplePattern0 t=0040 undefined undefined DDX/3DClient +AreaStipplePattern1 t=0041 undefined undefined DDX/3DClient +AreaStipplePattern2 t=0042 undefined undefined DDX/3DClient +AreaStipplePattern3 t=0043 undefined undefined DDX/3DClient +AreaStipplePattern4 t=0044 undefined undefined DDX/3DClient +AreaStipplePattern5 t=0045 undefined undefined DDX/3DClient +AreaStipplePattern6 t=0046 undefined undefined DDX/3DClient +AreaStipplePattern7 t=0047 undefined undefined DDX/3DClient +AreaStipplePattern8 t=0048 undefined undefined DDX/3DClient +AreaStipplePattern9 t=0049 undefined undefined DDX/3DClient +AreaStipplePattern10 t=004a undefined undefined DDX/3DClient +AreaStipplePattern11 t=004b undefined undefined DDX/3DClient +AreaStipplePattern12 t=004c undefined undefined DDX/3DClient +AreaStipplePattern13 t=004d undefined undefined DDX/3DClient +AreaStipplePattern14 t=004e undefined undefined DDX/3DClient +AreaStipplePattern15 t=004f undefined undefined DDX/3DClient +AreaStipplePattern16 t=0050 undefined undefined DDX/3DClient +AreaStipplePattern17 t=0051 undefined undefined DDX/3DClient +AreaStipplePattern18 t=0052 undefined undefined DDX/3DClient +AreaStipplePattern19 t=0053 undefined undefined DDX/3DClient +AreaStipplePattern20 t=0054 undefined undefined DDX/3DClient +AreaStipplePattern21 t=0055 undefined undefined DDX/3DClient +AreaStipplePattern22 t=0056 undefined undefined DDX/3DClient +AreaStipplePattern23 t=0057 undefined undefined DDX/3DClient +AreaStipplePattern24 t=0058 undefined undefined DDX/3DClient +AreaStipplePattern25 t=0059 undefined undefined DDX/3DClient +AreaStipplePattern26 t=005a undefined undefined DDX/3DClient +AreaStipplePattern27 t=005b undefined undefined DDX/3DClient +AreaStipplePattern28 t=005c undefined undefined DDX/3DClient +AreaStipplePattern29 t=005d undefined undefined DDX/3DClient +AreaStipplePattern30 t=005e undefined undefined DDX/3DClient +AreaStipplePattern31 t=005f undefined undefined DDX/3DClient +RouterMode t=0108 undefined undefined DDX/3DClient +TextureAddressMode t=0070 undefined undefined DDX/3DClient +SStart t=0071 undefined undefined 3DClient +dSdx t=0072 undefined undefined 3DClient +dSdyDom t=0073 undefined undefined 3DClient +TStart t=0074 undefined undefined 3DClient +dTdx t=0075 undefined undefined 3DClient +dTdyDom t=0076 undefined undefined 3DClient +QStart t=0077 undefined undefined 3DClient +dQdx t=0078 undefined undefined 3DClient +dQdyDom t=0079 undefined undefined 3DClient +LOD t=007a undefined undefined 3DClient +dSdy t=007b undefined undefined 3DClient +dTdy t=007c undefined undefined 3DClient +dQdy t=007d undefined undefined 3DClient +TextureReadMode t=0090 undefined undefined DDX/3DClient +TextureFormat t=0091 undefined undefined 3DClient +TextureCacheControl t=0092 undefined undefined 3DClient +GLINTBorderColor t=0095 undefined undefined 3DClient +TexelLUTIndex t=0098 undefined undefined 3DClient +TexelLUTData t=0099 undefined undefined 3DClient +TexelLUTAddress t=009a undefined undefined 3DClient +TexelLUTTransfer t=009b undefined undefined 3DClient +TextureFilterMode t=009c undefined undefined 3DClient +TextureChromaUpper t=009d undefined undefined 3DClient +TextureChromaLower t=009e undefined undefined 3DClient +TxBaseAddr0 t=00a0 undefined undefined 3DClient +TxBaseAddr1 t=00a1 undefined undefined 3DClient +TxBaseAddr2 t=00a2 undefined undefined 3DClient +TxBaseAddr3 t=00a3 undefined undefined 3DClient +TxBaseAddr4 t=00a4 undefined undefined 3DClient +TxBaseAddr5 t=00a5 undefined undefined 3DClient +TxBaseAddr6 t=00a6 undefined undefined 3DClient +TxBaseAddr7 t=00a7 undefined undefined 3DClient +TxBaseAddr8 t=00a8 undefined undefined 3DClient +TxBaseAddr9 t=00a9 undefined undefined 3DClient +TxBaseAddr10 t=00aa undefined undefined 3DClient +TxBaseAddr11 t=00ab undefined undefined 3DClient +TexelLUT0 t=01d0 undefined undefined 3DClient +TexelLUT1 t=01d1 undefined undefined 3DClient +TexelLUT2 t=01d2 undefined undefined 3DClient +TexelLUT3 t=01d3 undefined undefined 3DClient +TexelLUT4 t=01d4 undefined undefined 3DClient +TexelLUT5 t=01d5 undefined undefined 3DClient +TexelLUT6 t=01d6 undefined undefined 3DClient +TexelLUT7 t=01d7 undefined undefined 3DClient +TexelLUT8 t=01d8 undefined undefined 3DClient +TexelLUT9 t=01d9 undefined undefined 3DClient +TexelLUT10 t=01da undefined undefined 3DClient +TexelLUT11 t=01db undefined undefined 3DClient +TexelLUT12 t=01dc undefined undefined 3DClient +TexelLUT13 t=01dd undefined undefined 3DClient +TexelLUT14 t=01de undefined undefined 3DClient +TexelLUT15 t=01df undefined undefined 3DClient +Texel0 t=00c0 undefined undefined 3DClient +Texel1 t=00c1 undefined undefined 3DClient +Texel2 t=00c2 undefined undefined 3DClient +Texel3 t=00c3 undefined undefined 3DClient +Texel4 t=00c4 undefined undefined 3DClient +Texel5 t=00c5 undefined undefined 3DClient +Texel6 t=00c6 undefined undefined 3DClient +Texel7 t=00c7 undefined undefined 3DClient +Interp0 t=00c8 undefined undefined 3DClient +Interp1 t=00c9 undefined undefined 3DClient +Interp2 t=00ca undefined undefined 3DClient +Interp3 t=00cb undefined undefined 3DClient +Interp4 t=00cc undefined undefined 3DClient +TextureFilter t=00cd undefined undefined 3DClient +TextureColorMode t=00d0 undefined undefined DDX/3DClient +TextureEnvColor t=00d1 undefined undefined 3DClient +FogMode t=00d2 undefined undefined DDX/3DClient +FogColor t=00d3 undefined undefined 3DClient +FStart t=00d4 undefined undefined 3DClient +dFdx t=00d5 undefined undefined 3DClient +dFdyDom t=00d6 undefined undefined 3DClient +KsStart t=00d9 undefined undefined 3DClient +dKsdx t=00da undefined undefined 3DClient +dKsdyDom t=00db undefined undefined 3DClient +KdStart t=00dc undefined undefined 3DClient +dKdStart t=00dd undefined undefined 3DClient +dKddyDom t=00de undefined undefined 3DClient +RStart t=00f0 undefined undefined 3DClient +dRdx t=00f1 undefined undefined 3DClient +dRdyDom t=00f2 undefined undefined 3DClient +GStart t=00f3 undefined undefined 3DClient +dGdx t=00f4 undefined undefined 3DClient +dGdyDom t=00f5 undefined undefined 3DClient +BStart t=00f6 undefined undefined 3DClient +dBdx t=00f7 undefined undefined 3DClient +dBdyDom t=00f8 undefined undefined 3DClient +AStart t=00f9 undefined undefined 3DClient +dAdx t=00fa undefined undefined 3DClient +dAdyDom t=00fb undefined undefined 3DClient +ColorDDAMode t=00fc undefined undefined DDX/3DClient +ConstantColor t=00fd undefined undefined 3DClient +GLINTColor t=00fe undefined undefined DDX/3DClient +AlphaTestMode t=0100 undefined undefined DDX/3DClient +AntialiasMode t=0101 undefined undefined DDX/3DClient +AlphaBlendMode t=0102 undefined undefined DDX/3DClient +ChromaUpper t=01e1 undefined undefined 3DClient +ChromaLower t=01e2 undefined undefined 3DClient +ChromaTestMode t=01e3 undefined undefined 3DClient +DitherMode t=0103 undefined undefined DDX/3DClient +FBSoftwareWriteMask t=0104 undefined undefined DDX/3DClient +LogicalOpMode t=0105 undefined undefined DDX/3DClient +FBWriteData t=0106 undefined undefined DDX/3DClient +LBReadMode t=0110 undefined undefined DDX/3DClient + Partial Product bit 0-5 need by 3DClient +LBReadFormat t=0111 set by DDX set by DDX DDX +LBSourceOffset t=0112 undefined undefined DDX/3DClient +LBStencil t=0115 undefined undefined * +LBDepth t=0116 undefined undefined * +LBWindowBase t=0117 undefined undefined DDX/3DClient +LBWriteMode t=0118 undefined undefined DDX/3DClient +LBWriteFormat t=0119 set by DDX set by DDX DDX +TextureDownloadOffset t=011e undefined undefined DDX/3DClient +LBWindowOffset t=011f undefined undefined DDX/3DClient +GLINTWindow t=0130 undefined undefined DDX/3DClient +StencilMode t=0131 undefined undefined DDX/3DClient +StencilData t=0132 undefined undefined 3DClient +GLINTStencil t=0133 undefined undefined 3DClient +DepthMode t=0134 undefined undefined DDX/3DClient +GLINTDepth t=0135 undefined undefined DDX/3DClient +ZStartU t=0136 undefined undefined 3DClient +ZStartL t=0137 undefined undefined 3DClient +dZdxU t=0138 undefined undefined 3DClient +dZdxL t=0139 undefined undefined 3DClient +dZdyDomU t=013a undefined undefined 3DClient +dZdyDomL t=013b undefined undefined 3DClient +FastClearDepth t=013c undefined undefined 3DClient +FBReadMode t=0150 set by DDX set by DDX DDX/3DClient + Partial Product bit 0-5 need by 3DClient +LBReadFormat t=0111 set by DDX set by DDX DDX +FBSourceOffset t=0151 undefined undefined DDX/3DClient +FBPixelOffset t=0152 undefined undefined DDX/3DClient +FBWindowBase t=0156 undefined undefined DDX/3DClient +FBWriteMode t=0157 undefined undefined DDX/3DClient +FBHardwareWriteMask t=0158 undefined undefined DDX/3DClient +FBBlockColor t=0159 undefined undefined DDX/3DClient +PatternRamMode t=015f undefined undefined DDX/3DClient +PatternRamData0 t=0160 undefined undefined DDX/3DClient +PatternRamData1 t=0161 undefined undefined DDX/3DClient +PatternRamData2 t=0162 undefined undefined DDX/3DClient +PatternRamData3 t=0163 undefined undefined DDX/3DClient +PatternRamData4 t=0164 undefined undefined DDX/3DClient +PatternRamData5 t=0165 undefined undefined DDX/3DClient +PatternRamData6 t=0166 undefined undefined DDX/3DClient +PatternRamData7 t=0167 undefined undefined DDX/3DClient +PatternRamData8 t=0168 undefined undefined DDX/3DClient +PatternRamData9 t=0169 undefined undefined DDX/3DClient +PatternRamData10 t=016a undefined undefined DDX/3DClient +PatternRamData11 t=016b undefined undefined DDX/3DClient +PatternRamData12 t=016c undefined undefined DDX/3DClient +PatternRamData13 t=016d undefined undefined DDX/3DClient +PatternRamData14 t=016e undefined undefined DDX/3DClient +PatternRamData15 t=016f undefined undefined DDX/3DClient +PatternRamData16 t=0170 undefined undefined DDX/3DClient +PatternRamData17 t=0171 undefined undefined DDX/3DClient +PatternRamData18 t=0172 undefined undefined DDX/3DClient +PatternRamData19 t=0173 undefined undefined DDX/3DClient +PatternRamData20 t=0174 undefined undefined DDX/3DClient +PatternRamData21 t=0175 undefined undefined DDX/3DClient +PatternRamData22 t=0176 undefined undefined DDX/3DClient +PatternRamData23 t=0177 undefined undefined DDX/3DClient +PatternRamData24 t=0178 undefined undefined DDX/3DClient +PatternRamData25 t=0179 undefined undefined DDX/3DClient +PatternRamData26 t=017a undefined undefined DDX/3DClient +PatternRamData27 t=017b undefined undefined DDX/3DClient +PatternRamData28 t=017c undefined undefined DDX/3DClient +PatternRamData29 t=017d undefined undefined DDX/3DClient +PatternRamData30 t=017e undefined undefined DDX/3DClient +PatternRamData31 t=017f undefined undefined DDX/3DClient +FBBlockColorU t=018d undefined undefined DDX/3DClient +FBBlockColorL t=018e undefined undefined DDX/3DClient +FilterMode t=0180 undefined undefined DDX/3DClient +StatisticMode t=0181 undefined undefined DDX/3DClient +MinRegion t=0182 undefined undefined 3DClient +MaxRegion t=0183 undefined undefined 3DClient +KsRStart t=0190 undefined undefined 3DClient +dKsRdx t=0191 undefined undefined 3DClient +dKsRdyDom t=0192 undefined undefined 3DClient +KsGStart t=0193 undefined undefined 3DClient +dKsGdx t=0194 undefined undefined 3DClient +dKsGdyDom t=0195 undefined undefined 3DClient +KsBStart t=0196 undefined undefined 3DClient +dKsBdx t=0197 undefined undefined 3DClient +dKsBdyDom t=0198 undefined undefined 3DClient +KdRStart t=01a0 undefined undefined 3DClient +dKdRdx t=01a1 undefined undefined 3DClient +dKdRdyDom t=01a2 undefined undefined 3DClient +KdGStart t=01a3 undefined undefined 3DClient +dKdGdx t=01a4 undefined undefined 3DClient +dKdGdyDom t=01a5 undefined undefined 3DClient +KdBStart t=01a6 undefined undefined 3DClient +dKdBdx t=01a7 undefined undefined 3DClient +dKdBdyDom t=01a8 undefined undefined 3DClient + +All Gamma State is undefined and owned by 3DClient driver except for: + +BroadcastMask o=026f 0x00000003 DDX/3DClient + +All TI RAMDAC State is owned by DDX driver. diff --git a/README.pm3 b/README.pm3 new file mode 100644 index 0000000..4d6972e --- /dev/null +++ b/README.pm3 @@ -0,0 +1,57 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3,v 1.13 2002/05/07 23:15:58 alanh Exp $ */ + +STATUS as of Tue, 8 May 2001 19:01:39 +0200 + +Working : + * Unaccelerated : Depth 8, 15, 16 and 24 are ok. I tested them upto + 1280x1024 only as my monitor don't support higher modes. + * Endianess clean, thanks to Romain Dolbeau <dolbeaur@club-internet.fr> for + helping me debug this. + * HW cursor. + * ShadowFb. + * Full 2D Accels. + - Sync. + - Pixmap cache. + - Offscreen pixmaps. + - Clipping. + - Screen to screen copy. + - Solid fills. + - HorVert Solid Lines . + - 8x8 Mono Pattern Fills. + - Color Expansion Fills. + - Images Writes. + - Bitmap Writes using direct FIFO writes with or without FIFO Disconnect. + - Pixmap Writes using direct FIFO writes with or without FIFO Disconnect. + * Appian J2000 second head initialization. + * Xv : Hardware video scaler : + - Needs checking on a big endian machine. + - Needs acceleration to work - there is a hardware bug in YV12 mode. + - Support both dual head and single head, trough gamma or permedia3. + - NOTE: depth 15 and 16 currently broken as I can't figure out the + colorKey equation. From the docs it needs to be padded to 8bits per RGB, + but that doesn't seem to work either. FIXME. + - Attributes are : + - FILTER : None, Partial (X only) or Full filtering. + - COLORKEY : Speaks for itself + - DOUBLE_BUFFER : Speaks for itself + - AUTOPAINT_COLORKEY : Speaks for itself + - MIRROR : X and/or Y Axis mirroring. (NOT DONE) + - ALPHA : (NOT DONE) + - 0 -> FB Only + - 1 -> 25% Video, 75% FB + - 2 -> 75% Video, 25% FB + - 3 -> Video Only + +Not Working : + + * [NOT POSSIBLE] 2D Accel : + - Solid & Dashed Lines are not possible on glint hardware. + - 8x8 Color Pattern Fill is almost never used. + - Clipping needs cleaning up. + * [TODO] 2D Accel hooks for the Rendering extension : + - Render extension initialization. + - CPUToScreenTexture. + - CPUToScreenAlphaTexture. + +Sven Luther <luther@dpt-info.u-strasbg.fr> +Alan Hourihane <alanh@fairlite.demon.co.uk> diff --git a/man/glint.man b/man/glint.man new file mode 100644 index 0000000..166de51 --- /dev/null +++ b/man/glint.man @@ -0,0 +1,110 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.man,v 1.6 2003/02/14 12:03:09 alanh Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH GLINT __drivermansuffix__ __vendorversion__ +.SH NAME +glint \- GLINT/Permedia video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qglint\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B glint +is an XFree86 driver for 3Dlabs & Texas Instruments GLINT/Permedia based video +cards. The driver is rather fully accelerated, and provides support for the +following framebuffer depths: 8, 15 (may give bad results with FBDev support), +16, 24 (32 bpp recommended, 24 bpp has problems), 30, and an 8+24 overlay mode. +.SH SUPPORTED HARDWARE +The +.B glint +driver supports 3Dlabs (GLINT MX, GLINT 500TX, GLINT 300SX, GLINT GAMMA, +GLINT DELTA, GLINT GAMMA2, Permedia, Permedia 2, Permedia 2v, Permedia 3, R3, +R4) and Texas Instruments (Permedia, Permedia 2) chips. +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The driver auto-detects the chipset type, but the following +.B ChipSet +names may optionally be specified in the config file +.B \*qDevice\*q +section, and will override the auto-detection: +.PP +.RS 4 +"ti_pm2", "ti_pm", "r4", "pm3", "pm2v", "pm2", "pm", "300sx", "500tx", "mx", +"gamma", "gamma2", "delta" +.RE +.PP +The driver will try to auto-detect the amount of video memory present for all +chips. If it's not detected correctly, the actual amount of video memory should +be specified with a +.B VideoRam +entry in the config file +.B \*qDevice\*q +section. +.PP +Additionally, you may need to specify the bus ID of your card with a +.B BusID +entry in the config file +.B \*qDevice\*q +section, especially with FBDev support. +.PP +The following driver +.B Options +are supported: +.TP +.BI "Option \*qUseFlatPanel\*q \*q" boolean \*q +Enable the FlatPanel feature on the Permedia3. Default: off. +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Enable or disable the SW cursor. Default: off. +This option disables the +.B HWCursor +option and vice versa. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disable or enable acceleration. Default: acceleration is enabled. +.TP +.BI "Option \*qOverlay\*q" +Enable 8+24 overlay mode. Only appropriate for depth 24, 32 bpp. +.RB ( Note: +This hasn't been tested with FBDev support and probably won't work.) +Recognized values are: "8,24", "24,8". Default: off. +.TP +.BI "Option \*qPciRetry\*q \*q" boolean \*q +Enable or disable PCI retries. +.RB ( Note: +This doesn't work with Permedia2 based cards for Amigas.) Default: off. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Enable or disable use of the shadow framebuffer layer. +.RB ( Note: +This disables hardware acceleration.) Default: off. +.TP +.BI "Option \*qUseFBDev\*q \*q" boolean \*q +Enable or disable use of an OS-specific fb interface (which is not supported +on all OSs). See fbdevhw(__drivermansuffix__) for further information. +Default: off. +.ig +.TP +.BI "Option \*qRGBbits\*q \*q" integer \*q +Each gun of the RGB triple can have either 8 or 10 bits. Default: 8 +.. +.TP +.BI "Option \*qBlockWrite\*q \*q" boolean \*q +Enable or disable block writes for the various Permedia 2 chips. This improves +acceleration in general, but disables it for some special cases. Default: off. +.TP +.BI "Option \*qFireGL3000\*q \*q" boolean \*q +If you have a card of the same name, turn this on. Default: off. +.TP +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +Authors include: Alan Hourihane, Dirk Hohndel, Stefan Dirsch, Michel Dänzer, +Sven Luther diff --git a/src/IBMramdac.c b/src/IBMramdac.c new file mode 100644 index 0000000..2a41fab --- /dev/null +++ b/src/IBMramdac.c @@ -0,0 +1,125 @@ +/* + * Copyright 1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * glintOutIBMRGBIndReg() and glintInIBMRGBIndReg() are used to access + * the indirect IBM RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c,v 1.6 1999/02/12 22:52:02 hohndel Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "IBM.h" +#include "glint_regs.h" +#include "glint.h" + +#define IBMRGB_WRITE_ADDR 0x4000 +#define IBMRGB_RAMDAC_DATA 0x4008 +#define IBMRGB_PIXEL_MASK 0x4010 +#define IBMRGB_READ_ADDR 0x4018 +#define IBMRGB_INDEX_LOW 0x4020 +#define IBMRGB_INDEX_HIGH 0x4028 +#define IBMRGB_INDEX_DATA 0x4030 +#define IBMRGB_INDEX_CONTROL 0x4038 + +void +glintOutIBMRGBIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char tmp = 0x00; + + GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, IBMRGB_INDEX_HIGH); + GLINT_SLOW_WRITE_REG (reg & 0xFF, IBMRGB_INDEX_LOW); + + if (mask != 0x00) + tmp = GLINT_READ_REG (IBMRGB_INDEX_DATA) & mask; + + GLINT_SLOW_WRITE_REG (tmp | data, IBMRGB_INDEX_DATA); +} + +unsigned char +glintInIBMRGBIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + + GLINT_SLOW_WRITE_REG(reg & 0xFF, IBMRGB_INDEX_LOW); + GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, IBMRGB_INDEX_HIGH); + ret = GLINT_READ_REG(IBMRGB_INDEX_DATA); + return (ret); +} + +void +glintIBMWriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(index, IBMRGB_WRITE_ADDR); +} + +void +glintIBMWriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(data, IBMRGB_RAMDAC_DATA); +} + +void +glintIBMReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(0xFF, IBMRGB_PIXEL_MASK); + GLINT_SLOW_WRITE_REG(index, IBMRGB_READ_ADDR); +} + +unsigned char +glintIBMReadData (ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + return(GLINT_READ_REG(IBMRGB_RAMDAC_DATA)); +} + +Bool +glintIBMHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pGlint->CursorInfoRec = infoPtr; + + (*pGlint->RamDac->HWCursorInit)(infoPtr); + + return(xf86InitCursor(pScreen, infoPtr)); +} diff --git a/src/TIramdac.c b/src/TIramdac.c new file mode 100644 index 0000000..e471c01 --- /dev/null +++ b/src/TIramdac.c @@ -0,0 +1,232 @@ +/* + * Copyright 1998-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Modified from IBMramdac.c to support TI RAMDAC routines + * by Jens Owen, <jens@tungstengraphics.com>. + * + * glintOutTIIndReg() and glintInTIIndReg() are used to access + * the indirect TI RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c,v 1.5 2002/10/30 12:52:15 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "TI.h" +#include "glint_regs.h" +#include "glint.h" + +#define TI_WRITE_ADDR 0x4000 +#define TI_RAMDAC_DATA 0x4008 +#define TI_PIXEL_MASK 0x4010 +#define TI_READ_ADDR 0x4018 +#define TI_CURS_COLOR_WRITE_ADDR 0x4020 +#define TI_CURS_COLOR_DATA 0x4028 +#define TI_CURS_COLOR_READ_ADDR 0x4038 +#define TI_DIRECT_CURS_CTRL 0x4048 +#define TI_INDEX_DATA 0x4050 +#define TI_CURS_RAM_DATA 0x4058 +#define TI_CURS_X_LOW 0x4060 +#define TI_CURS_X_HIGH 0x4068 +#define TI_CURS_Y_LOW 0x4070 +#define TI_CURS_Y_HIGH 0x4078 + +void +glintOutTIIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char tmp = 0x00; + int offset; + + if ((reg & 0xf0) == 0xa0) { /* this is really a direct register write */ + offset = TI_WRITE_ADDR + ((reg & 0xf) << 3); + if (mask != 0x00) + tmp = GLINT_READ_REG(offset) & mask; + + GLINT_SLOW_WRITE_REG(tmp | data, offset); + } + else { /* normal indirect access */ + GLINT_SLOW_WRITE_REG(reg & 0xFF, TI_WRITE_ADDR); + + if (mask != 0x00) + tmp = GLINT_READ_REG(TI_INDEX_DATA) & mask; + + GLINT_SLOW_WRITE_REG(tmp | data, TI_INDEX_DATA); + } +} + +unsigned char +glintInTIIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + int offset; + + if ((reg & 0xf0) == 0xa0) { /* this is really a direct register write */ + offset = TI_WRITE_ADDR + ((reg & 0xf) << 3); + ret = GLINT_READ_REG(offset); + } + else { /* normal indirect access */ + GLINT_SLOW_WRITE_REG(reg & 0xFF, TI_WRITE_ADDR); + ret = GLINT_READ_REG(TI_INDEX_DATA); + } + + return (ret); +} + +void +glintTIWriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(index, TI_WRITE_ADDR); +} + +void +glintTIWriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(data, TI_RAMDAC_DATA); +} + +void +glintTIReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(0xFF, TI_PIXEL_MASK); + GLINT_SLOW_WRITE_REG(index, TI_READ_ADDR); +} + +unsigned char +glintTIReadData (ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + return(GLINT_READ_REG(TI_RAMDAC_DATA)); +} + +Bool +glintTIHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pGlint->CursorInfoRec = infoPtr; + + (*pGlint->RamDac->HWCursorInit)(infoPtr); + + return(xf86InitCursor(pScreen, infoPtr)); +} + +/* Special cases */ + +/* GMX2000 */ +void +GMX2000OutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + ACCESSCHIP2(); + + glintOutTIIndReg(pScrn, reg, mask, data); + + ACCESSCHIP1(); +} + +unsigned char +GMX2000InIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + + ACCESSCHIP2(); + + ret = glintInTIIndReg(pScrn, reg); + + ACCESSCHIP1(); + + return (ret); +} + +void +GMX2000WriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + ACCESSCHIP2(); + + glintTIWriteAddress(pScrn, index); + + ACCESSCHIP1(); +} + +void +GMX2000WriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + ACCESSCHIP2(); + + glintTIWriteData(pScrn, data); + + ACCESSCHIP1(); +} + +void +GMX2000ReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + ACCESSCHIP2(); + + glintTIReadAddress(pScrn, index); + + ACCESSCHIP1(); +} + +unsigned char +GMX2000ReadData (ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + + ACCESSCHIP2(); + + ret = glintTIReadData(pScrn); + + ACCESSCHIP1(); + + return (ret); +} diff --git a/src/glint.h b/src/glint.h new file mode 100644 index 0000000..58c1a8c --- /dev/null +++ b/src/glint.h @@ -0,0 +1,365 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.58 2003/02/17 16:08:28 dawes Exp $ */ +/* + * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + */ +#ifndef _GLINT_H_ +#define _GLINT_H_ + +#include "xaa.h" +#include "xf86RamDac.h" +#include "xf86cmap.h" +#include "xf86i2c.h" +#include "xf86DDC.h" +#include "xf86xv.h" +#ifdef XF86DRI +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "GL/glxint.h" +#include "glint_dripriv.h" +#endif + +#define GLINT_MAX_MULTI_DEVICES 2 + +#define VERSION 4000 +#define GLINT_NAME "GLINT" +#define GLINT_DRIVER_NAME "glint" +#define GLINT_MAJOR_VERSION 1 +#define GLINT_MINOR_VERSION 0 +#define GLINT_PATCHLEVEL 0 + +typedef struct { + CARD32 glintRegs[0x2000]; + CARD32 DacRegs[0x100]; + CARD8 cmap[0x300]; +} GLINTRegRec, *GLINTRegPtr; + +#define GLINTPTR(p) ((GLINTPtr)((p)->driverPrivate)) + +typedef struct { + int lastInstance; + int refCount; +} GLINTEntRec, *GLINTEntPtr; + +typedef struct { + pciVideoPtr PciInfo; + pciVideoPtr MultiPciInfo[GLINT_MAX_MULTI_DEVICES]; + int MultiIndex; + int numMultiDevices; + int MultiChip; + Bool MultiAperture; + PCITAG PciTag; + EntityInfoPtr pEnt; + GLINTEntPtr entityPrivate; + RamDacHelperRecPtr RamDac; + int Chipset; + int ChipRev; + int HwBpp; + int BppShift; + int pprod; + CARD32 ForeGroundColor; + CARD32 BackGroundColor; + int bppalign; + CARD32 startxdom; + CARD32 startxsub; + CARD32 starty; + CARD32 count; + CARD32 dy; + CARD32 x; + CARD32 y; + CARD32 w; + CARD32 h; + CARD32 dxdom; + int dwords; + int cpuheight; + int cpucount; + CARD32 planemask; + int realWidth; + CARD32 IOAddress; + unsigned long FbAddress; + int irq; + unsigned char * IOBase; + unsigned char * FbBase; + long FbMapSize; + long IOOffset; + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + Bool DoubleBuffer; + Bool NoAccel; + Bool FBDev; + Bool ShadowFB; + unsigned char * ShadowPtr; + int ShadowPitch; + Bool Dac6Bit; + Bool HWCursor; + Bool ClippingOn; + Bool UseBlockWrite; + Bool UseFlatPanel; + Bool UseFireGL3000; + CARD8 VGAdata[65536]; + Bool STATE; + Bool ScanlineDirect; + int MXFbSize; + CARD32 rasterizerMode; + int MinClock; + int MaxClock; + int RefClock; + GLINTRegRec SavedReg[GLINT_MAX_MULTI_DEVICES]; + GLINTRegRec ModeReg[GLINT_MAX_MULTI_DEVICES]; + CARD32 AccelFlags; + CARD32 ROP; + CARD32 FrameBufferReadMode; + CARD32 BltScanDirection; + CARD32 TexMapFormat; + CARD32 PixelWidth; + RamDacRecPtr RamDacRec; + xf86CursorInfoPtr CursorInfoRec; + XAAInfoRecPtr AccelInfoRec; + CloseScreenProcPtr CloseScreen; + ScreenBlockHandlerProcPtr BlockHandler; + GCPtr CurrentGC; + DrawablePtr CurrentDrawable; + I2CBusPtr DDCBus, VSBus; + CARD32 FGCursor; + CARD32 BGCursor; + CARD8 HardwareCursorPattern[1024]; + CARD8* XAAScanlineColorExpandBuffers[2]; + CARD8* ScratchBuffer; + CARD32 RasterizerSwap; + void (*LoadCursorCallback)(ScrnInfoPtr); + void (*CursorColorCallback)(ScrnInfoPtr); + CARD32 PM3_PixelSize; + CARD32 PM3_Config2D; + CARD32 PM3_Render2D; + CARD32 PM3_AreaStippleMode; + CARD32 PM3_VideoControl; + int FIFOSize; + int InFifoSpace; +#ifdef XvExtension + void (*VideoTimerCallback)(ScrnInfoPtr, Time); + XF86VideoAdaptorPtr adaptor; + int videoKey; +#endif +#ifdef XF86DRI + Bool directRenderingEnabled; + Bool PCIMode; + DRIInfoPtr pDRIInfo; + int drmSubFD; + drmBufMapPtr drmBufs; /* Map of DMA buffers */ + drmRegion agp; + drmRegion buffers; + int numVisualConfigs; + __GLXvisualConfig* pVisualConfigs; + GLINTConfigPrivPtr pVisualConfigsPriv; + GLINTRegRec DRContextRegs; + int DRIctx; + unsigned char *buf2D; +#endif + OptionInfoPtr Options; + Bool PM3_UsingSGRAM; +} GLINTRec, *GLINTPtr; + +/* Defines for PCI data */ + +#define PCI_VENDOR_TI_CHIP_PERMEDIA2 \ + ((PCI_VENDOR_TI << 16) | PCI_CHIP_TI_PERMEDIA2) +#define PCI_VENDOR_TI_CHIP_PERMEDIA \ + ((PCI_VENDOR_TI << 16) | PCI_CHIP_TI_PERMEDIA) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA2 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA2) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA2V) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA3 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA3) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA4 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA4) +#define PCI_VENDOR_3DLABS_CHIP_R4 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_R4) +#define PCI_VENDOR_3DLABS_CHIP_300SX \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_300SX) +#define PCI_VENDOR_3DLABS_CHIP_500TX \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_500TX) +#define PCI_VENDOR_3DLABS_CHIP_MX \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_MX) +#define PCI_VENDOR_3DLABS_CHIP_GAMMA \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_GAMMA) +#define PCI_VENDOR_3DLABS_CHIP_GAMMA2 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_GAMMA2) +#define PCI_VENDOR_3DLABS_CHIP_DELTA \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_DELTA) + +/* Prototypes */ + +void Permedia2StoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs); +void Permedia2InstallColormap(ColormapPtr pmap); +void Permedia2UninstallColormap(ColormapPtr pmap); +int Permedia2ListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps); +void Permedia2HandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp); +void Permedia2RestoreDACValues(ScrnInfoPtr pScrn); +void Permedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void Permedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool Permedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode); +void Permedia2PreInit(ScrnInfoPtr pScrn); +Bool Permedia2AccelInit(ScreenPtr pScreen); +void Permedia2Sync(ScrnInfoPtr pScrn); +void Permedia2InitializeEngine(ScrnInfoPtr pScrn); +Bool Permedia2HWCursorInit(ScreenPtr pScreen); + +void PermediaRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void PermediaSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool PermediaInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool PermediaAccelInit(ScreenPtr pScreen); +void PermediaInitializeEngine(ScrnInfoPtr pScrn); +void Permedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void Permedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool Permedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +void Permedia2VPreInit(ScrnInfoPtr pScrn); +Bool Permedia2vHWCursorInit(ScreenPtr pScreen); + +void Permedia3PreInit(ScrnInfoPtr pScrn); +int Permedia3MemorySizeDetect(ScrnInfoPtr pScrn); +void Permedia3Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void Permedia3Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg); +Bool Permedia3AccelInit(ScreenPtr pScreen); +void Permedia3InitializeEngine(ScrnInfoPtr pScrn); +void Permedia3EnableOffscreen(ScreenPtr pScreen); +void Permedia3Sync(ScrnInfoPtr pScrn); +void DualPermedia3Sync(ScrnInfoPtr pScrn); +void Permedia3InitVideo(ScreenPtr pScreen); + +void TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void TXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr glintReg); +Bool TXAccelInit(ScreenPtr pScreen); +void TXInitializeEngine(ScrnInfoPtr pScrn); + +void SXInitializeEngine(ScrnInfoPtr pScrn); +Bool SXAccelInit(ScreenPtr pScreen); + +void DualMXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +void DualMXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); +Bool DualMXInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool DualMXAccelInit(ScreenPtr pScreen); +void DualMXInitializeEngine(ScrnInfoPtr pScrn); + +void glintOutIBMRGBIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char glintInIBMRGBIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void glintIBMWriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void glintIBMReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void glintIBMWriteData(ScrnInfoPtr pScrn, unsigned char data); +Bool glintIBMHWCursorInit(ScreenPtr pScreen); +unsigned char glintIBMReadData(ScrnInfoPtr pScrn); +Bool glintIBM526HWCursorInit(ScreenPtr pScreen); +Bool glintIBM640HWCursorInit(ScreenPtr pScreen); + +void glintOutTIIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char glintInTIIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void GMX2000OutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char GMX2000InIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void glintTIWriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void glintTIReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void glintTIWriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char glintTIReadData(ScrnInfoPtr pScrn); +void GMX2000WriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void GMX2000ReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void GMX2000WriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char GMX2000ReadData(ScrnInfoPtr pScrn); +Bool glintTIHWCursorInit(ScreenPtr pScreen); + +void Permedia2OutIndReg(ScrnInfoPtr pScrn, + CARD32, unsigned char mask, unsigned char data); +unsigned char Permedia2InIndReg(ScrnInfoPtr pScrn, CARD32); +void Permedia2WriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void Permedia2ReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void Permedia2WriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char Permedia2ReadData(ScrnInfoPtr pScrn); +void Permedia2LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual); +void Permedia2LoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual); +void Permedia3LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual); +void Permedia3LoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual); +void Permedia2I2CUDelay(I2CBusPtr b, int usec); +void Permedia2I2CPutBits(I2CBusPtr b, int scl, int sda); +void Permedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda); + +void Permedia2VideoInit(ScreenPtr pScreen); +void Permedia2VideoUninit(ScrnInfoPtr pScrn); +void Permedia2VideoEnterVT(ScrnInfoPtr pScrn); +void Permedia2VideoLeaveVT(ScrnInfoPtr pScrn); + +void Permedia3VideoInit(ScreenPtr pScreen); +void Permedia3VideoUninit(ScrnInfoPtr pScrn); +void Permedia3VideoEnterVT(ScrnInfoPtr pScrn); +void Permedia3VideoLeaveVT(ScrnInfoPtr pScrn); + +void Permedia2vOutIndReg(ScrnInfoPtr pScrn, + CARD32, unsigned char mask, unsigned char data); +unsigned char Permedia2vInIndReg(ScrnInfoPtr pScrn, CARD32); + +Bool GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +void GLINTAdjustFrame(int scrnIndex, int x, int y, int flags); + +extern int partprodPermedia[]; +extern const char *GLINTint10Symbols[]; + +Bool GLINTDGAInit(ScreenPtr pScreen); + +Bool GLINTDRIScreenInit(ScreenPtr pScreen); +Bool GLINTDRIFinishScreenInit(ScreenPtr pScreen); +void GLINTDRICloseScreen(ScreenPtr pScreen); +Bool GLINTInitGLXVisuals(ScreenPtr pScreen); +void GLINTDRIWakeupHandler(ScreenPtr pScreen); +void GLINTDRIBlockHandler(ScreenPtr pScreen); +void GLINTDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); +void GLINTDRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index); + +void GLINT_VERB_WRITE_REG(GLINTPtr, CARD32 v, int r, char *file, int line); +CARD32 GLINT_VERB_READ_REG(GLINTPtr, CARD32 r, char *file, int line); + +void GLINTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +void GLINT_MoveBYTE(CARD32* dest, unsigned char* src, int dwords); +void GLINT_MoveWORDS(CARD32* dest, unsigned short* src, int dwords); +void GLINT_MoveDWORDS(CARD32* dest, CARD32* src, int dwords); + +int Shiftbpp(ScrnInfoPtr pScrn, int value); +#endif /* _GLINT_H_ */ diff --git a/src/glint_common.h b/src/glint_common.h new file mode 100644 index 0000000..4845be7 --- /dev/null +++ b/src/glint_common.h @@ -0,0 +1,63 @@ +/* glint_common.h -- common header definitions for Gamma 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_common.h,v 1.1 2002/10/30 12:52:15 alanh Exp $ + * + */ + +#ifndef _GLINT_COMMON_H_ +#define _GLINT_COMMON_H_ + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (gamma_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_GAMMA_INIT 0x00 +#define DRM_GAMMA_COPY 0x01 + +typedef struct { + enum { + GAMMA_INIT_DMA = 0x01, + GAMMA_CLEANUP_DMA = 0x02 + } func; + int sarea_priv_offset; + int pcimode; + unsigned int mmio0; + unsigned int mmio1; + unsigned int mmio2; + unsigned int mmio3; + unsigned int buffers_offset; +} drmGAMMAInit; + +extern int drmGAMMAInitDMA( int fd, drmGAMMAInit *info ); +extern int drmGAMMACleanupDMA( int fd ); + +#endif diff --git a/src/glint_dga.c b/src/glint_dga.c new file mode 100644 index 0000000..ece7657 --- /dev/null +++ b/src/glint_dga.c @@ -0,0 +1,273 @@ +/* + * Copyright 2000-2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c,v 1.4 2001/12/16 21:36:50 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "glint.h" +#include "glint_regs.h" +#include "dgaproc.h" + +static Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr); +static void GLINT_Sync(ScrnInfoPtr); +static int GLINT_GetViewport(ScrnInfoPtr); +static void GLINT_SetViewport(ScrnInfoPtr, int, int, int); +static void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); + +static +DGAFunctionRec GLINTDGAFuncs = { + GLINT_OpenFramebuffer, + NULL, + GLINT_SetMode, + GLINT_SetViewport, + GLINT_GetViewport, + GLINT_Sync, + GLINT_FillRect, + GLINT_BlitRect, + NULL +}; + +Bool +GLINTDGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrn->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while(pMode) { + + if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { + newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if(!newmodes) { + xfree(modes); + return FALSE; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + num; + num++; + + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + if(!pGlint->NoAccel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if(pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if(pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = pScrn->depth; + currentMode->bitsPerPixel = pScrn->bitsPerPixel; + currentMode->red_mask = pScrn->mask.red; + currentMode->green_mask = pScrn->mask.green; + currentMode->blue_mask = pScrn->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pGlint->FbBase; + + if(oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrn->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrn->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + + pMode = pMode->next; + if(pMode == firstMode) + break; + } + + pGlint->numDGAModes = num; + pGlint->DGAModes = modes; + + return DGAInit(pScreen, &GLINTDGAFuncs, modes, num); +} + + +static Bool +GLINT_SetMode( + ScrnInfoPtr pScrn, + DGAModePtr pMode +){ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrn->pScreen->myNum; + GLINTPtr pGlint = GLINTPTR(pScrn); + + if(!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + + pScrn->displayWidth = OldDisplayWidth[index]; + + GLINTSwitchMode(index, pScrn->currentMode, 0); + pGlint->DGAactive = FALSE; + } else { + if(!pGlint->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrn->displayWidth; + + pGlint->DGAactive = TRUE; + } + + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + + GLINTSwitchMode(index, pMode->mode, 0); + } + + return TRUE; +} + +static int +GLINT_GetViewport( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + return pGlint->DGAViewportStatus; +} + +static void +GLINT_SetViewport( + ScrnInfoPtr pScrn, + int x, int y, + int flags +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINTAdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pGlint->DGAViewportStatus = 0; /* GLINTAdjustFrame loops until finished */ +} + +static void +GLINT_FillRect ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if(pGlint->AccelInfoRec) { + (*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(pGlint->AccelInfoRec); + } +} + +static void +GLINT_Sync( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if(pGlint->AccelInfoRec) { + (*pGlint->AccelInfoRec->Sync)(pScrn); + } +} + +static void +GLINT_BlitRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if(pGlint->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pGlint->AccelInfoRec); + } +} + +static Bool +GLINT_OpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)pGlint->FbAddress; + *size = pGlint->FbMapSize; + *offset = 0; + *flags = DGA_NEED_ROOT; + + return TRUE; +} diff --git a/src/glint_dri.c b/src/glint_dri.c new file mode 100644 index 0000000..506fb7e --- /dev/null +++ b/src/glint_dri.c @@ -0,0 +1,1955 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c,v 1.32 2003/02/10 13:20:10 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Jens Owen <jens@tungstengraphics.com> + * Alan Hourihane <alanh@fairlite.demon.co.uk> + * + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Priv.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "fb.h" + +#include "miline.h" + +#include "GL/glxtokens.h" + +#include "glint_regs.h" +#include "glint.h" +#include "glint_dri.h" + +static char GLINTKernelDriverName[] = "gamma"; +static char GLINTClientDriverName[] = "gamma"; + +static void GLINTDestroyContext(ScreenPtr pScreen, drmContext hwContext, + DRIContextType contextStore); + + +static unsigned int mylog2( unsigned int n ) +{ + unsigned int log2 = 1; + while ( n > 1 ) n >>= 1, log2++; + return log2; +} + +static int +GLINTDRIControlInit(int drmSubFD, int irq) +{ + int retcode; + + if ((retcode = drmCtlInstHandler(drmSubFD, irq))) return 1; + return 0; +} + +static Bool +GLINTInitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = NULL; + GLINTConfigPrivPtr pGlintConfigs = NULL; + GLINTConfigPrivPtr *pGlintConfigPtrs = NULL; + int db, depth, stencil, accum; + int i; + + switch ( pScrn->depth ) { + case 15: + numConfigs = 8; + + pConfigs = (__GLXvisualConfig*)xnfcalloc( sizeof(__GLXvisualConfig), + numConfigs ); + if ( !pConfigs ) { + return FALSE; + } + + pGlintConfigs = (GLINTConfigPrivPtr)xnfcalloc( sizeof(GLINTConfigPrivRec), + numConfigs ); + if ( !pGlintConfigs ) { + xfree( pConfigs ); + return FALSE; + } + + pGlintConfigPtrs = (GLINTConfigPrivPtr*)xnfcalloc( sizeof(GLINTConfigPrivPtr), + numConfigs ); + if ( !pGlintConfigPtrs ) { + xfree( pConfigs ); + xfree( pGlintConfigs ); + return FALSE; + } + + for ( i = 0 ; i < numConfigs ; i++ ) { + pGlintConfigPtrs[i] = &pGlintConfigs[i]; + } + + i = 0; + depth = 1; + for ( accum = 0 ; accum <= 1 ; accum++ ) { + for ( stencil = 0 ; stencil <= 1 ; stencil++ ) { + for ( db = 1 ; db >= 0 ; db-- ) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 5; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 1; + pConfigs[i].redMask = 0x00007C00; + pConfigs[i].greenMask = 0x000003E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0x00008000; + if ( accum ) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if ( db ) { + pConfigs[i].doubleBuffer = TRUE; + } else { + pConfigs[i].doubleBuffer = FALSE; + } + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 20; + if ( depth ) { + pConfigs[i].depthSize = 16; + } else { + pConfigs[i].depthSize = 0; + } + if ( stencil ) { + pConfigs[i].stencilSize = 8; + } else { + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if ( accum || stencil ) { + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + } else { + pConfigs[i].visualRating = GLX_NONE_EXT; + } + pConfigs[i].transparentPixel = 0; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + if ( i != numConfigs ) { + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "[drm] Incorrect initialization of visuals\n" ); + return FALSE; + } + break; + + case 24: + numConfigs = 8; + + pConfigs = (__GLXvisualConfig*)xnfcalloc( sizeof(__GLXvisualConfig), + numConfigs ); + if ( !pConfigs ) { + return FALSE; + } + + pGlintConfigs = (GLINTConfigPrivPtr)xnfcalloc( sizeof(GLINTConfigPrivRec), + numConfigs ); + if ( !pGlintConfigs ) { + xfree( pConfigs ); + return FALSE; + } + + pGlintConfigPtrs = (GLINTConfigPrivPtr*)xnfcalloc( sizeof(GLINTConfigPrivPtr), + numConfigs ); + if ( !pGlintConfigPtrs ) { + xfree( pConfigs ); + xfree( pGlintConfigs ); + return FALSE; + } + + for ( i = 0 ; i < numConfigs ; i++ ) { + pGlintConfigPtrs[i] = &pGlintConfigs[i]; + } + + i = 0; + for ( accum = 0 ; accum <= 1 ; accum++ ) { + for ( depth = 0 ; depth <= 1 ; depth++ ) { /* and stencil */ + for ( db = 1 ; db >= 0 ; db-- ) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0; + if ( accum ) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if ( db ) { + pConfigs[i].doubleBuffer = TRUE; + } else { + pConfigs[i].doubleBuffer = FALSE; + } + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 24; + if ( depth ) { + pConfigs[i].depthSize = 16; + pConfigs[i].stencilSize = 8; + } + else { + pConfigs[i].depthSize = 0; + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if ( accum ) { + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + } else { + pConfigs[i].visualRating = GLX_NONE_EXT; + } + pConfigs[i].transparentPixel = 0; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + if ( i != numConfigs ) { + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "[drm] Incorrect initialization of visuals\n" ); + return FALSE; + } + break; + + default: /* Can't do depth 8 or 16, just 15 or 24 */ + return FALSE; + break; + } + + pGlint->numVisualConfigs = numConfigs; + pGlint->pVisualConfigs = pConfigs; + pGlint->pVisualConfigsPriv = pGlintConfigs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void **)pGlintConfigPtrs); + + return TRUE; +} + +static Bool GLINTDRIAgpInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + int ret, count; + CARD32 mode; + + /* FIXME: Make these configurable... + */ + pGlint->agp.size = 2 * 1024 * 1024; + pGlint->buffers.offset = 0; + pGlint->buffers.size = GLINT_DRI_BUF_COUNT * GLINT_DRI_BUF_SIZE; + + if ( drmAgpAcquire( pGlint->drmSubFD ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" ); + return FALSE; + } + + /* Read AGP Capabilities */ + mode = drmAgpGetMode(pGlint->drmSubFD) & ~0x03; /* Mask Host capabilities */ + + mode |= 0x01; /* Gamma only supports AGP 1x */ + + /* Now enable AGP only on the specified BusID */ + if ( drmAgpEnable( pGlint->drmSubFD, mode ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); + drmAgpRelease( pGlint->drmSubFD ); + return FALSE; + } + + ret = drmAgpAlloc( pGlint->drmSubFD, pGlint->agp.size, 0, NULL, + &pGlint->agp.handle); + + if ( ret < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret ); + drmAgpRelease( pGlint->drmSubFD ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] %d kB allocated with handle 0x%08x\n", + pGlint->agp.size/1024, pGlint->agp.handle ); + + if ( drmAgpBind( pGlint->drmSubFD, pGlint->agp.handle, 0 ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" ); + drmAgpFree( pGlint->drmSubFD, pGlint->agp.handle ); + drmAgpRelease( pGlint->drmSubFD ); + return FALSE; + } + + /* DMA buffers + */ + if ( drmAddMap( pGlint->drmSubFD, pGlint->buffers.offset, + pGlint->buffers.size, DRM_AGP, 0, + &pGlint->buffers.handle ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not add DMA buffers mapping\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] DMA buffers handle = 0x%08lx\n", + pGlint->buffers.handle ); + + if ( drmMap( pGlint->drmSubFD, pGlint->buffers.handle, + pGlint->buffers.size, &pGlint->buffers.map ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not map DMA buffers\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] DMA buffers mapped at 0x%08lx\n", pGlint->buffers.map); + + count = drmAddBufs( pGlint->drmSubFD, + GLINT_DRI_BUF_COUNT, GLINT_DRI_BUF_SIZE, + DRM_AGP_BUFFER, pGlint->buffers.offset ); + if ( count <= 0 ) { + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "[drm] failure adding %d %d byte DMA buffers\n", + GLINT_DRI_BUF_COUNT, GLINT_DRI_BUF_SIZE ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[drm] Added %d %d byte DMA buffers\n", + count, GLINT_DRI_BUF_SIZE ); + + { + int bufs; + + if ((bufs = drmAddBufs(pGlint->drmSubFD, + 1, + 8192, /* 8K = 8MB physical memory */ + 0, + DRM_RESTRICTED /* flags */)) <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] 0x%x failure adding page table buffer\n",bufs); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] added 1 page table buffer\n"); + } + + pGlint->PCIMode = FALSE; + + return TRUE; +} + +static Bool GLINTDRIKernelInit( ScreenPtr pScreen ) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + DRIInfoPtr pDRIInfo = pGlint->pDRIInfo; + GLINTDRIPtr pGlintDRI = pDRIInfo->devPrivate; + drmGAMMAInit init; + int ret; + + memset( &init, 0, sizeof(drmGAMMAInit) ); + + init.func = GAMMA_INIT_DMA; + init.sarea_priv_offset = sizeof(XF86DRISAREARec); + + init.mmio0 = pGlintDRI->registers0.handle; + init.mmio1 = pGlintDRI->registers1.handle; + init.mmio2 = pGlintDRI->registers2.handle; + init.mmio3 = pGlintDRI->registers3.handle; + + if (!pGlint->PCIMode) { + init.pcimode = 0; + init.buffers_offset = pGlint->buffers.handle; + } else { + init.pcimode = 1; + } + + ret = drmCommandWrite( pGlint->drmSubFD, DRM_GAMMA_INIT, + &init, sizeof(drmGAMMAInit) ); + + if ( ret < 0 ) { + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "[drm] Failed to initialize DMA! (%d)\n", ret ); + return FALSE; + } + + return TRUE; +} + +Bool +GLINTDRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + DRIInfoPtr pDRIInfo; + GLINTDRIPtr pGlintDRI; + int dmabufs = 0; + + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + for canonical symbols in each module. */ + if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; + if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] GLINTDRIScreenInit failed (libdri.a too old)\n"); + return FALSE; + } + + /* Check the DRI version */ + { + int major, minor, patch; + DRIQueryVersion(&major, &minor, &patch); + if (major != 4 || minor < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] GLINTDRIScreenInit failed because of a version mismatch.\n" + "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n" + "[dri] Disabling DRI.\n", + major, minor, patch); + return FALSE; + } + } + + if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA) return FALSE; + + if (pGlint->numMultiDevices > 2) return FALSE; + + if (pGlint->MultiChip != PCI_CHIP_MX) return FALSE; + + pDRIInfo = DRICreateInfoRec(); + if(pDRIInfo == NULL) + return FALSE; + + pGlint->pDRIInfo = pDRIInfo; + + /* setup device info */ + pDRIInfo->drmDriverName = GLINTKernelDriverName; + pDRIInfo->clientDriverName = GLINTClientDriverName; + pDRIInfo->busIdString = xalloc(64); /* Freed in DRIDestroyInfoRec */ + sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", + ((pciConfigPtr)pGlint->PciInfo->thisCard)->busnum, + ((pciConfigPtr)pGlint->PciInfo->thisCard)->devnum, + ((pciConfigPtr)pGlint->PciInfo->thisCard)->funcnum); + pDRIInfo->ddxDriverMajorVersion = GLINT_MAJOR_VERSION; + pDRIInfo->ddxDriverMinorVersion = GLINT_MINOR_VERSION; + pDRIInfo->ddxDriverPatchVersion = GLINT_PATCHLEVEL; + pDRIInfo->frameBufferPhysicalAddress = pGlint->FbAddress; + pDRIInfo->frameBufferSize = pGlint->FbMapSize; + pDRIInfo->frameBufferStride = + pScrn->displayWidth * (pScrn->bitsPerPixel >> 3); + pDRIInfo->ddxDrawableTableEntry = GLINT_MAX_DRAWABLES; + + /* MAX_DRAWABLES set to number of GID's minus one for DDX */ + if (SAREA_MAX_DRAWABLES < GLINT_MAX_DRAWABLES) { + pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; + } + else { + pDRIInfo->maxDrawableTableEntry = GLINT_MAX_DRAWABLES; + } + +#ifdef NOT_DONE + /* FIXME need to extend DRI protocol to pass this size back to client + * for SAREA mapping that includes a device private record + */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + /* + shared memory device private rec */ +#else + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + pDRIInfo->SAREASize = SAREA_MAX; +#endif + + if (!(pGlintDRI = (GLINTDRIPtr)xcalloc(sizeof(GLINTDRIRec),1))) { + DRIDestroyInfoRec(pGlint->pDRIInfo); + return FALSE; + } + + /* setup visual configurations */ + if (!(GLINTInitVisualConfigs(pScreen))) { + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" ); + + pDRIInfo->devPrivate = pGlintDRI; + pDRIInfo->devPrivateSize = sizeof(GLINTDRIRec); + pDRIInfo->contextSize = sizeof(GLINTDRIContextRec); + + /* setup call backs */ + pDRIInfo->CreateContext = GLINTCreateContext; + pDRIInfo->DestroyContext = GLINTDestroyContext; + pDRIInfo->SwapContext = GLINTDRISwapContext; + pDRIInfo->InitBuffers = GLINTDRIInitBuffers; + pDRIInfo->MoveBuffers = GLINTDRIMoveBuffers; + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + + /* So DRICloseScreen does the right thing if we abort */ + pGlint->buffers.map = 0; + pGlint->agp.handle = 0; + + if (!DRIScreenInit(pScreen, pDRIInfo, &(pGlint->drmSubFD))) { + DRIDestroyInfoRec(pGlint->pDRIInfo); + xfree(pGlintDRI); + return FALSE; + } + + /* Check the DRM versioning */ + { + drmVersionPtr version; + + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(pGlint->drmSubFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(pGlint->drmSubFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] GLINTDRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + GLINTDRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Check the GLINT DRM version */ + version = drmGetVersion(pGlint->drmSubFD); + if (version) { + if (version->version_major != 2 || + version->version_minor < 0) { + /* incompatible drm version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] GLINTDRIScreenInit failed because of a version mismatch.\n" + "[dri] gamma.o kernel module version is %d.%d.%d but version 2.0.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + GLINTDRICloseScreen(pScreen); + drmFreeVersion(version); + return FALSE; + } + drmFreeVersion(version); + } + } + + /* Tell the client driver how many MX's we have */ + pGlintDRI->numMultiDevices = pGlint->numMultiDevices; + /* Tell the client about our screen size setup */ + pGlintDRI->pprod = pGlint->pprod; + + pGlintDRI->cpp = pScrn->bitsPerPixel / 8; + pGlintDRI->frontPitch = pScrn->displayWidth; + pGlintDRI->frontOffset = 0; + + pGlintDRI->textureSize = 32 * 1024 * 1024; + pGlintDRI->logTextureGranularity = + mylog2( pGlintDRI->textureSize / GAMMA_NR_TEX_REGIONS ); + + /* setup device specific direct rendering memory maps */ + + /* pci region 0: control regs, first 4k page, priveledged writes */ + pGlintDRI->registers0.size = 0x1000; + if (drmAddMap( pGlint->drmSubFD, + (drmHandle)pGlint->IOAddress, + pGlintDRI->registers0.size, + DRM_REGISTERS, DRM_READ_ONLY, + &pGlintDRI->registers0.handle) < 0) + { + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Register handle 0 = 0x%08lx\n", + pGlintDRI->registers0.handle); + + /* pci region 0: control regs, following region, client access */ + pGlintDRI->registers1.size = 0xf000; + if (drmAddMap( pGlint->drmSubFD, + (drmHandle)(pGlint->IOAddress + 0x1000), + pGlintDRI->registers1.size, + DRM_REGISTERS, 0, + &pGlintDRI->registers1.handle) < 0) + { + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Register handle 1 = 0x%08lx\n", + pGlintDRI->registers1.handle); + + /* pci region 0: control regs, second MX, first 4k page */ + pGlintDRI->registers2.size = 0x1000; + if (drmAddMap( pGlint->drmSubFD, + (drmHandle)(pGlint->IOAddress + 0x10000), + pGlintDRI->registers2.size, + DRM_REGISTERS, DRM_READ_ONLY, + &pGlintDRI->registers2.handle) < 0) + { + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Register handle 2 = 0x%08lx\n", + pGlintDRI->registers2.handle); + + /* pci region 0: control regs, second MX, following region */ + pGlintDRI->registers3.size = 0xf000; + if (drmAddMap( pGlint->drmSubFD, + (drmHandle)(pGlint->IOAddress + 0x11000), + pGlintDRI->registers3.size, + DRM_REGISTERS, 0, + &pGlintDRI->registers3.handle) < 0) + { + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Register handle 3 = 0x%08lx\n", + pGlintDRI->registers3.handle); + + /* setup DMA buffers */ + + /* TRY AGP */ + if ( !GLINTDRIAgpInit( pScreen ) ) { + /* OUCH, NO AGP, TRY PCI */ + pGlint->PCIMode = TRUE; + if (xf86ConfigDRI.bufs_count) { + int i; + int bufs; + + for (i = 0; i < xf86ConfigDRI.bufs_count; i++) { + if ((bufs = drmAddBufs(pGlint->drmSubFD, + xf86ConfigDRI.bufs[i].count, + xf86ConfigDRI.bufs[i].size, + 0, + 0 /* flags */)) <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] failure adding %d %d byte DMA buffers\n", + xf86ConfigDRI.bufs[i].count, + xf86ConfigDRI.bufs[i].size); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] added %d %d byte DMA buffers\n", + bufs, xf86ConfigDRI.bufs[i].size); + dmabufs += bufs; + } + } + } + + if (dmabufs <= 0) { + int bufs; + + if ((bufs = drmAddBufs(pGlint->drmSubFD, + GLINT_DRI_BUF_COUNT, + GLINT_DRI_BUF_SIZE, + 0, + 0 /* flags */)) <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] failure adding %d %d byte DMA buffers\n", + GLINT_DRI_BUF_COUNT, + GLINT_DRI_BUF_SIZE); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] added %d %d byte DMA buffers\n", + bufs, GLINT_DRI_BUF_SIZE); + + if ((bufs = drmAddBufs(pGlint->drmSubFD, + 1, + 8192, /* 8K = 8MB physical memory */ + 0, + DRM_RESTRICTED /* flags */)) <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] 0x%x failure adding page table buffer\n",bufs); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] added 1 page table buffer\n"); + } + + if (!(pGlint->drmBufs = drmMapBufs(pGlint->drmSubFD))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] failure mapping DMA buffers\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] buffers mapped with %p\n", + pGlint->drmBufs); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] %d DMA buffers mapped\n", + pGlint->drmBufs->count); + } /* PCIMODE */ + + if (pGlint->irq <= 0) { + pGlint->irq = drmGetInterruptFromBusID(pGlint->drmSubFD, + ((pciConfigPtr)pGlint->PciInfo + ->thisCard)->busnum, + ((pciConfigPtr)pGlint->PciInfo + ->thisCard)->devnum, + ((pciConfigPtr)pGlint->PciInfo + ->thisCard)->funcnum); + } + + return TRUE; +} + +void +GLINTDRICloseScreen(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (pGlint->buffers.map) { + drmUnmap( pGlint->buffers.map, pGlint->buffers.size); + pGlint->buffers.map = NULL; + } + + if (pGlint->agp.handle) { + drmAgpUnbind( pGlint->drmSubFD, pGlint->agp.handle ); + drmAgpFree( pGlint->drmSubFD, pGlint->agp.handle ); + pGlint->agp.handle = 0; + drmAgpRelease( pGlint->drmSubFD ); + } + + if (pGlint->drmBufs) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] unmapping %d buffers\n", + pGlint->drmBufs->count); + if (drmUnmapBufs(pGlint->drmBufs)) { + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] unable to unmap DMA buffers\n"); + } + + } + + DRICloseScreen(pScreen); + + if (pGlint->pDRIInfo) { + if (pGlint->pDRIInfo->devPrivate) { + xfree(pGlint->pDRIInfo->devPrivate); + } + DRIDestroyInfoRec(pGlint->pDRIInfo); + } + + if (pGlint->pVisualConfigs) xfree(pGlint->pVisualConfigs); + if (pGlint->pVisualConfigsPriv) xfree(pGlint->pVisualConfigsPriv); +} + +Bool +GLINTCreateContext(ScreenPtr pScreen, + VisualPtr visual, + drmContext hwContext, + void *pVisualConfigPriv, + DRIContextType contextStore) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTConfigPrivPtr pGlintConfig = (GLINTConfigPrivPtr)pVisualConfigPriv; + + /* These are really assertions rather than necessary logic, + just using this to exercise device private region until really needed */ + + if (!pGlintConfig) + return TRUE; /* no GLX driver private support, yet */ + +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[GLINTCreateContext] context priv index = %d\n", + pGlintConfig->index); +#endif + + if (pGlintConfig->index >= pGlint->numVisualConfigs) + return FALSE; + + if (pGlint->pVisualConfigs[pGlintConfig->index].redMask != visual->redMask) + return FALSE; + + return TRUE; +} + +static void +GLINTDestroyContext(ScreenPtr pScreen, + drmContext hwContext, + DRIContextType contextStore) +{ +} + +Bool +GLINTDRIFinishScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + DRIInfoPtr pDRIInfo = pGlint->pDRIInfo; + GLINTDRIPtr pGlintDRI = pDRIInfo->devPrivate; + FBAreaPtr fbarea; + + /* + * Setup one of 4 types of context swap handling methods + * + * Option A: HIDE X CONTEXT SWAPS. X contexts will be flagged as + * preserved by the server. The kernel will never swap a preserved + * context. The kernel will call back into the server for swapping + * all other contexts. + * + * pGlint->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + * + * + * Option B: SERVER SIDE CONTEXT SWAPS. X contexts will be flagged + * as 2D contexts, but the flag will be ignored by the kernel. The + * preserved flag will not be used, so the kernel will call back into + * the server for swapping all contexts. The 2D flag will be used by + * the server to optimize for 2D/3D switching between a single 3D + * context and the servers 2D context. + * + * pGlint->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; + * + * + * Option C: KERNEL SIDE GENERIC SWAPS. X server will provide generic + * kernel driver with byte codes for performing swap. X contexts will + * be flagged as 2D contexts, so 2D/3D switching optimizations can still + * be done. This is not supported, yet. Additional work is required + * to support generic kernel driver and provide byte code examples. + * + * pGlint->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP; + * + * add byte codes for context swap here: + * drmCtlAddCommand(drmSubFD, ... + * + * + * Option D: KERNEL SIDE DEVICE SPECIFIC SWAPS. DrmSubdriver will + * have device specific code for handling swaps. X context will be + * flagged as 2D contexts, so 2D/3D switching optimizations can still + * be done. This is not supported by gamma driver, yet; however, the + * framework is in place to use this option. + * + * pGlint->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP; + */ + + pGlint->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + + /* Allocate the shared back buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + pGlintDRI->backPitch = pScrn->displayWidth; + pGlintDRI->backOffset = (fbarea->box.y1 * pScrn->displayWidth * + pScrn->bitsPerPixel / 8) + + (fbarea->box.x1 * pScrn->bitsPerPixel / 8); + pGlintDRI->backX = fbarea->box.x1; + pGlintDRI->backY = fbarea->box.y1; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + pGlintDRI->backPitch = -1; + pGlintDRI->backOffset = -1; + } + + if (!DRIFinishScreenInit(pScreen)) { + DRICloseScreen(pScreen); + return FALSE; + } + + if (!GLINTDRIKernelInit(pScreen)) { + DRICloseScreen(pScreen); + return FALSE; + } + + if ( (pGlint->irq <= 0) || + GLINTDRIControlInit(pGlint->drmSubFD, pGlint->irq) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] cannot initialize dma with IRQ %d\n", + pGlint->irq); + DRICloseScreen(pScreen); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] dma control initialized, using IRQ %d\n", + pGlint->irq); + + if (!pGlint->PCIMode) { + if (!(pGlint->drmBufs = drmMapBufs(pGlint->drmSubFD))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] failure mapping DMA buffers\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] buffers mapped with %p\n", + pGlint->drmBufs); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] %d DMA buffers mapped\n", + pGlint->drmBufs->count); + } + +#if 0 + /* Get the X server's context */ + pGlint->DRIctx = DRIGetContext(pScreen); + pGlint->buf2D = pGlint->drmBufs->list[GLINT_DRI_BUF_COUNT + 1].address; +#endif + + return TRUE; +} + +#define ContextDump_tag 0x1b8 +#define ContextRestore_tag 0x1b9 +#define ContextData_tag 0x1ba + +void +GLINTDRISwapContext( + ScreenPtr pScreen, + DRISyncType syncType, + DRIContextType readContextType, + void *readContextStore, + DRIContextType writeContextType, + void *writeContextStore) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTDRIContextPtr pRC = (GLINTDRIContextPtr)readContextStore; + GLINTDRIContextPtr pWC = (GLINTDRIContextPtr)writeContextStore; + int dumpIndex; + CARD32 readValue; + + /* Sync here covers both read and write context of contexts */ + if (pGlint->AccelInfoRec->Sync) { + (*pGlint->AccelInfoRec->Sync)(pGlint->AccelInfoRec->pScrn); + } + pGlint->AccelInfoRec->NeedToSync = FALSE; + + if (readContextType != DRI_NO_CONTEXT) { + + /* save the 2D portion of the old context */ + pRC->MX1.CStartXDom = GLINT_READ_REG(StartXDom); + pRC->MX1.CdXDom = GLINT_READ_REG(dXDom); + pRC->MX1.CStartXSub = GLINT_READ_REG(StartXSub); + pRC->MX1.CdXSub = GLINT_READ_REG(dXSub); + pRC->MX1.CStartY = GLINT_READ_REG(StartY); + pRC->MX1.CdY = GLINT_READ_REG(dY); + pRC->MX1.CGLINTCount = GLINT_READ_REG(GLINTCount); + pRC->MX1.CPointTable0 = GLINT_READ_REG(PointTable0); + pRC->MX1.CPointTable1 = GLINT_READ_REG(PointTable1); + pRC->MX1.CPointTable2 = GLINT_READ_REG(PointTable2); + pRC->MX1.CPointTable3 = GLINT_READ_REG(PointTable3); + pRC->MX1.CRasterizerMode = GLINT_READ_REG(RasterizerMode); + pRC->MX1.CYLimits = GLINT_READ_REG(YLimits); + pRC->MX1.CScanLineOwnership = GLINT_READ_REG(ScanLineOwnership); + pRC->MX1.CPixelSize = GLINT_READ_REG(PixelSize); + pRC->MX1.CScissorMode = GLINT_READ_REG(ScissorMode); + pRC->MX1.CScissorMinXY = GLINT_READ_REG(ScissorMinXY); + pRC->MX1.CScissorMaxXY = GLINT_READ_REG(ScissorMaxXY); + pRC->MX1.CScreenSize = GLINT_READ_REG(ScreenSize); + pRC->MX1.CAreaStippleMode = GLINT_READ_REG(AreaStippleMode); + pRC->MX1.CLineStippleMode = GLINT_READ_REG(LineStippleMode); + pRC->MX1.CLoadLineStippleCounters = GLINT_READ_REG(LoadLineStippleCounters); + pRC->MX1.CWindowOrigin = GLINT_READ_REG(WindowOrigin); + pRC->MX1.CRouterMode = GLINT_READ_REG(RouterMode); + pRC->MX1.CTextureAddressMode = GLINT_READ_REG(TextureAddressMode); + pRC->MX1.CTextureReadMode = GLINT_READ_REG(TextureReadMode); + pRC->MX1.CTextureColorMode = GLINT_READ_REG(TextureColorMode); + pRC->MX1.CFogMode = GLINT_READ_REG(FogMode); + pRC->MX1.CColorDDAMode = GLINT_READ_REG(ColorDDAMode); + pRC->MX1.CGLINTColor = GLINT_READ_REG(GLINTColor); + pRC->MX1.CAlphaTestMode = GLINT_READ_REG(AlphaTestMode); + pRC->MX1.CAntialiasMode = GLINT_READ_REG(AntialiasMode); + pRC->MX1.CAlphaBlendMode = GLINT_READ_REG(AlphaBlendMode); + pRC->MX1.CDitherMode = GLINT_READ_REG(DitherMode); + pRC->MX1.CFBSoftwareWriteMask = GLINT_READ_REG(FBSoftwareWriteMask); + pRC->MX1.CLogicalOpMode = GLINT_READ_REG(LogicalOpMode); + pRC->MX1.CFBWriteData = GLINT_READ_REG(FBWriteData); + pRC->MX1.CLBReadMode = GLINT_READ_REG(LBReadMode); + pRC->MX1.CLBSourceOffset = GLINT_READ_REG(LBSourceOffset); + pRC->MX1.CLBWindowBase = GLINT_READ_REG(LBWindowBase); + pRC->MX1.CLBWriteMode = GLINT_READ_REG(LBWriteMode); + pRC->MX1.CTextureDownloadOffset = GLINT_READ_REG(TextureDownloadOffset); + pRC->MX1.CLBWindowOffset = GLINT_READ_REG(LBWindowOffset); + pRC->MX1.CGLINTWindow = GLINT_READ_REG(GLINTWindow); + pRC->MX1.CStencilMode = GLINT_READ_REG(StencilMode); + pRC->MX1.CDepthMode = GLINT_READ_REG(DepthMode); + pRC->MX1.CGLINTDepth = GLINT_READ_REG(GLINTDepth); + pRC->MX1.CFBReadMode = GLINT_READ_REG(FBReadMode); + pRC->MX1.CFBSourceOffset = GLINT_READ_REG(FBSourceOffset); + pRC->MX1.CFBPixelOffset = GLINT_READ_REG(FBPixelOffset); + pRC->MX1.CFBWindowBase = GLINT_READ_REG(FBWindowBase); + pRC->MX1.CFBWriteMode = GLINT_READ_REG(FBWriteMode); + pRC->MX1.CFBHardwareWriteMask = GLINT_READ_REG(FBHardwareWriteMask); + pRC->MX1.CFBBlockColor = GLINT_READ_REG(FBBlockColor); + pRC->MX1.CPatternRamMode = GLINT_READ_REG(PatternRamMode); + pRC->MX1.CFBBlockColorU = GLINT_READ_REG(FBBlockColorU); + pRC->MX1.CFBBlockColorL = GLINT_READ_REG(FBBlockColorL); + pRC->MX1.CFilterMode = GLINT_READ_REG(FilterMode); + pRC->MX1.CStatisticMode = GLINT_READ_REG(StatisticMode); + + if (pGlint->numMultiDevices == 2) { + pRC->MX1.CBroadcastMask = GLINT_READ_REG(BroadcastMask); + + ACCESSCHIP2(); + pRC->MX2.CStartXDom = GLINT_READ_REG(StartXDom); + pRC->MX2.CdXDom = GLINT_READ_REG(dXDom); + pRC->MX2.CStartXSub = GLINT_READ_REG(StartXSub); + pRC->MX2.CdXSub = GLINT_READ_REG(dXSub); + pRC->MX2.CStartY = GLINT_READ_REG(StartY); + pRC->MX2.CdY = GLINT_READ_REG(dY); + pRC->MX2.CGLINTCount = GLINT_READ_REG(GLINTCount); + pRC->MX2.CPointTable0 = GLINT_READ_REG(PointTable0); + pRC->MX2.CPointTable1 = GLINT_READ_REG(PointTable1); + pRC->MX2.CPointTable2 = GLINT_READ_REG(PointTable2); + pRC->MX2.CPointTable3 = GLINT_READ_REG(PointTable3); + pRC->MX2.CRasterizerMode = GLINT_READ_REG(RasterizerMode); + pRC->MX2.CYLimits = GLINT_READ_REG(YLimits); + pRC->MX2.CScanLineOwnership = GLINT_READ_REG(ScanLineOwnership); + pRC->MX2.CPixelSize = GLINT_READ_REG(PixelSize); + pRC->MX2.CScissorMode = GLINT_READ_REG(ScissorMode); + pRC->MX2.CScissorMinXY = GLINT_READ_REG(ScissorMinXY); + pRC->MX2.CScissorMaxXY = GLINT_READ_REG(ScissorMaxXY); + pRC->MX2.CScreenSize = GLINT_READ_REG(ScreenSize); + pRC->MX2.CAreaStippleMode = GLINT_READ_REG(AreaStippleMode); + pRC->MX2.CLineStippleMode = GLINT_READ_REG(LineStippleMode); + pRC->MX2.CLoadLineStippleCounters = GLINT_READ_REG(LoadLineStippleCounters); + pRC->MX2.CWindowOrigin = GLINT_READ_REG(WindowOrigin); + pRC->MX2.CRouterMode = GLINT_READ_REG(RouterMode); + pRC->MX2.CTextureAddressMode = GLINT_READ_REG(TextureAddressMode); + pRC->MX2.CTextureReadMode = GLINT_READ_REG(TextureReadMode); + pRC->MX2.CTextureColorMode = GLINT_READ_REG(TextureColorMode); + pRC->MX2.CFogMode = GLINT_READ_REG(FogMode); + pRC->MX2.CColorDDAMode = GLINT_READ_REG(ColorDDAMode); + pRC->MX2.CGLINTColor = GLINT_READ_REG(GLINTColor); + pRC->MX2.CAlphaTestMode = GLINT_READ_REG(AlphaTestMode); + pRC->MX2.CAntialiasMode = GLINT_READ_REG(AntialiasMode); + pRC->MX2.CAlphaBlendMode = GLINT_READ_REG(AlphaBlendMode); + pRC->MX2.CDitherMode = GLINT_READ_REG(DitherMode); + pRC->MX2.CFBSoftwareWriteMask = GLINT_READ_REG(FBSoftwareWriteMask); + pRC->MX2.CLogicalOpMode = GLINT_READ_REG(LogicalOpMode); + pRC->MX2.CFBWriteData = GLINT_READ_REG(FBWriteData); + pRC->MX2.CLBReadMode = GLINT_READ_REG(LBReadMode); + pRC->MX2.CLBSourceOffset = GLINT_READ_REG(LBSourceOffset); + pRC->MX2.CLBWindowBase = GLINT_READ_REG(LBWindowBase); + pRC->MX2.CLBWriteMode = GLINT_READ_REG(LBWriteMode); + pRC->MX2.CTextureDownloadOffset = GLINT_READ_REG(TextureDownloadOffset); + pRC->MX2.CLBWindowOffset = GLINT_READ_REG(LBWindowOffset); + pRC->MX2.CGLINTWindow = GLINT_READ_REG(GLINTWindow); + pRC->MX2.CStencilMode = GLINT_READ_REG(StencilMode); + pRC->MX2.CDepthMode = GLINT_READ_REG(DepthMode); + pRC->MX2.CGLINTDepth = GLINT_READ_REG(GLINTDepth); + pRC->MX2.CFBReadMode = GLINT_READ_REG(FBReadMode); + pRC->MX2.CFBSourceOffset = GLINT_READ_REG(FBSourceOffset); + pRC->MX2.CFBPixelOffset = GLINT_READ_REG(FBPixelOffset); + pRC->MX2.CFBWindowBase = GLINT_READ_REG(FBWindowBase); + pRC->MX2.CFBWriteMode = GLINT_READ_REG(FBWriteMode); + pRC->MX2.CFBHardwareWriteMask = GLINT_READ_REG(FBHardwareWriteMask); + pRC->MX2.CFBBlockColor = GLINT_READ_REG(FBBlockColor); + pRC->MX2.CPatternRamMode = GLINT_READ_REG(PatternRamMode); + pRC->MX2.CFBBlockColorU = GLINT_READ_REG(FBBlockColorU); + pRC->MX2.CFBBlockColorL = GLINT_READ_REG(FBBlockColorL); + pRC->MX2.CFilterMode = GLINT_READ_REG(FilterMode); + pRC->MX2.CStatisticMode = GLINT_READ_REG(StatisticMode); + ACCESSCHIP1(); + } + + if (readContextType == DRI_3D_CONTEXT) { + /* save the 3D portion of the old context */ + + /* first the MX portions */ + pRC->MX1.CSStart = GLINT_READ_REG(SStart); + pRC->MX1.CdSdx = GLINT_READ_REG(dSdx); + pRC->MX1.CdSdyDom = GLINT_READ_REG(dSdyDom); + pRC->MX1.CTStart = GLINT_READ_REG(TStart); + pRC->MX1.CdTdx = GLINT_READ_REG(dTdx); + pRC->MX1.CdTdyDom = GLINT_READ_REG(dTdyDom); + pRC->MX1.CQStart = GLINT_READ_REG(QStart); + pRC->MX1.CdQdx = GLINT_READ_REG(dQdx); + pRC->MX1.CdQdyDom = GLINT_READ_REG(dQdyDom); + pRC->MX1.CLOD = GLINT_READ_REG(LOD); + pRC->MX1.CdSdy = GLINT_READ_REG(dSdy); + pRC->MX1.CdTdy = GLINT_READ_REG(dTdy); + pRC->MX1.CdQdy = GLINT_READ_REG(dQdy); + pRC->MX1.CTextureFormat = GLINT_READ_REG(TextureFormat); + pRC->MX1.CTextureCacheControl = GLINT_READ_REG(TextureCacheControl); + pRC->MX1.CGLINTBorderColor = GLINT_READ_REG(GLINTBorderColor); + pRC->MX1.CTexelLUTIndex = GLINT_READ_REG(TexelLUTIndex); + pRC->MX1.CTexelLUTData = GLINT_READ_REG(TexelLUTData); + pRC->MX1.CTexelLUTAddress = GLINT_READ_REG(TexelLUTAddress); + pRC->MX1.CTexelLUTTransfer = GLINT_READ_REG(TexelLUTTransfer); + pRC->MX1.CTextureFilterMode = GLINT_READ_REG(TextureFilterMode); + pRC->MX1.CTextureChromaUpper = GLINT_READ_REG(TextureChromaUpper); + pRC->MX1.CTextureChromaLower = GLINT_READ_REG(TextureChromaLower); + pRC->MX1.CTxBaseAddr0 = GLINT_READ_REG(TxBaseAddr0); + pRC->MX1.CTxBaseAddr1 = GLINT_READ_REG(TxBaseAddr1); + pRC->MX1.CTxBaseAddr2 = GLINT_READ_REG(TxBaseAddr2); + pRC->MX1.CTxBaseAddr3 = GLINT_READ_REG(TxBaseAddr3); + pRC->MX1.CTxBaseAddr4 = GLINT_READ_REG(TxBaseAddr4); + pRC->MX1.CTxBaseAddr5 = GLINT_READ_REG(TxBaseAddr5); + pRC->MX1.CTxBaseAddr6 = GLINT_READ_REG(TxBaseAddr6); + pRC->MX1.CTxBaseAddr7 = GLINT_READ_REG(TxBaseAddr7); + pRC->MX1.CTxBaseAddr8 = GLINT_READ_REG(TxBaseAddr8); + pRC->MX1.CTxBaseAddr9 = GLINT_READ_REG(TxBaseAddr9); + pRC->MX1.CTxBaseAddr10 = GLINT_READ_REG(TxBaseAddr10); + pRC->MX1.CTxBaseAddr11 = GLINT_READ_REG(TxBaseAddr11); + pRC->MX1.CTexelLUT0 = GLINT_READ_REG(TexelLUT0); + pRC->MX1.CTexelLUT1 = GLINT_READ_REG(TexelLUT1); + pRC->MX1.CTexelLUT2 = GLINT_READ_REG(TexelLUT2); + pRC->MX1.CTexelLUT3 = GLINT_READ_REG(TexelLUT3); + pRC->MX1.CTexelLUT4 = GLINT_READ_REG(TexelLUT4); + pRC->MX1.CTexelLUT5 = GLINT_READ_REG(TexelLUT5); + pRC->MX1.CTexelLUT6 = GLINT_READ_REG(TexelLUT6); + pRC->MX1.CTexelLUT7 = GLINT_READ_REG(TexelLUT7); + pRC->MX1.CTexelLUT8 = GLINT_READ_REG(TexelLUT8); + pRC->MX1.CTexelLUT9 = GLINT_READ_REG(TexelLUT9); + pRC->MX1.CTexelLUT10 = GLINT_READ_REG(TexelLUT10); + pRC->MX1.CTexelLUT11 = GLINT_READ_REG(TexelLUT11); + pRC->MX1.CTexelLUT12 = GLINT_READ_REG(TexelLUT12); + pRC->MX1.CTexelLUT13 = GLINT_READ_REG(TexelLUT13); + pRC->MX1.CTexelLUT14 = GLINT_READ_REG(TexelLUT14); + pRC->MX1.CTexelLUT15 = GLINT_READ_REG(TexelLUT15); + pRC->MX1.CTexel0 = GLINT_READ_REG(Texel0); + pRC->MX1.CTexel1 = GLINT_READ_REG(Texel1); + pRC->MX1.CTexel2 = GLINT_READ_REG(Texel2); + pRC->MX1.CTexel3 = GLINT_READ_REG(Texel3); + pRC->MX1.CTexel4 = GLINT_READ_REG(Texel4); + pRC->MX1.CTexel5 = GLINT_READ_REG(Texel5); + pRC->MX1.CTexel6 = GLINT_READ_REG(Texel6); + pRC->MX1.CTexel7 = GLINT_READ_REG(Texel7); + pRC->MX1.CInterp0 = GLINT_READ_REG(Interp0); + pRC->MX1.CInterp1 = GLINT_READ_REG(Interp1); + pRC->MX1.CInterp2 = GLINT_READ_REG(Interp2); + pRC->MX1.CInterp3 = GLINT_READ_REG(Interp3); + pRC->MX1.CInterp4 = GLINT_READ_REG(Interp4); + pRC->MX1.CTextureFilter = GLINT_READ_REG(TextureFilter); + pRC->MX1.CTextureEnvColor = GLINT_READ_REG(TextureEnvColor); + pRC->MX1.CFogColor = GLINT_READ_REG(FogColor); + pRC->MX1.CFStart = GLINT_READ_REG(FStart); + pRC->MX1.CdFdx = GLINT_READ_REG(dFdx); + pRC->MX1.CdFdyDom = GLINT_READ_REG(dFdyDom); + pRC->MX1.CKsStart = GLINT_READ_REG(KsStart); + pRC->MX1.CdKsdx = GLINT_READ_REG(dKsdx); + pRC->MX1.CdKsdyDom = GLINT_READ_REG(dKsdyDom); + pRC->MX1.CKdStart = GLINT_READ_REG(KdStart); + pRC->MX1.CdKdStart = GLINT_READ_REG(dKdStart); + pRC->MX1.CdKddyDom = GLINT_READ_REG(dKddyDom); + pRC->MX1.CRStart = GLINT_READ_REG(RStart); + pRC->MX1.CdRdx = GLINT_READ_REG(dRdx); + pRC->MX1.CdRdyDom = GLINT_READ_REG(dRdyDom); + pRC->MX1.CGStart = GLINT_READ_REG(GStart); + pRC->MX1.CdGdx = GLINT_READ_REG(dGdx); + pRC->MX1.CdGdyDom = GLINT_READ_REG(dGdyDom); + pRC->MX1.CBStart = GLINT_READ_REG(BStart); + pRC->MX1.CdBdx = GLINT_READ_REG(dBdx); + pRC->MX1.CdBdyDom = GLINT_READ_REG(dBdyDom); + pRC->MX1.CAStart = GLINT_READ_REG(AStart); + pRC->MX1.CdAdx = GLINT_READ_REG(dAdx); + pRC->MX1.CdAdyDom = GLINT_READ_REG(dAdyDom); + pRC->MX1.CConstantColor = GLINT_READ_REG(ConstantColor); + pRC->MX1.CChromaUpper = GLINT_READ_REG(ChromaUpper); + pRC->MX1.CChromaLower = GLINT_READ_REG(ChromaLower); + pRC->MX1.CChromaTestMode = GLINT_READ_REG(ChromaTestMode); + pRC->MX1.CStencilData = GLINT_READ_REG(StencilData); + pRC->MX1.CGLINTStencil = GLINT_READ_REG(GLINTStencil); + pRC->MX1.CZStartU = GLINT_READ_REG(ZStartU); + pRC->MX1.CZStartL = GLINT_READ_REG(ZStartL); + pRC->MX1.CdZdxU = GLINT_READ_REG(dZdxU); + pRC->MX1.CdZdxL = GLINT_READ_REG(dZdxL); + pRC->MX1.CdZdyDomU = GLINT_READ_REG(dZdyDomU); + pRC->MX1.CdZdyDomL = GLINT_READ_REG(dZdyDomL); + pRC->MX1.CFastClearDepth = GLINT_READ_REG(FastClearDepth); + pRC->MX1.CMinRegion = GLINT_READ_REG(MinRegion); + pRC->MX1.CMaxRegion = GLINT_READ_REG(MaxRegion); + pRC->MX1.CKsRStart = GLINT_READ_REG(KsRStart); + pRC->MX1.CdKsRdx = GLINT_READ_REG(dKsRdx); + pRC->MX1.CdKsRdyDom = GLINT_READ_REG(dKsRdyDom); + pRC->MX1.CKsGStart = GLINT_READ_REG(KsGStart); + pRC->MX1.CdKsGdx = GLINT_READ_REG(dKsGdx); + pRC->MX1.CdKsGdyDom = GLINT_READ_REG(dKsGdyDom); + pRC->MX1.CKsBStart = GLINT_READ_REG(KsBStart); + pRC->MX1.CdKsBdx = GLINT_READ_REG(dKsBdx); + pRC->MX1.CdKsBdyDom = GLINT_READ_REG(dKsBdyDom); + pRC->MX1.CKdRStart = GLINT_READ_REG(KdRStart); + pRC->MX1.CdKdRdx = GLINT_READ_REG(dKdRdx); + pRC->MX1.CdKdRdyDom = GLINT_READ_REG(dKdRdyDom); + pRC->MX1.CKdGStart = GLINT_READ_REG(KdGStart); + pRC->MX1.CdKdGdx = GLINT_READ_REG(dKdGdx); + pRC->MX1.CdKdGdyDom = GLINT_READ_REG(dKdGdyDom); + pRC->MX1.CKdBStart = GLINT_READ_REG(KdBStart); + pRC->MX1.CdKdBdx = GLINT_READ_REG(dKdBdx); + pRC->MX1.CdKdBdyDom = GLINT_READ_REG(dKdBdyDom); + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + pRC->MX2.CSStart = GLINT_READ_REG(SStart); + pRC->MX2.CdSdx = GLINT_READ_REG(dSdx); + pRC->MX2.CdSdyDom = GLINT_READ_REG(dSdyDom); + pRC->MX2.CTStart = GLINT_READ_REG(TStart); + pRC->MX2.CdTdx = GLINT_READ_REG(dTdx); + pRC->MX2.CdTdyDom = GLINT_READ_REG(dTdyDom); + pRC->MX2.CQStart = GLINT_READ_REG(QStart); + pRC->MX2.CdQdx = GLINT_READ_REG(dQdx); + pRC->MX2.CdQdyDom = GLINT_READ_REG(dQdyDom); + pRC->MX2.CLOD = GLINT_READ_REG(LOD); + pRC->MX2.CdSdy = GLINT_READ_REG(dSdy); + pRC->MX2.CdTdy = GLINT_READ_REG(dTdy); + pRC->MX2.CdQdy = GLINT_READ_REG(dQdy); + pRC->MX2.CTextureFormat = GLINT_READ_REG(TextureFormat); + pRC->MX2.CTextureCacheControl = GLINT_READ_REG(TextureCacheControl); + pRC->MX2.CGLINTBorderColor = GLINT_READ_REG(GLINTBorderColor); + pRC->MX2.CTexelLUTIndex = GLINT_READ_REG(TexelLUTIndex); + pRC->MX2.CTexelLUTData = GLINT_READ_REG(TexelLUTData); + pRC->MX2.CTexelLUTAddress = GLINT_READ_REG(TexelLUTAddress); + pRC->MX2.CTexelLUTTransfer = GLINT_READ_REG(TexelLUTTransfer); + pRC->MX2.CTextureFilterMode = GLINT_READ_REG(TextureFilterMode); + pRC->MX2.CTextureChromaUpper = GLINT_READ_REG(TextureChromaUpper); + pRC->MX2.CTextureChromaLower = GLINT_READ_REG(TextureChromaLower); + pRC->MX2.CTxBaseAddr0 = GLINT_READ_REG(TxBaseAddr0); + pRC->MX2.CTxBaseAddr1 = GLINT_READ_REG(TxBaseAddr1); + pRC->MX2.CTxBaseAddr2 = GLINT_READ_REG(TxBaseAddr2); + pRC->MX2.CTxBaseAddr3 = GLINT_READ_REG(TxBaseAddr3); + pRC->MX2.CTxBaseAddr4 = GLINT_READ_REG(TxBaseAddr4); + pRC->MX2.CTxBaseAddr5 = GLINT_READ_REG(TxBaseAddr5); + pRC->MX2.CTxBaseAddr6 = GLINT_READ_REG(TxBaseAddr6); + pRC->MX2.CTxBaseAddr7 = GLINT_READ_REG(TxBaseAddr7); + pRC->MX2.CTxBaseAddr8 = GLINT_READ_REG(TxBaseAddr8); + pRC->MX2.CTxBaseAddr9 = GLINT_READ_REG(TxBaseAddr9); + pRC->MX2.CTxBaseAddr10 = GLINT_READ_REG(TxBaseAddr10); + pRC->MX2.CTxBaseAddr11 = GLINT_READ_REG(TxBaseAddr11); + pRC->MX2.CTexelLUT0 = GLINT_READ_REG(TexelLUT0); + pRC->MX2.CTexelLUT1 = GLINT_READ_REG(TexelLUT1); + pRC->MX2.CTexelLUT2 = GLINT_READ_REG(TexelLUT2); + pRC->MX2.CTexelLUT3 = GLINT_READ_REG(TexelLUT3); + pRC->MX2.CTexelLUT4 = GLINT_READ_REG(TexelLUT4); + pRC->MX2.CTexelLUT5 = GLINT_READ_REG(TexelLUT5); + pRC->MX2.CTexelLUT6 = GLINT_READ_REG(TexelLUT6); + pRC->MX2.CTexelLUT7 = GLINT_READ_REG(TexelLUT7); + pRC->MX2.CTexelLUT8 = GLINT_READ_REG(TexelLUT8); + pRC->MX2.CTexelLUT9 = GLINT_READ_REG(TexelLUT9); + pRC->MX2.CTexelLUT10 = GLINT_READ_REG(TexelLUT10); + pRC->MX2.CTexelLUT11 = GLINT_READ_REG(TexelLUT11); + pRC->MX2.CTexelLUT12 = GLINT_READ_REG(TexelLUT12); + pRC->MX2.CTexelLUT13 = GLINT_READ_REG(TexelLUT13); + pRC->MX2.CTexelLUT14 = GLINT_READ_REG(TexelLUT14); + pRC->MX2.CTexelLUT15 = GLINT_READ_REG(TexelLUT15); + pRC->MX2.CTexel0 = GLINT_READ_REG(Texel0); + pRC->MX2.CTexel1 = GLINT_READ_REG(Texel1); + pRC->MX2.CTexel2 = GLINT_READ_REG(Texel2); + pRC->MX2.CTexel3 = GLINT_READ_REG(Texel3); + pRC->MX2.CTexel4 = GLINT_READ_REG(Texel4); + pRC->MX2.CTexel5 = GLINT_READ_REG(Texel5); + pRC->MX2.CTexel6 = GLINT_READ_REG(Texel6); + pRC->MX2.CTexel7 = GLINT_READ_REG(Texel7); + pRC->MX2.CInterp0 = GLINT_READ_REG(Interp0); + pRC->MX2.CInterp1 = GLINT_READ_REG(Interp1); + pRC->MX2.CInterp2 = GLINT_READ_REG(Interp2); + pRC->MX2.CInterp3 = GLINT_READ_REG(Interp3); + pRC->MX2.CInterp4 = GLINT_READ_REG(Interp4); + pRC->MX2.CTextureFilter = GLINT_READ_REG(TextureFilter); + pRC->MX2.CTextureEnvColor = GLINT_READ_REG(TextureEnvColor); + pRC->MX2.CFogColor = GLINT_READ_REG(FogColor); + pRC->MX2.CFStart = GLINT_READ_REG(FStart); + pRC->MX2.CdFdx = GLINT_READ_REG(dFdx); + pRC->MX2.CdFdyDom = GLINT_READ_REG(dFdyDom); + pRC->MX2.CKsStart = GLINT_READ_REG(KsStart); + pRC->MX2.CdKsdx = GLINT_READ_REG(dKsdx); + pRC->MX2.CdKsdyDom = GLINT_READ_REG(dKsdyDom); + pRC->MX2.CKdStart = GLINT_READ_REG(KdStart); + pRC->MX2.CdKdStart = GLINT_READ_REG(dKdStart); + pRC->MX2.CdKddyDom = GLINT_READ_REG(dKddyDom); + pRC->MX2.CRStart = GLINT_READ_REG(RStart); + pRC->MX2.CdRdx = GLINT_READ_REG(dRdx); + pRC->MX2.CdRdyDom = GLINT_READ_REG(dRdyDom); + pRC->MX2.CGStart = GLINT_READ_REG(GStart); + pRC->MX2.CdGdx = GLINT_READ_REG(dGdx); + pRC->MX2.CdGdyDom = GLINT_READ_REG(dGdyDom); + pRC->MX2.CBStart = GLINT_READ_REG(BStart); + pRC->MX2.CdBdx = GLINT_READ_REG(dBdx); + pRC->MX2.CdBdyDom = GLINT_READ_REG(dBdyDom); + pRC->MX2.CAStart = GLINT_READ_REG(AStart); + pRC->MX2.CdAdx = GLINT_READ_REG(dAdx); + pRC->MX2.CdAdyDom = GLINT_READ_REG(dAdyDom); + pRC->MX2.CConstantColor = GLINT_READ_REG(ConstantColor); + pRC->MX2.CChromaUpper = GLINT_READ_REG(ChromaUpper); + pRC->MX2.CChromaLower = GLINT_READ_REG(ChromaLower); + pRC->MX2.CChromaTestMode = GLINT_READ_REG(ChromaTestMode); + pRC->MX2.CStencilData = GLINT_READ_REG(StencilData); + pRC->MX2.CGLINTStencil = GLINT_READ_REG(GLINTStencil); + pRC->MX2.CZStartU = GLINT_READ_REG(ZStartU); + pRC->MX2.CZStartL = GLINT_READ_REG(ZStartL); + pRC->MX2.CdZdxU = GLINT_READ_REG(dZdxU); + pRC->MX2.CdZdxL = GLINT_READ_REG(dZdxL); + pRC->MX2.CdZdyDomU = GLINT_READ_REG(dZdyDomU); + pRC->MX2.CdZdyDomL = GLINT_READ_REG(dZdyDomL); + pRC->MX2.CFastClearDepth = GLINT_READ_REG(FastClearDepth); + pRC->MX2.CMinRegion = GLINT_READ_REG(MinRegion); + pRC->MX2.CMaxRegion = GLINT_READ_REG(MaxRegion); + pRC->MX2.CKsRStart = GLINT_READ_REG(KsRStart); + pRC->MX2.CdKsRdx = GLINT_READ_REG(dKsRdx); + pRC->MX2.CdKsRdyDom = GLINT_READ_REG(dKsRdyDom); + pRC->MX2.CKsGStart = GLINT_READ_REG(KsGStart); + pRC->MX2.CdKsGdx = GLINT_READ_REG(dKsGdx); + pRC->MX2.CdKsGdyDom = GLINT_READ_REG(dKsGdyDom); + pRC->MX2.CKsBStart = GLINT_READ_REG(KsBStart); + pRC->MX2.CdKsBdx = GLINT_READ_REG(dKsBdx); + pRC->MX2.CdKsBdyDom = GLINT_READ_REG(dKsBdyDom); + pRC->MX2.CKdRStart = GLINT_READ_REG(KdRStart); + pRC->MX2.CdKdRdx = GLINT_READ_REG(dKdRdx); + pRC->MX2.CdKdRdyDom = GLINT_READ_REG(dKdRdyDom); + pRC->MX2.CKdGStart = GLINT_READ_REG(KdGStart); + pRC->MX2.CdKdGdx = GLINT_READ_REG(dKdGdx); + pRC->MX2.CdKdGdyDom = GLINT_READ_REG(dKdGdyDom); + pRC->MX2.CKdBStart = GLINT_READ_REG(KdBStart); + pRC->MX2.CdKdBdx = GLINT_READ_REG(dKdBdx); + pRC->MX2.CdKdBdyDom = GLINT_READ_REG(dKdBdyDom); + ACCESSCHIP1(); + } + + /* send gamma the context dump command */ + GLINT_WAIT(3); + if (pGlint->numMultiDevices == 2) + GLINT_WRITE_REG(1, BroadcastMask); + GLINT_WRITE_REG(3<<14, FilterMode); /* context bits on gamma */ + GLINT_WRITE_REG(GLINT_GAMMA_CONTEXT_MASK, ContextDump); + + /* save context data from output fifo */ + dumpIndex = 0; + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); +#ifdef DEBUG +xf86DrvMsg(pScreen->myNum, X_INFO, "pRC tag [%d]: %x\n", +dumpIndex,readValue); +#endif + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); +#ifdef DEBUG +xf86DrvMsg(pScreen->myNum, X_INFO, "pRC data [%d]: %x\n", +dumpIndex,readValue); +#endif + pRC->Gamma[dumpIndex++] = readValue; + } while (dumpIndex < GLINT_GAMMA_CONTEXT_SIZE); + + /* clear contextDump tag and data out of fifo */ + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + if (readValue != ContextDump_tag) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "Context dump error\n"); + } + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + + GLINT_SLOW_WRITE_REG(1<<10, FilterMode); + if (pGlint->numMultiDevices == 2) + GLINT_SLOW_WRITE_REG(3,BroadcastMask); + } + } + + if (writeContextType != DRI_NO_CONTEXT) { + + if (writeContextType == DRI_3D_CONTEXT) { + /* restore the 3D portion of the new context */ + + /* send context restore command */ + GLINT_WAIT(1); + if (pGlint->numMultiDevices == 2) + GLINT_WRITE_REG(1, BroadcastMask); + + GLINT_WAIT(3); + GLINT_WRITE_REG(ContextRestore_tag, OutputFIFO); + GLINT_WRITE_REG(GLINT_GAMMA_CONTEXT_MASK, OutputFIFO); + GLINT_WRITE_REG((((GLINT_GAMMA_CONTEXT_SIZE-1) << 16) | + ContextData_tag), OutputFIFO); + + /* restore context data to context data register */ + dumpIndex = 0; + do { + GLINT_WAIT(1); +#ifdef DEBUG +xf86DrvMsg(pScreen->myNum, X_INFO, "pWC data [%d]: %x\n", +dumpIndex,pWC->Gamma[dumpIndex]); +#endif + GLINT_WRITE_REG(pWC->Gamma[dumpIndex++], OutputFIFO); + } while (dumpIndex < (GLINT_GAMMA_CONTEXT_SIZE)); + + /* Sync after writing gamma context and + before writing MX context */ + if (pGlint->AccelInfoRec->Sync) { + (*pGlint->AccelInfoRec->Sync)(pGlint->AccelInfoRec->pScrn); + } + /* Update XAA's NeedToSync flag */ + pGlint->AccelInfoRec->NeedToSync = TRUE; + + /* finally the MX portions */ + if (pGlint->numMultiDevices == 2) + GLINT_SLOW_WRITE_REG(1, BroadcastMask); + GLINT_SLOW_WRITE_REG(pWC->MX1.CSStart, SStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdx, dSdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdyDom, dSdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTStart, TStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdx, dTdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdyDom, dTdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CQStart, QStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdx, dQdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdyDom, dQdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLOD, LOD); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdy, dSdy); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdy, dTdy); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdy, dQdy); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFormat, TextureFormat); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureCacheControl, TextureCacheControl); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTBorderColor, GLINTBorderColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTIndex, TexelLUTIndex); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTData, TexelLUTData); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTAddress, TexelLUTAddress); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTTransfer, TexelLUTTransfer); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFilterMode, TextureFilterMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureChromaUpper, TextureChromaUpper); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureChromaLower, TextureChromaLower); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr0, TxBaseAddr0); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr1, TxBaseAddr1); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr2, TxBaseAddr2); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr3, TxBaseAddr3); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr4, TxBaseAddr4); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr5, TxBaseAddr5); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr6, TxBaseAddr6); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr7, TxBaseAddr7); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr8, TxBaseAddr8); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr9, TxBaseAddr9); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr10, TxBaseAddr10); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr11, TxBaseAddr11); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT0, TexelLUT0); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT1, TexelLUT1); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT2, TexelLUT2); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT3, TexelLUT3); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT4, TexelLUT4); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT5, TexelLUT5); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT6, TexelLUT6); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT7, TexelLUT7); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT8, TexelLUT8); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT9, TexelLUT9); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT10, TexelLUT10); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT11, TexelLUT11); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT12, TexelLUT12); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT13, TexelLUT13); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT14, TexelLUT14); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT15, TexelLUT15); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel0, Texel0); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel1, Texel1); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel2, Texel2); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel3, Texel3); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel4, Texel4); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel5, Texel5); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel6, Texel6); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel7, Texel7); + GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp0, Interp0); + GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp1, Interp1); + GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp2, Interp2); + GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp3, Interp3); + GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp4, Interp4); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFilter, TextureFilter); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureEnvColor, TextureEnvColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFogColor, FogColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFStart, FStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdFdx, dFdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdFdyDom, dFdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKsStart, KsStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsdx, dKsdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsdyDom, dKsdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKdStart, KdStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdStart, dKdStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKddyDom, dKddyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CRStart, RStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdRdx, dRdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdRdyDom, dRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGStart, GStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdGdx, dGdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdGdyDom, dGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CBStart, BStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdBdx, dBdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdBdyDom, dBdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CAStart, AStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdAdx, dAdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdAdyDom, dAdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CConstantColor, ConstantColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaUpper, ChromaUpper); + GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaLower, ChromaLower); + GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaTestMode, ChromaTestMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStencilData, StencilData); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTStencil, GLINTStencil); + GLINT_SLOW_WRITE_REG(pWC->MX1.CZStartU, ZStartU); + GLINT_SLOW_WRITE_REG(pWC->MX1.CZStartL, ZStartL); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdxU, dZdxU); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdxL, dZdxL); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdyDomU, dZdyDomU); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdyDomL, dZdyDomL); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFastClearDepth, FastClearDepth); + GLINT_SLOW_WRITE_REG(pWC->MX1.CMinRegion, MinRegion); + GLINT_SLOW_WRITE_REG(pWC->MX1.CMaxRegion, MaxRegion); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKsRStart, KsRStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsRdx, dKsRdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsRdyDom, dKsRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKsGStart, KsGStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsGdx, dKsGdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsGdyDom, dKsGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKsBStart, KsBStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsBdx, dKsBdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsBdyDom, dKsBdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKdRStart, KdRStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdRdx, dKdRdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdRdyDom, dKdRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKdGStart, KdGStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdGdx, dKdGdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdGdyDom, dKdGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CKdBStart, KdBStart); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdBdx, dKdBdx); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdBdyDom, dKdBdyDom); + + if (pGlint->numMultiDevices == 2) { + GLINT_SLOW_WRITE_REG(2, BroadcastMask); + GLINT_SLOW_WRITE_REG(pWC->MX2.CSStart, SStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdx, dSdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdyDom, dSdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTStart, TStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdx, dTdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdyDom, dTdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CQStart, QStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdx, dQdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdyDom, dQdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLOD, LOD); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdy, dSdy); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdy, dTdy); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdy, dQdy); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFormat, TextureFormat); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureCacheControl, TextureCacheControl); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTBorderColor, GLINTBorderColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTIndex, TexelLUTIndex); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTData, TexelLUTData); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTAddress, TexelLUTAddress); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTTransfer, TexelLUTTransfer); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFilterMode, TextureFilterMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureChromaUpper, TextureChromaUpper); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureChromaLower, TextureChromaLower); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr0, TxBaseAddr0); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr1, TxBaseAddr1); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr2, TxBaseAddr2); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr3, TxBaseAddr3); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr4, TxBaseAddr4); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr5, TxBaseAddr5); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr6, TxBaseAddr6); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr7, TxBaseAddr7); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr8, TxBaseAddr8); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr9, TxBaseAddr9); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr10, TxBaseAddr10); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr11, TxBaseAddr11); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT0, TexelLUT0); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT1, TexelLUT1); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT2, TexelLUT2); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT3, TexelLUT3); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT4, TexelLUT4); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT5, TexelLUT5); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT6, TexelLUT6); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT7, TexelLUT7); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT8, TexelLUT8); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT9, TexelLUT9); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT10, TexelLUT10); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT11, TexelLUT11); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT12, TexelLUT12); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT13, TexelLUT13); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT14, TexelLUT14); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT15, TexelLUT15); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel0, Texel0); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel1, Texel1); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel2, Texel2); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel3, Texel3); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel4, Texel4); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel5, Texel5); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel6, Texel6); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel7, Texel7); + GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp0, Interp0); + GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp1, Interp1); + GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp2, Interp2); + GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp3, Interp3); + GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp4, Interp4); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFilter, TextureFilter); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureEnvColor, TextureEnvColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFogColor, FogColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFStart, FStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdFdx, dFdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdFdyDom, dFdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKsStart, KsStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsdx, dKsdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsdyDom, dKsdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKdStart, KdStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdStart, dKdStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKddyDom, dKddyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CRStart, RStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdRdx, dRdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdRdyDom, dRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGStart, GStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdGdx, dGdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdGdyDom, dGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CBStart, BStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdBdx, dBdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdBdyDom, dBdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CAStart, AStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdAdx, dAdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdAdyDom, dAdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CConstantColor, ConstantColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaUpper, ChromaUpper); + GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaLower, ChromaLower); + GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaTestMode, ChromaTestMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStencilData, StencilData); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTStencil, GLINTStencil); + GLINT_SLOW_WRITE_REG(pWC->MX2.CZStartU, ZStartU); + GLINT_SLOW_WRITE_REG(pWC->MX2.CZStartL, ZStartL); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdxU, dZdxU); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdxL, dZdxL); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdyDomU, dZdyDomU); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdyDomL, dZdyDomL); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFastClearDepth, FastClearDepth); + GLINT_SLOW_WRITE_REG(pWC->MX2.CMinRegion, MinRegion); + GLINT_SLOW_WRITE_REG(pWC->MX2.CMaxRegion, MaxRegion); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKsRStart, KsRStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsRdx, dKsRdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsRdyDom, dKsRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKsGStart, KsGStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsGdx, dKsGdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsGdyDom, dKsGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKsBStart, KsBStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsBdx, dKsBdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsBdyDom, dKsBdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKdRStart, KdRStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdRdx, dKdRdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdRdyDom, dKdRdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKdGStart, KdGStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdGdx, dKdGdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdGdyDom, dKdGdyDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CKdBStart, KdBStart); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdBdx, dKdBdx); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdBdyDom, dKdBdyDom); + } + } + + /* restore the 2D portion of the new context */ + + /* Restore MX1's registers */ + if (pGlint->numMultiDevices == 2) + GLINT_SLOW_WRITE_REG(1, BroadcastMask); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStartXDom, StartXDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdXDom, dXDom); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStartXSub, StartXSub); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdXSub, dXSub); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStartY, StartY); + GLINT_SLOW_WRITE_REG(pWC->MX1.CdY, dY); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTCount, GLINTCount); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable0, PointTable0); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable1, PointTable1); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable2, PointTable2); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable3, PointTable3); + GLINT_SLOW_WRITE_REG(pWC->MX1.CRasterizerMode, RasterizerMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CYLimits, YLimits); + GLINT_SLOW_WRITE_REG(pWC->MX1.CScanLineOwnership, ScanLineOwnership); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPixelSize, PixelSize); + GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMode, ScissorMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMinXY, ScissorMinXY); + GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMaxXY, ScissorMaxXY); + GLINT_SLOW_WRITE_REG(pWC->MX1.CScreenSize, ScreenSize); + GLINT_SLOW_WRITE_REG(pWC->MX1.CAreaStippleMode, AreaStippleMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLineStippleMode, LineStippleMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLoadLineStippleCounters, LoadLineStippleCounters); + GLINT_SLOW_WRITE_REG(pWC->MX1.CWindowOrigin, WindowOrigin); + GLINT_SLOW_WRITE_REG(pWC->MX1.CRouterMode, RouterMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureAddressMode, TextureAddressMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureReadMode, TextureReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureColorMode, TextureColorMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFogMode, FogMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CColorDDAMode, ColorDDAMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTColor, GLINTColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CAlphaTestMode, AlphaTestMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CAntialiasMode, AntialiasMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CAlphaBlendMode, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CDitherMode, DitherMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBSoftwareWriteMask, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLogicalOpMode, LogicalOpMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWriteData, FBWriteData); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLBReadMode, LBReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLBSourceOffset, LBSourceOffset); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWindowBase, LBWindowBase); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWriteMode, LBWriteMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureDownloadOffset, TextureDownloadOffset); + GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWindowOffset, LBWindowOffset); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTWindow, GLINTWindow); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStencilMode, StencilMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CDepthMode, DepthMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTDepth, GLINTDepth); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBReadMode, FBReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBSourceOffset, FBSourceOffset); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBPixelOffset, FBPixelOffset); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWindowBase, FBWindowBase); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWriteMode, FBWriteMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBHardwareWriteMask, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColor, FBBlockColor); + GLINT_SLOW_WRITE_REG(pWC->MX1.CPatternRamMode, PatternRamMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColorU, FBBlockColorU); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColorL, FBBlockColorL); + GLINT_SLOW_WRITE_REG(pWC->MX1.CFilterMode, FilterMode); + GLINT_SLOW_WRITE_REG(pWC->MX1.CStatisticMode, StatisticMode); + + /* Restore MX2's registers */ + if (pGlint->numMultiDevices == 2) { + GLINT_SLOW_WRITE_REG(2, BroadcastMask); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStartXDom, StartXDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdXDom, dXDom); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStartXSub, StartXSub); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdXSub, dXSub); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStartY, StartY); + GLINT_SLOW_WRITE_REG(pWC->MX2.CdY, dY); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTCount, GLINTCount); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable0, PointTable0); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable1, PointTable1); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable2, PointTable2); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable3, PointTable3); + GLINT_SLOW_WRITE_REG(pWC->MX2.CRasterizerMode, RasterizerMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CYLimits, YLimits); + GLINT_SLOW_WRITE_REG(pWC->MX2.CScanLineOwnership, ScanLineOwnership); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPixelSize, PixelSize); + GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMode, ScissorMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMinXY, ScissorMinXY); + GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMaxXY, ScissorMaxXY); + GLINT_SLOW_WRITE_REG(pWC->MX2.CScreenSize, ScreenSize); + GLINT_SLOW_WRITE_REG(pWC->MX2.CAreaStippleMode, AreaStippleMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLineStippleMode, LineStippleMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLoadLineStippleCounters, LoadLineStippleCounters); + GLINT_SLOW_WRITE_REG(pWC->MX2.CWindowOrigin, WindowOrigin); + GLINT_SLOW_WRITE_REG(pWC->MX2.CRouterMode, RouterMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureAddressMode, TextureAddressMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureReadMode, TextureReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureColorMode, TextureColorMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFogMode, FogMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CColorDDAMode, ColorDDAMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTColor, GLINTColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CAlphaTestMode, AlphaTestMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CAntialiasMode, AntialiasMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CAlphaBlendMode, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CDitherMode, DitherMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBSoftwareWriteMask, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLogicalOpMode, LogicalOpMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWriteData, FBWriteData); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLBReadMode, LBReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLBSourceOffset, LBSourceOffset); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWindowBase, LBWindowBase); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWriteMode, LBWriteMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureDownloadOffset, TextureDownloadOffset); + GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWindowOffset, LBWindowOffset); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTWindow, GLINTWindow); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStencilMode, StencilMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CDepthMode, DepthMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTDepth, GLINTDepth); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBReadMode, FBReadMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBSourceOffset, FBSourceOffset); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBPixelOffset, FBPixelOffset); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWindowBase, FBWindowBase); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWriteMode, FBWriteMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBHardwareWriteMask, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColor, FBBlockColor); + GLINT_SLOW_WRITE_REG(pWC->MX2.CPatternRamMode, PatternRamMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColorU, FBBlockColorU); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColorL, FBBlockColorL); + GLINT_SLOW_WRITE_REG(pWC->MX2.CFilterMode, FilterMode); + GLINT_SLOW_WRITE_REG(pWC->MX2.CStatisticMode, StatisticMode); + + /* Restore the "real" broadcast mask last */ + GLINT_SLOW_WRITE_REG(pWC->MX1.CBroadcastMask, BroadcastMask); + } + /* Sync is needed here probabilistically */ + if (pGlint->AccelInfoRec->Sync) { + (*pGlint->AccelInfoRec->Sync)(pGlint->AccelInfoRec->pScrn); + pGlint->AccelInfoRec->NeedToSync = FALSE; + } + } +} + +void +GLINTDRIInitBuffers( + WindowPtr pWin, + RegionPtr prgn, + CARD32 index) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + BoxPtr pbox; + int nbox; + + pbox = REGION_RECTS(prgn); + nbox = REGION_NUM_RECTS(prgn); + + GLINT_WAIT(7); + /* Turn off writes the FB */ + GLINT_WRITE_REG(0, FBWriteMode); + GLINT_WRITE_REG(0, LBWindowBase); + GLINT_WRITE_REG(1, LBWriteMode); + if (pGlint->numMultiDevices == 2) { + GLINT_WRITE_REG( pGlint->pprod | + LBRM_ScanlineInt2 , LBReadMode); + } else { + GLINT_WRITE_REG( pGlint->pprod , LBReadMode); + } + GLINT_WRITE_REG(0, LBDepth); + GLINT_WRITE_REG(0, LBStencil); + GLINT_WRITE_REG( GWIN_UnitEnable | + GWIN_ForceLBUpdate | + ((index & 0xf) << 5) | + GWIN_LBUpdateSourceREG | + GWIN_OverrideWriteFilter, GLINTWindow); + + while (nbox--) { + GLINT_WAIT(8); + GLINT_WRITE_REG((pbox->x2)<<16, StartXSub); + GLINT_WRITE_REG((pbox->x1)<<16, StartXDom); + GLINT_WRITE_REG((pbox->y1)<<16, StartY); + GLINT_WRITE_REG((pbox->y2 - pbox->y1), GLINTCount); + GLINT_WRITE_REG(0, dXDom); + GLINT_WRITE_REG(0x10000, dY); + /* Must also set dXSub, since 3D tris cause it to be != 0 */ + GLINT_WRITE_REG(0, dXSub); + GLINT_WRITE_REG(PrimitiveTrapezoid, Render); + pbox++; + } + + GLINT_WAIT(3); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow); + + /* Update XAA's NeedToSync flag */ + pGlint->AccelInfoRec->NeedToSync = TRUE; +} + +void +GLINTDRIMoveBuffers( + WindowPtr pParent, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc, + CARD32 index) +{ +#if 0 + ScreenPtr pScreen = pParent->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#endif + int dx, dy; + WindowPtr pChild; + RegionRec rgnSubWindow, rgnTranslateSrc; + CARD32 indexSubWindow; + + /* NOT_DONE: For now, just init the buffer. We are not copying the depth + * and stencil, they just get redrawn for the next frame(s). + */ + + REGION_INIT(pScreen, &rgnSubWindow, NullBox, 0); + REGION_INIT(pScreen, &rgnTranslateSrc, NullBox, 0); + REGION_COPY(pScreen, &rgnTranslateSrc, prgnSrc); + dx = ptOldOrg.x - pParent->drawable.x; + dy = ptOldOrg.y - pParent->drawable.y; + REGION_TRANSLATE(pScreen, &rgnTranslateSrc, -dx, -dy); + + pChild = pParent; + while (1) { + if (pChild->viewable) { + REGION_INTERSECT(pScreen, &rgnSubWindow, + &pChild->borderClip, &rgnTranslateSrc); + indexSubWindow = DRIGetDrawableIndex(pChild); + GLINTDRIInitBuffers( pChild, &rgnSubWindow, indexSubWindow); + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + } + while (!pChild->nextSib && (pChild != pParent)) + pChild = pChild->parent; + if (pChild == pParent) + break; + pChild = pChild->nextSib; + } +} diff --git a/src/glint_dri.h b/src/glint_dri.h new file mode 100644 index 0000000..3952759 --- /dev/null +++ b/src/glint_dri.h @@ -0,0 +1,123 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h,v 1.7 2002/10/30 12:52:16 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Author: + * Jens Owen <jens@tungstengraphics.com> + * + */ + +#ifndef _GLINT_DRI_H_ +#define _GLINT_DRI_H_ + +#include "xf86drm.h" +#include "glint_common.h" + +typedef struct { + unsigned int GDeltaMode; + unsigned int GDepthMode; + unsigned int GGeometryMode; + unsigned int GTransformMode; +} GAMMAContextRegionRec, *GAMMAContextRegionPtr; + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} GAMMATextureRegionRec, *GAMMATextureRegionPtr; + +typedef struct { + GAMMAContextRegionRec context_state; + + unsigned int dirty; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + +#define GAMMA_NR_TEX_REGIONS 64 + GAMMATextureRegionRec texList[GAMMA_NR_TEX_REGIONS+1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ + + int vertex_prim; +} GLINTSAREADRIRec, *GLINTSAREADRIPtr; + +/* + * Glint specific record passed back to client driver + * via DRIGetDeviceInfo request + */ +typedef struct { + drmRegion registers0; + drmRegion registers1; + drmRegion registers2; + drmRegion registers3; + int numMultiDevices; + int pprod; + int cpp; + int frontOffset; + int frontPitch; + int backOffset; + int backPitch; + int backX; + int backY; + int depthOffset; + int depthPitch; + int textureSize; + int logTextureGranularity; +} GLINTDRIRec, *GLINTDRIPtr; + +#define GLINT_DRI_BUF_COUNT 256 +#define GLINT_DRI_BUF_SIZE 4096 + +#define GAMMA_NR_TEX_REGIONS 64 + +#define DMA_WRITE(val,reg) \ +do { \ + pGlint->buf2D++ = Glint##reg##Tag; \ + pGlint->buf2D++ = val; \ +} while (0) + +#endif /* _GLINT_DRI_H_ */ diff --git a/src/glint_dripriv.h b/src/glint_dripriv.h new file mode 100644 index 0000000..15d5e48 --- /dev/null +++ b/src/glint_dripriv.h @@ -0,0 +1,296 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h,v 1.6 2002/10/30 12:52:16 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Author: + * Jens Owen <jens@tungstengraphics.com> + * + */ + +extern void GlxSetVisualConfigs( + int nconfigs, + __GLXvisualConfig *configs, + void **configprivs +); + +extern Bool GLINTCreateContext(ScreenPtr pScreen, + VisualPtr visual, + drmContext hwContext, + void* pVisualConfigPriv, + DRIContextType contextStore); + +extern void GLINTDRISwapContext( ScreenPtr pScreen, + DRISyncType syncType, + DRIContextType readContextType, + void* readContextStore, + DRIContextType writeContextType, + void* writeContextStore); + +/* Macros to Setup Generic Kernel Device Driver to Handle DMA for gamma */ + +/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the + kernel must be specified here. Currently, the number is 2. */ +#define DRM_REG(reg) \ + (2 \ + + ((reg < 0x1000) \ + ? 0 \ + : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3)))) + +#define DRM_OFF(reg) \ + ((reg < 0x1000) \ + ? reg \ + : ((reg < 0x10000) \ + ? (reg - 0x1000) \ + : ((reg < 0x11000) \ + ? (reg - 0x10000) \ + : (reg - 0x11000)))) + + +#define DRM_I_WRITE_R(reg,a,b,c,d) \ + DRM_I_WRITE(DRM_REG(reg), DRM_OFF(reg), a, b, c, d) + +#define DRM_I_WRITE_IMM_R(reg,a) \ + DRM_I_WRITE_IMM(DRM_REG(reg), DRM_OFF(reg), a) + +#define DRM_I_READ_R(reg) \ + DRM_I_READ(DRM_REG(reg), DRM_OFF(reg)) + +#define DRM_I_WHILE_IMM_R(reg,a,b) \ + DRM_I_WHILE_IMM(DRM_REG(reg), DRM_OFF(reg), a, b) + +#define DRM_I_IF_IMM_R(reg,a,b,c) \ + DRM_I_IF_IMM(DRM_REG(reg), DRM_OFF(reg), a, b, c) + +#define GLINTSync GlintSync +#define GLINTSyncTag 0x188 + +#define GLINT_MAX_DRAWABLES 15 +#define GLINT_GAMMA_CONTEXT_SIZE 964 +#define GLINT_GAMMA_CONTEXT_MASK 0x7ff + +typedef struct { + int index; +} GLINTConfigPrivRec, *GLINTConfigPrivPtr; + +typedef struct { + + /* 2D components */ + CARD32 CStartXDom; + CARD32 CdXDom; + CARD32 CStartXSub; + CARD32 CdXSub; + CARD32 CStartY; + CARD32 CdY; + CARD32 CGLINTCount; + CARD32 CPointTable0; + CARD32 CPointTable1; + CARD32 CPointTable2; + CARD32 CPointTable3; + CARD32 CRasterizerMode; + CARD32 CYLimits; + CARD32 CScanLineOwnership; + CARD32 CPixelSize; + CARD32 CScissorMode; + CARD32 CScissorMinXY; + CARD32 CScissorMaxXY; + CARD32 CScreenSize; + CARD32 CAreaStippleMode; + CARD32 CLineStippleMode; + CARD32 CLoadLineStippleCounters; + CARD32 CWindowOrigin; + CARD32 CRouterMode; + CARD32 CTextureAddressMode; + CARD32 CTextureReadMode; + CARD32 CTextureColorMode; + CARD32 CFogMode; + CARD32 CColorDDAMode; + CARD32 CGLINTColor; + CARD32 CAlphaTestMode; + CARD32 CAntialiasMode; + CARD32 CAlphaBlendMode; + CARD32 CDitherMode; + CARD32 CFBSoftwareWriteMask; + CARD32 CLogicalOpMode; + CARD32 CFBWriteData; + CARD32 CLBReadMode; + CARD32 CLBSourceOffset; + CARD32 CLBWindowBase; + CARD32 CLBWriteMode; + CARD32 CTextureDownloadOffset; + CARD32 CLBWindowOffset; + CARD32 CGLINTWindow; + CARD32 CStencilMode; + CARD32 CDepthMode; + CARD32 CGLINTDepth; + CARD32 CFBReadMode; + CARD32 CFBSourceOffset; + CARD32 CFBPixelOffset; + CARD32 CFBWindowBase; + CARD32 CFBWriteMode; + CARD32 CFBHardwareWriteMask; + CARD32 CFBBlockColor; + CARD32 CPatternRamMode; + CARD32 CFBBlockColorU; + CARD32 CFBBlockColorL; + CARD32 CFilterMode; + CARD32 CStatisticMode; + CARD32 CBroadcastMask; + + /* 3D components */ + CARD32 CSStart; + CARD32 CdSdx; + CARD32 CdSdyDom; + CARD32 CTStart; + CARD32 CdTdx; + CARD32 CdTdyDom; + CARD32 CQStart; + CARD32 CdQdx; + CARD32 CdQdyDom; + CARD32 CLOD; + CARD32 CdSdy; + CARD32 CdTdy; + CARD32 CdQdy; + CARD32 CTex; + CARD32 CTextureFormat; + CARD32 CTextureCacheControl; + CARD32 CGLINTBorderColor; + CARD32 CTexelLUTIndex; + CARD32 CTexelLUTData; + CARD32 CTexelLUTAddress; + CARD32 CTexelLUTTransfer; + CARD32 CTextureFilterMode; + CARD32 CTextureChromaUpper; + CARD32 CTextureChromaLower; + CARD32 CTxBaseAddr0; + CARD32 CTxBaseAddr1; + CARD32 CTxBaseAddr2; + CARD32 CTxBaseAddr3; + CARD32 CTxBaseAddr4; + CARD32 CTxBaseAddr5; + CARD32 CTxBaseAddr6; + CARD32 CTxBaseAddr7; + CARD32 CTxBaseAddr8; + CARD32 CTxBaseAddr9; + CARD32 CTxBaseAddr10; + CARD32 CTxBaseAddr11; + CARD32 CTxBaseAddr12; + CARD32 CTexelLUT0; + CARD32 CTexelLUT1; + CARD32 CTexelLUT2; + CARD32 CTexelLUT3; + CARD32 CTexelLUT4; + CARD32 CTexelLUT5; + CARD32 CTexelLUT6; + CARD32 CTexelLUT7; + CARD32 CTexelLUT8; + CARD32 CTexelLUT9; + CARD32 CTexelLUT10; + CARD32 CTexelLUT11; + CARD32 CTexelLUT12; + CARD32 CTexelLUT13; + CARD32 CTexelLUT14; + CARD32 CTexelLUT15; + CARD32 CTexel0; + CARD32 CTexel1; + CARD32 CTexel2; + CARD32 CTexel3; + CARD32 CTexel4; + CARD32 CTexel5; + CARD32 CTexel6; + CARD32 CTexel7; + CARD32 CInterp0; + CARD32 CInterp1; + CARD32 CInterp2; + CARD32 CInterp3; + CARD32 CInterp4; + CARD32 CTextureFilter; + CARD32 CTextureEnvColor; + CARD32 CFogColor; + CARD32 CFStart; + CARD32 CdFdx; + CARD32 CdFdyDom; + CARD32 CKsStart; + CARD32 CdKsdx; + CARD32 CdKsdyDom; + CARD32 CKdStart; + CARD32 CdKdStart; + CARD32 CdKddyDom; + CARD32 CRStart; + CARD32 CdRdx; + CARD32 CdRdyDom; + CARD32 CGStart; + CARD32 CdGdx; + CARD32 CdGdyDom; + CARD32 CBStart; + CARD32 CdBdx; + CARD32 CdBdyDom; + CARD32 CAStart; + CARD32 CdAdx; + CARD32 CdAdyDom; + CARD32 CConstantColor; + CARD32 CChromaUpper; + CARD32 CChromaLower; + CARD32 CChromaTestMode; + CARD32 CStencilData; + CARD32 CGLINTStencil; + CARD32 CZStartU; + CARD32 CZStartL; + CARD32 CdZdxU; + CARD32 CdZdxL; + CARD32 CdZdyDomU; + CARD32 CdZdyDomL; + CARD32 CFastClearDepth; + CARD32 CMinRegion; + CARD32 CMaxRegion; + CARD32 CKsRStart; + CARD32 CdKsRdx; + CARD32 CdKsRdyDom; + CARD32 CKsGStart; + CARD32 CdKsGdx; + CARD32 CdKsGdyDom; + CARD32 CKsBStart; + CARD32 CdKsBdx; + CARD32 CdKsBdyDom; + CARD32 CKdRStart; + CARD32 CdKdRdx; + CARD32 CdKdRdyDom; + CARD32 CKdGStart; + CARD32 CdKdGdx; + CARD32 CdKdGdyDom; + CARD32 CKdBStart; + CARD32 CdKdBdx; + CARD32 CdKdBdyDom; + +} GLINTMXRec; + +typedef struct { + GLINTMXRec MX1; + GLINTMXRec MX2; + CARD32 Gamma[GLINT_GAMMA_CONTEXT_SIZE]; +} GLINTDRIContextRec, *GLINTDRIContextPtr; diff --git a/src/glint_driver.c b/src/glint_driver.c new file mode 100644 index 0000000..de0c992 --- /dev/null +++ b/src/glint_driver.c @@ -0,0 +1,3875 @@ +/* + * Copyright 1997-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Michel Dänzer, <michdaen@iiic.ethz.ch> + * Sven Luther, <luther@dpt-info.u-strasbg.fr> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen, + * Siemens Nixdorf Informationssysteme and Appian Graphics. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.156 2003/02/17 16:08:28 dawes Exp $ */ + +#include "fb.h" +#include "cfb8_32.h" +#include "micmap.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "shadowfb.h" +#include "fbdevhw.h" +#include "xf86RAC.h" +#include "xf86Resources.h" +#include "xf86int10.h" +#include "dixstruct.h" +#include "vbe.h" + +#include "compiler.h" +#include "mipointer.h" + +#include "mibstore.h" + +#include "pm3_regs.h" +#include "glint_regs.h" +#include "IBM.h" +#include "TI.h" +#include "glint.h" + +#define _XF86DGA_SERVER_ +#include "extensions/xf86dgastr.h" + +#include "globals.h" +#define DPMS_SERVER +#include "extensions/dpms.h" + +#define DEBUG 0 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("glint: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("glint: " str " done\n") +# define TRACE(str) ErrorF("glint trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +# define TRACE(str) +#endif + +static const OptionInfoRec * GLINTAvailableOptions(int chipid, int busid); +static void GLINTIdentify(int flags); +static Bool GLINTProbe(DriverPtr drv, int flags); +static Bool GLINTPreInit(ScrnInfoPtr pScrn, int flags); +static Bool GLINTScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool GLINTEnterVT(int scrnIndex, int flags); +static void GLINTLeaveVT(int scrnIndex, int flags); +static Bool GLINTCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool GLINTSaveScreen(ScreenPtr pScreen, int mode); + +/* Optional functions */ +static void GLINTFreeScreen(int scrnIndex, int flags); +static int GLINTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); + +/* Internally used functions */ +static Bool GLINTMapMem(ScrnInfoPtr pScrn); +static Bool GLINTUnmapMem(ScrnInfoPtr pScrn); +static void GLINTSave(ScrnInfoPtr pScrn); +static void GLINTRestore(ScrnInfoPtr pScrn); +static Bool GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void GLINTBlockHandler(int, pointer, pointer, pointer); + +/* + * This is intentionally screen-independent. It indicates the binding + * choice made in the first PreInit. + */ +static int GLINTEntityIndex = -1; +static Bool FBDevProbed = FALSE; + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the SetupProc + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +DriverRec GLINT = { + VERSION, + GLINT_DRIVER_NAME, + GLINTIdentify, + GLINTProbe, + GLINTAvailableOptions, + NULL, + 0 +}; + +static SymTabRec GLINTVGAChipsets[] = { + { PCI_VENDOR_TI_CHIP_PERMEDIA2, "ti_pm2" }, + { PCI_VENDOR_TI_CHIP_PERMEDIA, "ti_pm" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, "pm4" }, + { PCI_VENDOR_3DLABS_CHIP_R4, "r4" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, "pm3" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, "pm2v" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, "pm2" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, "pm" }, + {-1, NULL } +}; + +static PciChipsets GLINTVGAPciChipsets[] = { + { PCI_VENDOR_TI_CHIP_PERMEDIA2, PCI_VENDOR_TI_CHIP_PERMEDIA2, RES_SHARED_VGA }, + { PCI_VENDOR_TI_CHIP_PERMEDIA, PCI_VENDOR_TI_CHIP_PERMEDIA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_R4, PCI_VENDOR_3DLABS_CHIP_R4, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, PCI_VENDOR_3DLABS_CHIP_PERMEDIA, NULL }, + { -1, -1, RES_UNDEFINED } +}; + +static SymTabRec GLINTChipsets[] = { + { PCI_VENDOR_3DLABS_CHIP_GAMMA, "gamma" }, + { PCI_VENDOR_3DLABS_CHIP_GAMMA2, "gamma2" }, + { PCI_VENDOR_TI_CHIP_PERMEDIA2, "ti_pm2" }, + { PCI_VENDOR_TI_CHIP_PERMEDIA, "ti_pm" }, + { PCI_VENDOR_3DLABS_CHIP_R4, "r4" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, "pm4" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, "pm3" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, "pm2v" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, "pm2" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, "pm" }, + { PCI_VENDOR_3DLABS_CHIP_300SX, "300sx" }, + { PCI_VENDOR_3DLABS_CHIP_500TX, "500tx" }, + { PCI_VENDOR_3DLABS_CHIP_MX, "mx" }, + { PCI_VENDOR_3DLABS_CHIP_DELTA, "delta" }, + { -1, NULL } +}; + +static PciChipsets GLINTPciChipsets[] = { + { PCI_VENDOR_3DLABS_CHIP_GAMMA, PCI_VENDOR_3DLABS_CHIP_GAMMA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_GAMMA2, PCI_VENDOR_3DLABS_CHIP_GAMMA2, NULL }, + { PCI_VENDOR_TI_CHIP_PERMEDIA2, PCI_VENDOR_TI_CHIP_PERMEDIA2, RES_SHARED_VGA }, + { PCI_VENDOR_TI_CHIP_PERMEDIA, PCI_VENDOR_TI_CHIP_PERMEDIA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_R4, PCI_VENDOR_3DLABS_CHIP_R4, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, RES_SHARED_VGA }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, PCI_VENDOR_3DLABS_CHIP_PERMEDIA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_300SX, PCI_VENDOR_3DLABS_CHIP_300SX, NULL }, + { PCI_VENDOR_3DLABS_CHIP_500TX, PCI_VENDOR_3DLABS_CHIP_500TX, NULL }, + { PCI_VENDOR_3DLABS_CHIP_MX, PCI_VENDOR_3DLABS_CHIP_MX, NULL }, + { PCI_VENDOR_3DLABS_CHIP_DELTA, PCI_VENDOR_3DLABS_CHIP_DELTA, NULL }, + { -1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_SW_CURSOR, + OPTION_RGB_BITS, + OPTION_NOACCEL, + OPTION_BLOCK_WRITE, + OPTION_FIREGL3000, + OPTION_OVERLAY, + OPTION_SHADOW_FB, + OPTION_FBDEV, + OPTION_FLATPANEL, + OPTION_VIDEO_KEY +} GLINTOpts; + +static const OptionInfoRec GLINTOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_BLOCK_WRITE, "BlockWrite", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FIREGL3000, "FireGL3000", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FLATPANEL, "UseFlatPanel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static RamDacSupportedInfoRec IBMRamdacs[] = { + { IBM526DB_RAMDAC }, + { IBM526_RAMDAC }, + { IBM640_RAMDAC }, + { -1 } +}; + +static RamDacSupportedInfoRec TIRamdacs[] = { + { TI3030_RAMDAC }, + { TI3026_RAMDAC }, + { -1 } +}; + +static const char *xf8_32bppSymbols[] = { + "cfb8_32ScreenInit", + "xf86Overlay8Plus32Init", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAFillSolidRects", + "XAAInit", + "XAAPolyLines", + "XAAPolySegment", + "XAAScreenIndex", + NULL +}; + +static const char *fbSymbols[] = { + "fbBres", + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC2", + "xf86SetDDCproperties", + NULL +}; + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86DestroyI2CBusRec", + "xf86DestroyI2CDevRec", + "xf86I2CBusInit", + "xf86I2CDevInit", + "xf86I2CProbeAddress", + "xf86I2CWriteByte", + "xf86I2CWriteVec", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef XFree86LOADER +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; +#endif + +static const char *ramdacSymbols[] = { + "IBMramdac526CalculateMNPCForClock", + "IBMramdac640CalculateMNPCForClock", + "IBMramdacProbe", + "RamDacCreateInfoRec", + "RamDacDestroyInfoRec", + "RamDacFreeRec", + "RamDacGetHWIndex", + "RamDacHandleColormaps", + "RamDacInit", + "TIramdacCalculateMNPForClock", + "TIramdacLoadPalette", + "TIramdacProbe", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL +}; + + +static const char *fbdevHWSymbols[] = { + "fbdevHWFreeRec", + "fbdevHWInit", + "fbdevHWProbe", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + + /* ScrnInfo hooks */ + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + "fbdevHWModeInit", + "fbdevHWRestore", + "fbdevHWSave", + "fbdevHWSwitchMode", + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWValidMode", + + NULL +}; + +const char *GLINTint10Symbols[] = { + "xf86FreeInt10", + "xf86InitInt10", + NULL +}; + +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmCommandWrite", + "drmCtlInstHandler", + "drmFreeVersion", + "drmGetInterruptFromBusID", + "drmGetLibVersion", + "drmGetVersion", + "drmMapBufs", + "drmUnmapBufs", + NULL +}; + +static const char *driSymbols[] = { + "DRICloseScreen", + "DRICreateInfoRec", + "DRIDestroyInfoRec", + "DRIFinishScreenInit", + "DRIGetDrawableIndex", + "DRIQueryVersion", + "DRIScreenInit", + "GlxSetVisualConfigs", + NULL +}; +#endif + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(glintSetup); + +static XF86ModuleVersionInfo glintVersRec = +{ + "glint", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + GLINT_MAJOR_VERSION, GLINT_MINOR_VERSION, GLINT_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +XF86ModuleData glintModuleData = { &glintVersRec, glintSetup, NULL }; + +pointer +glintSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&GLINT, module, 0); + LoaderRefSymLists(fbSymbols, ddcSymbols, i2cSymbols, + xaaSymbols, xf8_32bppSymbols, + shadowSymbols, fbdevHWSymbols, GLINTint10Symbols, + vbeSymbols, ramdacSymbols, +#ifdef XF86DRI + drmSymbols, driSymbols, +#endif + NULL); + return (pointer)TRUE; + } + + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; +} + +#endif /* XFree86LOADER */ + +#define PARTPROD(a,b,c) (((a)<<6) | ((b)<<3) | (c)) + +static char bppand[4] = { 0x03, /* 8bpp */ + 0x01, /* 16bpp */ + 0x00, /* 24bpp */ + 0x00 /* 32bpp */}; + +static int partprod500TX[] = { + -1, + PARTPROD(0,0,1), PARTPROD(0,0,2), PARTPROD(0,1,2), PARTPROD(0,0,3), + PARTPROD(0,1,3), PARTPROD(0,2,3), PARTPROD(1,2,3), PARTPROD(0,0,4), + PARTPROD(0,1,4), PARTPROD(0,2,4), PARTPROD(1,2,4), PARTPROD(0,3,4), + PARTPROD(1,3,4), PARTPROD(2,3,4), -1, PARTPROD(0,0,5), + PARTPROD(0,1,5), PARTPROD(0,2,5), PARTPROD(1,2,5), PARTPROD(0,3,5), + PARTPROD(1,3,5), PARTPROD(2,3,5), -1, PARTPROD(0,4,5), + PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5), -1, + -1, -1, -1, PARTPROD(0,0,6), + PARTPROD(0,1,6), PARTPROD(0,2,6), PARTPROD(1,2,6), PARTPROD(0,3,6), + PARTPROD(1,3,6), PARTPROD(2,3,6), -1, PARTPROD(0,4,6), + PARTPROD(1,4,6), PARTPROD(2,4,6), -1, PARTPROD(3,4,6), + -1, -1, -1, PARTPROD(0,5,6), + PARTPROD(1,5,6), PARTPROD(2,5,6), -1, PARTPROD(3,5,6), + -1, -1, -1, PARTPROD(4,5,6), + -1, -1, -1, -1, + -1, -1, -1, PARTPROD(0,0,7), + -1, PARTPROD(0,2,7), PARTPROD(1,2,7), PARTPROD(0,3,7), + PARTPROD(1,3,7), PARTPROD(2,3,7), -1, PARTPROD(0,4,7), + PARTPROD(1,4,7), PARTPROD(2,4,7), -1, PARTPROD(3,4,7), + -1, -1, -1, PARTPROD(0,5,7), + PARTPROD(1,5,7), PARTPROD(2,5,7), -1, PARTPROD(3,5,7), + -1, -1, -1, PARTPROD(4,5,7), + -1, -1, -1, -1, + -1, -1, -1, PARTPROD(0,6,7), + PARTPROD(1,6,7), PARTPROD(2,6,7), -1, PARTPROD(3,6,7), + -1, -1, -1, PARTPROD(4,6,7), + -1, -1, -1, -1, + -1, -1, -1, PARTPROD(5,6,7), + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, PARTPROD(0,7,7), + 0}; + +int partprodPermedia[] = { + -1, + PARTPROD(0,0,1), PARTPROD(0,1,1), PARTPROD(1,1,1), PARTPROD(1,1,2), + PARTPROD(1,2,2), PARTPROD(2,2,2), PARTPROD(1,2,3), PARTPROD(2,2,3), + PARTPROD(1,3,3), PARTPROD(2,3,3), PARTPROD(1,2,4), PARTPROD(3,3,3), + PARTPROD(1,3,4), PARTPROD(2,3,4), -1, PARTPROD(3,3,4), + PARTPROD(1,4,4), PARTPROD(2,4,4), -1, PARTPROD(3,4,4), + -1, PARTPROD(2,3,5), -1, PARTPROD(4,4,4), + PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5), -1, + -1, -1, -1, PARTPROD(4,4,5), + PARTPROD(1,5,5), PARTPROD(2,5,5), -1, PARTPROD(3,5,5), + -1, -1, -1, PARTPROD(4,5,5), + -1, -1, -1, PARTPROD(3,4,6), + -1, -1, -1, PARTPROD(5,5,5), + PARTPROD(1,5,6), PARTPROD(2,5,6), -1, PARTPROD(3,5,6), + -1, -1, -1, PARTPROD(4,5,6), + -1, -1, -1, -1, + -1, -1, -1, PARTPROD(5,5,6), + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + 0}; + +static void +GLINTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, + int flags) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int videocontrol = 0, vtgpolarity = 0; + + if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_300SX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_500TX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_MX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_MX)) ) { + vtgpolarity = GLINT_READ_REG(VTGPolarity) & 0xFFFFFFF0; + } else { + videocontrol = GLINT_READ_REG(PMVideoControl) & 0xFFFFFFD6; + } + + switch (PowerManagementMode) { + case DPMSModeOn: + /* Screen: On, HSync: On, VSync: On */ + videocontrol |= 0x29; + vtgpolarity |= 0x05; + break; + case DPMSModeStandby: + /* Screen: Off, HSync: Off, VSync: On */ + videocontrol |= 0x20; + vtgpolarity |= 0x04; + break; + case DPMSModeSuspend: + /* Screen: Off, HSync: On, VSync: Off */ + videocontrol |= 0x08; + vtgpolarity |= 0x01; + break; + case DPMSModeOff: + /* Screen: Off, HSync: Off, VSync: Off */ + videocontrol |= 0x00; + vtgpolarity |= 0x00; + break; + default: + return; + } + + if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_300SX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_500TX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_MX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_MX)) ) { + GLINT_SLOW_WRITE_REG(vtgpolarity, VTGPolarity); + } else { + GLINT_SLOW_WRITE_REG(videocontrol, PMVideoControl); + } +} + +static Bool +GLINTGetRec(ScrnInfoPtr pScrn) +{ + TRACE_ENTER("GLINTGetRec"); + /* + * Allocate an GLINTRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(GLINTRec), 1); + /* Initialise it */ + + TRACE_EXIT("GLINTGetRec"); + return TRUE; +} + +static void +GLINTFreeRec(ScrnInfoPtr pScrn) +{ + TRACE_ENTER("GLINTFreeRec"); + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + TRACE_EXIT("GLINTFreeRec"); +} + + +/* Mandatory */ +static void +GLINTIdentify(int flags) +{ + xf86PrintChipsets(GLINT_NAME, "driver for 3Dlabs chipsets", GLINTChipsets); +} + +static const OptionInfoRec * +GLINTAvailableOptions(int chipid, int busid) +{ + return GLINTOptions; +} + +static void +GLINTProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) + { + pVbe = VBEInit(NULL,index); + vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +/* Mandatory */ +static Bool +GLINTProbe(DriverPtr drv, int flags) +{ + int i; + pciVideoPtr pPci, *checkusedPci; + GDevPtr *devSections; + int numDevSections; + int numUsed,bus,device,func; + char *dev; + int *usedChips = NULL; + Bool foundScreen = FALSE; + char *name; + + /* + TRACE_ENTER("GLINTProbe"); + */ + TRACE_EXIT("GLINTProbe (Enter)"); + + + if ((numDevSections = xf86MatchDevice(GLINT_DRIVER_NAME, + &devSections)) <= 0) { + return FALSE; + } + + checkusedPci = xf86GetPciVideoInfo(); + + if (checkusedPci == NULL && devSections /* for xf86DoProbe */) { + /* + * Changed the behaviour to try probing using the FBDev support + * when no PCI cards have been found. This is for systems without + * (proper) PCI support. (Michel) + */ + if (!xf86LoadDrvSubModule(drv, "fbdevhw")) + return FALSE; + + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + + for (i = 0; i < numDevSections; i++) { + dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); + if (devSections[i]->busID) { + xf86ParsePciBusString(devSections[i]->busID,&bus,&device,&func); + if (!xf86CheckPciSlot(bus,device,func)) + continue; + } + if (fbdevHWProbe(NULL,dev,&name)) { + ScrnInfoPtr pScrn; + + /* Check for pm2fb */ + if (strcmp(name,"Permedia2")) continue; + foundScreen = TRUE; + pScrn = NULL; + + if (devSections[i]->busID) { + /* XXX what about when there's no busID set? */ + int entity; + entity = xf86ClaimPciSlot(bus,device,func,drv, + 0,devSections[i], + TRUE); + pScrn = xf86ConfigPciEntity(pScrn,0,entity, + NULL,RES_SHARED_VGA, + NULL,NULL,NULL,NULL); + if (pScrn) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "claimed PCI slot %d:%d:%d\n",bus,device,func); + } else { + /* XXX This is a quick hack */ + int entity; + + entity = xf86ClaimIsaSlot(drv, 0, + devSections[i], TRUE); + pScrn = xf86ConfigIsaEntity(pScrn,0,entity, + NULL,RES_SHARED_VGA, + NULL,NULL,NULL,NULL); + } + if (pScrn) { + /* Fill in what we can of the ScrnInfoRec */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s successfully probed\n", dev ? dev : "default framebuffer device"); + pScrn->driverVersion = VERSION; + pScrn->driverName = GLINT_DRIVER_NAME; + pScrn->name = GLINT_NAME; + pScrn->Probe = GLINTProbe; + pScrn->PreInit = GLINTPreInit; + pScrn->ScreenInit = GLINTScreenInit; + pScrn->SwitchMode = GLINTSwitchMode; + pScrn->FreeScreen = GLINTFreeScreen; + pScrn->EnterVT = GLINTEnterVT; + } + } + } + + xfree(devSections); + + } else if (checkusedPci) { + + if (flags & PROBE_DETECT) { + /* HACK, Currently when -configuring, we only return VGA + * based chips. Manual configuring is necessary to poke + * at the other chips */ + numUsed = xf86MatchPciInstances(GLINT_NAME, 0, + GLINTVGAChipsets, GLINTVGAPciChipsets, + devSections, + numDevSections, drv, &usedChips); + } else { + numUsed = xf86MatchPciInstances(GLINT_NAME, 0, + GLINTChipsets, GLINTPciChipsets, devSections, + numDevSections, drv, &usedChips); + } + + xfree(devSections); + if (numUsed <= 0) + return FALSE; + foundScreen = TRUE; + + if (!(flags & PROBE_DETECT)) + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + GLINTEntPtr pGlintEnt = NULL; + DevUnion *pPriv; + + pPci = xf86GetPciInfoForEntity(usedChips[i]); + /* Allocate a ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + GLINTPciChipsets, NULL, + NULL, NULL, NULL, NULL))) { + + + /* Claim specifics, when we KNOW ! the board */ + + /* Appian Jeronimo J2000 */ + if ((pPci->subsysVendor == 0x1097) && + (pPci->subsysCard == 0x3d32)) { + int eIndex; + if (!xf86IsEntityShared(usedChips[i])) { + eIndex = xf86ClaimPciSlot(pPci->bus, + pPci->device, + 1, + drv, -1 /* XXX */, + NULL, FALSE); + xf86AddEntityToScreen(pScrn,eIndex); + } else { + eIndex = xf86ClaimPciSlot(pPci->bus, + pPci->device, + 2, + drv, -1 /* XXX */, + NULL, FALSE); + xf86AddEntityToScreen(pScrn,eIndex); + } + } else + /* Only claim other chips when GAMMA is used */ + if ((pPci->chipType == PCI_CHIP_GAMMA) || + (pPci->chipType == PCI_CHIP_GAMMA2) || + (pPci->chipType == PCI_CHIP_DELTA)) { + while (*checkusedPci != NULL) { + int eIndex; + /* make sure we claim all but our source device */ + if ((pPci->bus == (*checkusedPci)->bus && + pPci->device == (*checkusedPci)->device) && + pPci->func != (*checkusedPci)->func) { + + /* Claim other entities on the same card */ + eIndex = xf86ClaimPciSlot((*checkusedPci)->bus, + (*checkusedPci)->device, + (*checkusedPci)->func, + drv, -1 /* XXX */, + NULL, FALSE); + + if (eIndex != -1) { + xf86AddEntityToScreen(pScrn,eIndex); + } else { + ErrorF("BusID %d:%d:%d already claimed\n", + (*checkusedPci)->bus, + (*checkusedPci)->device, + (*checkusedPci)->func); + xfree(usedChips); + return FALSE; + } + } + checkusedPci++; + } + } + + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = VERSION; + pScrn->driverName = GLINT_DRIVER_NAME; + pScrn->name = GLINT_NAME; + pScrn->Probe = GLINTProbe; + pScrn->PreInit = GLINTPreInit; + pScrn->ScreenInit = GLINTScreenInit; + pScrn->SwitchMode = GLINTSwitchMode; + pScrn->FreeScreen = GLINTFreeScreen; + pScrn->EnterVT = GLINTEnterVT; + } + + /* Allow sharing if Appian J2000 detected */ + /* (later Diamond FireGL3000 support too) */ + + if ((pPci->subsysVendor == 0x1097) && + (pPci->subsysCard == 0x3d32)) { + xf86SetEntitySharable(usedChips[i]); + /* Allocate an entity private if necessary */ + if (GLINTEntityIndex < 0) + GLINTEntityIndex = xf86AllocateEntityPrivateIndex(); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + GLINTEntityIndex); + if (!pPriv->ptr) { + pPriv->ptr = xnfcalloc(sizeof(GLINTEntRec), 1); + pGlintEnt = pPriv->ptr; + pGlintEnt->lastInstance = -1; + } else { + pGlintEnt = pPriv->ptr; + } + + /* + * Set the entity instance for this instance of the driver. + * For dual head per card, instance 0 is the "master" + * instance, driving the primary head, and instance 1 is + * the "slave". + */ + pGlintEnt->lastInstance++; + xf86SetEntityInstanceForScreen(pScrn, + pScrn->entityList[0], pGlintEnt->lastInstance); + } + } + } + + xfree(usedChips); + + TRACE_EXIT("GLINTProbe"); + return foundScreen; +} + +/* + * GetAccelPitchValues - + * + * This function returns a list of display width (pitch) values that can + * be used in accelerated mode. + */ +static int * +GetAccelPitchValues(ScrnInfoPtr pScrn) +{ + int *linePitches = NULL; + int i, n = 0; + int *linep = NULL; + GLINTPtr pGlint = GLINTPTR(pScrn); + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + linep = &partprodPermedia[0]; + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + linep = &partprod500TX[0]; + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + /* When GAMMA/DELTA in use, we always have MultiChip defined, even if + * only one chip is connected to GAMMA/DELTA as the entities > 1 + */ + switch (pGlint->MultiChip) { + case PCI_CHIP_MX: + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + linep = &partprod500TX[0]; + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + linep = &partprodPermedia[0]; + break; + } + break; + } + + for (i = 0; linep[i] != 0; i++) { + if (linep[i] != -1) { + n++; + linePitches = xnfrealloc(linePitches, n * sizeof(int)); + linePitches[n - 1] = i << 5; + } + } + + /* Mark the end of the list */ + if (n > 0) { + linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); + linePitches[n] = 0; + } + + return linePitches; +} + +static void +GLINTProbeTIramdac(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + CARD32 temp = 0; + pGlint = GLINTPTR(pScrn); + + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = glintInTIIndReg; + pGlint->RamDacRec->WriteDAC = glintOutTIIndReg; + pGlint->RamDacRec->ReadAddress = glintTIReadAddress; + pGlint->RamDacRec->WriteAddress = glintTIWriteAddress; + pGlint->RamDacRec->ReadData = glintTIReadData; + pGlint->RamDacRec->WriteData = glintTIWriteData; + pGlint->RamDacRec->LoadPalette = TIramdacLoadPalette; + + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return; + } + GLINTMapMem(pScrn); + if (pGlint->numMultiDevices == 2) { + temp = GLINT_READ_REG(GCSRAperture); + GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture); + } + pGlint->RamDac = TIramdacProbe(pScrn, TIRamdacs); + if (pGlint->numMultiDevices == 2) { + GLINT_SLOW_WRITE_REG(temp, GCSRAperture); + } + GLINTUnmapMem(pScrn); +} + +static void +GLINTProbeIBMramdac(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + pGlint = GLINTPTR(pScrn); + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = glintInIBMRGBIndReg; + pGlint->RamDacRec->WriteDAC = glintOutIBMRGBIndReg; + pGlint->RamDacRec->ReadAddress = glintIBMReadAddress; + pGlint->RamDacRec->WriteAddress = glintIBMWriteAddress; + pGlint->RamDacRec->ReadData = glintIBMReadData; + pGlint->RamDacRec->WriteData = glintIBMWriteData; + pGlint->RamDacRec->LoadPalette = NULL; + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return; + } + GLINTMapMem(pScrn); + pGlint->RamDac = IBMramdacProbe(pScrn, IBMRamdacs); + GLINTUnmapMem(pScrn); +} + +/* Mandatory */ +static Bool +GLINTPreInit(ScrnInfoPtr pScrn, int flags) +{ + GLINTPtr pGlint; + GLINTEntPtr pGlintEnt = NULL; + MessageType from; + int i; + Bool Overlay = FALSE; + int maxwidth = 0, maxheight = 0; + ClockRangePtr clockRanges; + char *mod = NULL; + const char *s; + const char **syms = NULL; + + TRACE_ENTER("GLINTPreInit"); + + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ + + /* Check the number of entities, and fail if it isn't one or more. */ + if (pScrn->numEntities < 1) + return FALSE; + + /* Allocate the GLINTRec driverPrivate */ + if (!GLINTGetRec(pScrn)) { + return FALSE; + } + pGlint = GLINTPTR(pScrn); + + /* Get the entities, and make sure they are PCI. */ + pGlint->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + /* Allocate an entity private if necessary */ + if (xf86IsEntityShared(pScrn->entityList[0])) { + pGlintEnt = xf86GetEntityPrivate(pScrn->entityList[0], + GLINTEntityIndex)->ptr; + pGlint->entityPrivate = pGlintEnt; + } + + if (pGlint->pEnt->location.type == BUS_PCI) + { + pGlint->PciInfo = xf86GetPciInfoForEntity(pGlint->pEnt->index); + pGlint->PciTag = pciTag(pGlint->PciInfo->bus, pGlint->PciInfo->device, + pGlint->PciInfo->func); + } + + pGlint->InFifoSpace = 0; /* Force a Read of FIFO space on first run */ + pGlint->numMultiDevices = 0; + pGlint->IOOffset = 0; /* Set IO Offset for Gamma */ + + if (pScrn->numEntities > 1) { + pciVideoPtr pPci; + EntityInfoPtr pEnt; + + for (i = 1; i < pScrn->numEntities; i++) { + pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + pPci = xf86GetPciInfoForEntity(pEnt->index); + if ( (pPci->chipType == PCI_CHIP_MX) || + (pPci->chipType == PCI_CHIP_PERMEDIA) || + (pPci->chipType == PCI_CHIP_TI_PERMEDIA) || + (pPci->chipType == PCI_CHIP_500TX) || + (pPci->chipType == PCI_CHIP_300SX) || + (pPci->chipType == PCI_CHIP_R4) || + (pPci->chipType == PCI_CHIP_PERMEDIA3) ) { + pGlint->MultiChip = pPci->chipType; + if (pGlint->numMultiDevices >= GLINT_MAX_MULTI_DEVICES) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%d multiple chips unsupported, aborting. (Max - 2)\n", + pGlint->numMultiDevices); + return FALSE; + } else { + pGlint->MultiPciInfo[pGlint->numMultiDevices] = pPci; + pGlint->numMultiDevices++; + } + } + } + } + + { + EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + pciVideoPtr pPci = xf86GetPciInfoForEntity(pEnt->index); + + if ( ((pPci->chipType == PCI_CHIP_GAMMA) || + (pPci->chipType == PCI_CHIP_GAMMA2) || + (pPci->chipType == PCI_CHIP_DELTA)) && + (pGlint->numMultiDevices == 0) ) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Gamma/Delta with ZERO connected chips, aborting\n"); + return FALSE; + } + } + + if (flags & PROBE_DETECT) { + EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + pciVideoPtr pPci = xf86GetPciInfoForEntity(pEnt->index); + + if ((pPci->chipType != PCI_CHIP_GAMMA) && + (pPci->chipType != PCI_CHIP_GAMMA2) && + (pPci->chipType != PCI_CHIP_DELTA)) { + GLINTProbeDDC(pScrn, pGlint->pEnt->index); + return TRUE; + } else + return FALSE; + } + + xf86SetOperatingState(resVga, pGlint->pEnt->index, ResDisableOpr); + + /* Operations for which memory access is required. */ + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + /* + * The first thing we should figure out is the depth, bpp, etc. + * Our default depth is 8, so pass it to the helper function. + * We support both 24bpp and 32bpp layouts, so indicate that. + */ + if (FBDevProbed) { + int default_depth, fbbpp; + + if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(pGlint->pEnt->device->options,"fbdev"))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "fbdevHWInit failed!\n"); + return FALSE; + } + default_depth = fbdevHWGetDepth(pScrn,&fbbpp); + if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, fbbpp,0)) + return FALSE; + } else { + if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb | Support32bppFb + /*| SupportConvert32to24 | PreferConvert32to24*/)) + return FALSE; + } + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + case 30: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + + xf86PrintDepthBpp(pScrn); + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() + * here. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if (!(pGlint->Options = xalloc(sizeof(GLINTOptions)))) + return FALSE; + memcpy(pGlint->Options, GLINTOptions, sizeof(GLINTOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pGlint->Options); + + /* Default to 8bits per RGB */ + if (pScrn->depth == 30) pScrn->rgbBits = 10; + else pScrn->rgbBits = 8; + if (xf86GetOptValInteger(pGlint->Options, OPTION_RGB_BITS, &pScrn->rgbBits)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", + pScrn->rgbBits); + } + + from = X_DEFAULT; + pGlint->HWCursor = TRUE; /* ON by default */ + if (xf86ReturnOptValBool(pGlint->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pGlint->HWCursor = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pGlint->HWCursor ? "HW" : "SW"); + if (xf86ReturnOptValBool(pGlint->Options, OPTION_FLATPANEL, FALSE)) { + pGlint->UseFlatPanel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Flat Panel Interface\n"); + } + if (xf86ReturnOptValBool(pGlint->Options, OPTION_NOACCEL, FALSE)) { + pGlint->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + if (xf86ReturnOptValBool(pGlint->Options, OPTION_SHADOW_FB, FALSE)) { + pGlint->ShadowFB = TRUE; + pGlint->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + } + if(xf86GetOptValInteger(pGlint->Options, OPTION_VIDEO_KEY, + &(pGlint->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + pGlint->videoKey); + } else { + /* Needs 8bit values for all modes */ + pGlint->videoKey = (1 << 16) | + (1 << 8) | + ((pScrn->mask.blue - 1) << 0); + } + + /* Check whether to use the FBDev stuff and fill in the rest of pScrn */ + if (xf86ReturnOptValBool(pGlint->Options, OPTION_FBDEV, FALSE)) { + if (!FBDevProbed && !xf86LoadSubModule(pScrn, "fbdevhw")) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "couldn't load fbdevHW module!\n"); + return FALSE; + } + + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + + if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(pGlint->pEnt->device->options,"fbdev"))) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "fbdevHWInit failed!\n"); + return FALSE; + } + + pGlint->FBDev = TRUE; + from = X_CONFIG; + + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->LeaveVT = fbdevHWLeaveVT; + pScrn->ValidMode = fbdevHWValidMode; + + } else { + /* Only use FBDev if requested */ + pGlint->FBDev = FALSE; + from = X_PROBED; + + pScrn->AdjustFrame = GLINTAdjustFrame; + pScrn->LeaveVT = GLINTLeaveVT; + pScrn->ValidMode = GLINTValidMode; + + } + xf86DrvMsg(pScrn->scrnIndex, from, "%s Linux framebuffer device\n", + pGlint->FBDev ? "Using" : "Not using"); + + pScrn->overlayFlags = 0; + from = X_DEFAULT; + if ((s = xf86GetOptValString(pGlint->Options, OPTION_OVERLAY))) { + if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) { + Overlay = TRUE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "\"%s\" is not a valid value for Option \"Overlay\"\n", s); + } + } + if (Overlay) { + if ((pScrn->depth == 24) && (pScrn->bitsPerPixel == 32)) { + pScrn->colorKey = 255; /* we should let the user change this */ + pScrn->overlayFlags = OVERLAY_8_32_PLANAR; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "24/8 overlay enabled\n"); + } + } + + pGlint->DoubleBuffer = FALSE; + pGlint->RamDac = NULL; + pGlint->STATE = FALSE; + /* + * Set the Chipset and ChipRev, allowing config file entries to + * override. + */ + if (FBDevProbed) { /* pm2fb so far only supports the Permedia2 */ + pScrn->chipset = "ti_pm2"; + pGlint->Chipset = xf86StringToToken(GLINTChipsets, pScrn->chipset); + from = X_PROBED; + } else { + if (pGlint->pEnt->device->chipset && *pGlint->pEnt->device->chipset) { + pScrn->chipset = pGlint->pEnt->device->chipset; + pGlint->Chipset = xf86StringToToken(GLINTChipsets, pScrn->chipset); + from = X_CONFIG; + } else if (pGlint->pEnt->device->chipID >= 0) { + pGlint->Chipset = pGlint->pEnt->device->chipID; + pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets, + pGlint->Chipset); + + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pGlint->Chipset); + } else { + from = X_PROBED; + pGlint->Chipset = pGlint->PciInfo->vendor << 16 | + pGlint->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets, + pGlint->Chipset); + } + if (pGlint->pEnt->device->chipRev >= 0) { + pGlint->ChipRev = pGlint->pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pGlint->ChipRev); + } else { + pGlint->ChipRev = pGlint->PciInfo->chipRev; + } + } + + /* + * This shouldn't happen because such problems should be caught in + * GLINTProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pGlint->Chipset); + return FALSE; + } + if (pGlint->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + + if ((pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2)) { + if (xf86ReturnOptValBool(pGlint->Options, OPTION_BLOCK_WRITE, FALSE)) { + pGlint->UseBlockWrite = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Block Writes enabled\n"); + } + } + + if (xf86ReturnOptValBool(pGlint->Options, OPTION_FIREGL3000, FALSE)) { + /* Can't we detect a Fire GL 3000 ????? and remove this ? */ + pGlint->UseFireGL3000 = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Diamond FireGL3000 mode enabled\n"); + } + + if (!FBDevProbed) { + if (pGlint->pEnt->device->MemBase != 0) { + /* + * XXX Should check that the config file value matches one of the + * PCI base address values. + */ + pGlint->FbAddress = pGlint->pEnt->device->MemBase; + from = X_CONFIG; + } else { + pGlint->FbAddress = pGlint->PciInfo->memBase[2] & 0xFF800000; + } + + if (pGlint->FbAddress) + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pGlint->FbAddress); + + /* Trap GAMMA & DELTA specification, with no linear address */ + /* Find the first GLINT chip and use that address */ + if (pGlint->FbAddress == 0) { + if (pGlint->MultiPciInfo[0]->memBase[2]) { + pGlint->FbAddress = pGlint->MultiPciInfo[0]->memBase[2]; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "FrameBuffer used from first rasterizer chip at 0x%x\n", + pGlint->MultiPciInfo[0]->memBase[2]); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "No FrameBuffer memory - aborting\n"); + return FALSE; + } + } + + if (pGlint->pEnt->device->IOBase != 0) { + /* + * XXX Should check that the config file value matches one of the + * PCI base address values. + */ + pGlint->IOAddress = pGlint->pEnt->device->IOBase; + from = X_CONFIG; + } else { + pGlint->IOAddress = pGlint->PciInfo->memBase[0] & 0xFFFFC000; + } + + if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { + /* We know which head is the primary on the J2000 board, need a more + * generix solution though. + */ + if ((xf86IsEntityShared(pScrn->entityList[0])) && + (xf86IsPrimInitDone(pScrn->entityList[0]))) { + pGlint->IOAddress += 0x10000; + pGlint->MultiIndex = 2; + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + pGlint->MultiIndex = 1; + } +#if X_BYTE_ORDER == X_BIG_ENDIAN + GLINT_SLOW_WRITE_REG( + GLINT_READ_REG(GCSRAperture) | GCSRBitSwap + , GCSRAperture); + } else { + pGlint->IOAddress += 0x10000; +#endif + } + + xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", + (unsigned long)pGlint->IOAddress); + + pGlint->irq = pGlint->pEnt->device->irq; + + /* Register all entities */ + for (i = 0; i < pScrn->numEntities; i++) { + EntityInfoPtr pEnt; + pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + if (xf86RegisterResources(pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n"); + return FALSE; + } + } + } + + /* Initialize the card through int10 interface if needed */ + if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA && + pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA2 && + pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_DELTA && + !xf86IsPrimaryPci(pGlint->PciInfo) && !pGlint->FBDev) { + if ( xf86LoadSubModule(pScrn, "int10")){ + xf86Int10InfoPtr pInt; + + xf86LoaderReqSymLists(GLINTint10Symbols, NULL); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); + pInt = xf86InitInt10(pGlint->pEnt->index); + xf86FreeInt10(pInt); + } + } + + pGlint->FbMapSize = 0; + + { + /* We have to boot some multiple head type boards here */ + GLINTMapMem(pScrn); + switch (pGlint->Chipset) { + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + Permedia3PreInit(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VPreInit(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + Permedia2PreInit(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + switch (pGlint->MultiChip) { + case PCI_CHIP_PERMEDIA3: + Permedia3PreInit(pScrn); + break; + } + break; + case PCI_VENDOR_3DLABS_CHIP_DELTA: + /* Delta has a bug, we need to fix it here */ + { + int basecopro = + pGlint->MultiPciInfo[0]->memBase[0] & 0xFFFFC000; + int basedelta = pGlint->PciInfo->memBase[0] & 0xFFFFC000; + int glintdelta = pGlint->PciTag; + int glintcopro = pciTag(pGlint->MultiPciInfo[0]->bus, + pGlint->MultiPciInfo[0]->device, + pGlint->MultiPciInfo[0]->func); + int temp, base3copro, offset; + + if( (basedelta & 0x20000) ^ (basecopro & 0x20000) ) { + if ((pGlint->MultiChip == PCI_CHIP_PERMEDIA) || + (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA)) { + offset = 0x20; /* base4 */ + } else { + offset = 0x1c; /* base3 */ + } + base3copro = pciReadLong(glintcopro, offset); + if( (basecopro & 0x20000) ^ (base3copro & 0x20000) ) { + /* + * oops, still different; we know that base3 + * is at least 16 MB, so we just take 128k + * offset into it. + */ + base3copro += 0x20000; + } + /* + * and now for the magic. + * read old value + * write fffffffff + * read value + * write new value + */ + temp = pciReadLong(glintdelta, 0x10); + pciWriteLong(glintdelta, 0x10, 0xffffffff); + temp = pciReadLong(glintdelta, 0x10); + pciWriteLong(glintdelta, 0x10, base3copro); + + /* + * additionally,sometimes we see the baserom which might + * confuse the chip, so let's make sure that is disabled + */ + temp = pciReadLong(glintcopro, 0x30); + pciWriteLong(glintcopro, 0x30, 0xffffffff); + temp = pciReadLong(glintcopro, 0x30); + pciWriteLong(glintcopro, 0x30, 0); + + /* + * now update our internal structure accordingly + */ + pGlint->IOAddress = + pGlint->PciInfo->memBase[0] = base3copro; + xf86DrvMsg(pScrn->scrnIndex, from, + "Delta Bug - Changing MMIO registers to 0x%lX\n", + (unsigned long)pGlint->IOAddress); + } + } + break; + default: + break; + } + GLINTUnmapMem(pScrn); + } + + /* HW bpp matches reported bpp */ + pGlint->HwBpp = pScrn->bitsPerPixel; + + pGlint->FbBase = NULL; + if (!FBDevProbed) { + if (pGlint->pEnt->device->videoRam != 0) { + pScrn->videoRam = pGlint->pEnt->device->videoRam; + from = X_CONFIG; + } else { + /* Need to access MMIO to determine videoRam */ + GLINTMapMem(pScrn); + switch (pGlint->Chipset) { + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) & + 0xE0000000)>>29)) * 1024; + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig) >> 29) & + 0x03) + 1) * 2048; + break; + case PCI_VENDOR_3DLABS_CHIP_R4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + pScrn->videoRam = Permedia3MemorySizeDetect(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_DELTA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + switch (pGlint->MultiChip) { + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is GLINT Permedia\n"); + pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig)>>29) & + 0x03) + 1) * 2048; + break; + case PCI_CHIP_300SX: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is GLINT 300SX\n"); + pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) & + 0xE0000000)>>29)) * 1024; + break; + case PCI_CHIP_500TX: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is GLINT 500TX\n"); + pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) & + 0xE0000000)>>29)) * 1024; + break; + case PCI_CHIP_MX: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is GLINT MX\n"); + pScrn->videoRam = + (1 << ((GLINT_READ_REG(FBMemoryCtl) & + 0xE0000000)>>29)) * 1024; + break; + case PCI_CHIP_PERMEDIA3: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is Permedia3\n"); + pScrn->videoRam = Permedia3MemorySizeDetect(pScrn); + break; + case PCI_CHIP_R4: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Attached Rasterizer is R4\n"); + pScrn->videoRam = Permedia3MemorySizeDetect(pScrn); + break; + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Number of Rasterizers attached is %d\n", + pGlint->numMultiDevices); + break; + } + GLINTUnmapMem(pScrn); + } + } else { + pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024; + } + + pGlint->FbMapSize = pScrn->videoRam * 1024; + + /* OVERRIDE videoRam/FbMapSize, for Multiply connected chips to GAMMA */ + pGlint->MultiAperture = FALSE; + if ( ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2)) && + (pGlint->numMultiDevices == 2) ) { + CARD32 chipconfig; + CARD32 size = 0; + CARD32 temp; + + GLINTMapMem(pScrn); + + temp = GLINT_READ_REG(GCSRAperture); + GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture); + + chipconfig = GLINT_READ_REG(GChipConfig); + + GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture); + + GLINTUnmapMem(pScrn); + + switch (chipconfig & GChipMultiGLINTApMask) { + case GChipMultiGLINTAp_0M: + size = 0; + break; + case GChipMultiGLINTAp_16M: + size = 16 * 1024 * 1024; + break; + case GChipMultiGLINTAp_32M: + size = 32 * 1024 * 1024; + break; + case GChipMultiGLINTAp_64M: + size = 64 * 1024 * 1024; + break; + } + + if (size == 0) { + xf86DrvMsg(pScrn->scrnIndex, from, "MultiAperture: disabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, from, "MultiAperture: enabled\n"); + pGlint->FbMapSize = size; + pGlint->MultiAperture = TRUE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", + pGlint->FbMapSize / 1024); + + /* The ramdac module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "ramdac")) + return FALSE; + + xf86LoaderReqSymLists(ramdacSymbols, NULL); + + /* Let's check what type of DAC we have and reject if necessary */ + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + pGlint->FIFOSize = 256; + maxheight = 2048; + maxwidth = 2048; + pGlint->RefClock = 14318; + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = Permedia2InIndReg; + pGlint->RamDacRec->WriteDAC = Permedia2OutIndReg; + pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress; + pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress; + pGlint->RamDacRec->ReadData = Permedia2ReadData; + pGlint->RamDacRec->WriteData = Permedia2WriteData; + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return FALSE; + } + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + pGlint->FIFOSize = 256; + maxheight = 2048; + maxwidth = 2048; + pGlint->RefClock = 14318; + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg; + pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg; + pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress; + pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress; + pGlint->RamDacRec->ReadData = Permedia2ReadData; + pGlint->RamDacRec->WriteData = Permedia2WriteData; + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return FALSE; + } + break; + case PCI_VENDOR_3DLABS_CHIP_R4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + if (pScrn->bitsPerPixel == 24) { + xf86DrvMsg(pScrn->scrnIndex, from, + "-depth 24 -pixmap24 not supported by this chip.\n"); + return FALSE; + } + pGlint->FIFOSize = 120; + maxheight = 4096; + maxwidth = 4096; + pGlint->RefClock = 14318; + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg; + pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg; + pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress; + pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress; + pGlint->RamDacRec->ReadData = Permedia2ReadData; + pGlint->RamDacRec->WriteData = Permedia2WriteData; + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return FALSE; + } + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + pGlint->FIFOSize = 31; + maxheight = 1024; + maxwidth = 1536; + /* Test for an TI ramdac */ + if (!pGlint->RamDac) { + GLINTProbeTIramdac(pScrn); + if (pGlint->RamDac) + if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) + pGlint->RefClock = 14318; + } + /* Test for an IBM ramdac */ + if (!pGlint->RamDac) { + GLINTProbeIBMramdac(pScrn); + if (pGlint->RamDac) { + if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) + pGlint->RefClock = 14318; + } + } + if (!pGlint->RamDac) + return FALSE; + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + pGlint->FIFOSize = 15; + if (pScrn->bitsPerPixel == 24) { + xf86DrvMsg(pScrn->scrnIndex, from, + "-depth 24 -pixmap24 not supported by this chip.\n"); + return FALSE; + } + maxheight = 4096; + maxwidth = 4096; + /* Test for an TI ramdac */ + if (!pGlint->RamDac) { + GLINTProbeTIramdac(pScrn); + if (pGlint->RamDac) + if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ) + pGlint->RefClock = 14318; + } + /* Test for an IBM ramdac */ + if (!pGlint->RamDac) { + GLINTProbeIBMramdac(pScrn); + if (pGlint->RamDac) { + if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) + pGlint->RefClock = 28322; + else + if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) + pGlint->RefClock = 40000; + } + } + if (!pGlint->RamDac) + return FALSE; + break; + case PCI_VENDOR_3DLABS_CHIP_DELTA: + pGlint->FIFOSize = 15; + switch (pGlint->MultiChip) { + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + maxheight = 1024; + maxwidth = 1536; + /* Test for an TI ramdac */ + if (!pGlint->RamDac) { + GLINTProbeTIramdac(pScrn); + if (pGlint->RamDac) + if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) + pGlint->RefClock = 14318; + } + /* Test for an IBM ramdac */ + if (!pGlint->RamDac) { + GLINTProbeIBMramdac(pScrn); + if (pGlint->RamDac) { + if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) + pGlint->RefClock = 14318; + } + } + if (!pGlint->RamDac) + return FALSE; + break; + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + case PCI_CHIP_MX: + if (pScrn->bitsPerPixel == 24) { + xf86DrvMsg(pScrn->scrnIndex, from, + "-depth 24 -pixmap24 not supported by this chip.\n"); + return FALSE; + } + maxheight = 4096; + maxwidth = 4096; + /* Test for an TI ramdac */ + if (!pGlint->RamDac) { + GLINTProbeTIramdac(pScrn); + if (pGlint->RamDac) + if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ) + pGlint->RefClock = 14318; + } + /* Test for an IBM ramdac */ + if (!pGlint->RamDac) { + GLINTProbeIBMramdac(pScrn); + if (pGlint->RamDac) { + if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) + pGlint->RefClock = 40000; + } + } + break; + } + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + pGlint->FIFOSize = 32; + if (pScrn->bitsPerPixel == 24) { + xf86DrvMsg(pScrn->scrnIndex, from, + "-depth 24 -pixmap24 not supported by this chip.\n"); + return FALSE; + } + maxheight = 4096; + maxwidth = 4096; + /* Let's do board specific stuff first */ + if (IS_J2000) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Appian Jeronimo 2000 board detected\n"); + pGlint->RefClock = 14318; + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg; + pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg; + pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress; + pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress; + pGlint->RamDacRec->ReadData = Permedia2ReadData; + pGlint->RamDacRec->WriteData = Permedia2WriteData; + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return FALSE; + } + break; + } + if (IS_GMX2000) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "3DLabs GMX2000 board detected\n"); + /* We need to wrap these after detection as the second MX + * is the only chip that can write to the TI3030 dac */ + ACCESSCHIP2(); + GLINTProbeTIramdac(pScrn); + ACCESSCHIP1(); + pGlint->RamDacRec->ReadDAC = GMX2000InIndReg; + pGlint->RamDacRec->WriteDAC = GMX2000OutIndReg; + pGlint->RamDacRec->ReadAddress = GMX2000ReadAddress; + pGlint->RamDacRec->WriteAddress = GMX2000WriteAddress; + pGlint->RamDacRec->ReadData = GMX2000ReadData; + pGlint->RamDacRec->WriteData = GMX2000WriteData; + pGlint->RefClock = 14318; + break; + } + /* Test for an TI ramdac */ + if (!pGlint->RamDac) { + GLINTProbeTIramdac(pScrn); + if (pGlint->RamDac) + if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ) + pGlint->RefClock = 14318; + } + /* Test for an IBM ramdac */ + if (!pGlint->RamDac) { + GLINTProbeIBMramdac(pScrn); + if (pGlint->RamDac) { + if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) + pGlint->RefClock = 28322; + else + if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) || + pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) + pGlint->RefClock = 40000; + } + } + if (!pGlint->RamDac) { + if ((pGlint->MultiChip == PCI_CHIP_PERMEDIA3) || + (pGlint->MultiChip == PCI_CHIP_R4)) { + pGlint->RefClock = 14318; + pGlint->RamDacRec = RamDacCreateInfoRec(); + pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg; + pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg; + pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress; + pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress; + pGlint->RamDacRec->ReadData = Permedia2ReadData; + pGlint->RamDacRec->WriteData = Permedia2WriteData; + } + if(!RamDacInit(pScrn, pGlint->RamDacRec)) { + RamDacDestroyInfoRec(pGlint->RamDacRec); + return FALSE; + } + } else + if (!pGlint->RamDac) + return FALSE; + break; + } + + if ( pGlint->RamDac && + (pGlint->RamDac->RamDacType != (IBM640_RAMDAC)) && + (pScrn->depth == 30) ) + { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Depth 30 not supported for this chip\n"); + return FALSE; + } + + if (pGlint->FIFOSize) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "FIFO Size is %d DWORDS\n", + pGlint->FIFOSize); + + /* Set the min pixel clock */ + pGlint->MinClock = 16250; /* XXX Guess, need to check this */ + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", + pGlint->MinClock / 1000); + + /* + * If the user has specified ramdac speed in the XF86Config + * file, we respect that setting. + */ + if (pGlint->pEnt->device->dacSpeeds[0]) { + int speed = 0; + + switch (pScrn->bitsPerPixel) { + case 8: + speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP8]; + break; + case 16: + speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP16]; + break; + case 24: + speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP24]; + break; + case 32: + speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP32]; + break; + } + if (speed == 0) + pGlint->MaxClock = pGlint->pEnt->device->dacSpeeds[0]; + else + pGlint->MaxClock = speed; + from = X_CONFIG; + } else { + if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX)|| + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_300SX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_500TX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_MX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_MX)) ) + pGlint->MaxClock = 220000; + if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + ((pGlint->MultiChip == PCI_CHIP_PERMEDIA) || + (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA))) ) { + switch (pScrn->bitsPerPixel) { + case 8: + pGlint->MaxClock = 200000; + break; + case 16: + pGlint->MaxClock = 100000; + break; + case 24: + pGlint->MaxClock = 50000; + break; + case 32: + pGlint->MaxClock = 50000; + break; + } + } + if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ) { + switch (pScrn->bitsPerPixel) { + case 8: + pGlint->MaxClock = 230000; + break; + case 16: + pGlint->MaxClock = 230000; + break; + case 24: + pGlint->MaxClock = 150000; + break; + case 32: + pGlint->MaxClock = 110000; + break; + } + } + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) && + (pGlint->MultiChip == PCI_CHIP_R4)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) + pGlint->MaxClock = 300000; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", + pGlint->MaxClock / 1000); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = pGlint->MinClock; + clockRanges->maxClock = pGlint->MaxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = FALSE; /* XXX check this */ + clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our GLINTValidMode() already takes + * care of this, we don't worry about setting them here. + */ + + /* Select valid modes from those available */ + if ((pGlint->NoAccel) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) && + (pGlint->MultiChip == PCI_CHIP_R4)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) { + /* + * XXX Assuming min pitch 256, max <maxwidth> + * XXX Assuming min height 128, max <maxheight> + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, maxwidth, + pScrn->bitsPerPixel, 128, maxheight, + pScrn->display->virtualX, + pScrn->display->virtualY, + pGlint->FbMapSize, + LOOKUP_BEST_REFRESH); + } else { + /* + * Minimum width 32, Maximum width <maxwidth> + * Minimum height 128, Maximum height <maxheight> + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + GetAccelPitchValues(pScrn), 32, maxwidth, + pScrn->bitsPerPixel, 128, maxheight, + pScrn->display->virtualX, + pScrn->display->virtualY, + pGlint->FbMapSize, + LOOKUP_BEST_REFRESH); + } + + if (i < 1 && pGlint->FBDev) { + fbdevHWUseBuildinMode(pScrn); + i = 1; + } + + if (i == -1) { + GLINTFreeRec(pScrn); + return FALSE; + } + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + GLINTFreeRec(pScrn); + return FALSE; + } + + if (pGlint->FBDev) { + /* shift horizontal timings for 64bit VRAM's or 32bit SGRAMs */ + switch (pScrn->bitsPerPixel) { + case 8: + pGlint->BppShift = 2; + break; + case 16: + if (pGlint->DoubleBuffer) { + pGlint->BppShift = 0; + } else { + pGlint->BppShift = 1; + } + break; + case 24: + pGlint->BppShift = 2; + break; + case 32: + pGlint->BppShift = 0; + break; + } + + pScrn->displayWidth = pScrn->virtualX; + + /* Ensure vsync and hsync are high when using HW cursor */ + if (pGlint->HWCursor) { + DisplayModePtr mode, first = mode = pScrn->modes; + + do { /* We know there is at least the built-in mode */ + mode->Flags |= V_PHSYNC | V_PVSYNC; + mode->Flags &= ~V_NHSYNC | ~V_NVSYNC; + mode = mode->next; + } while (mode != NULL && mode != first); + } + } + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + /* Only allow a single mode for MX and TX chipsets */ + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_300SX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_500TX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_MX)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_MX)) ) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "This GLINT chip only supports one modeline, using first\n"); + pScrn->modes->next = NULL; + pScrn->virtualX = pScrn->modes->HDisplay; + pScrn->virtualY = pScrn->modes->VDisplay; + pScrn->displayWidth = pScrn->virtualX; + if (partprod500TX[pScrn->displayWidth >> 5] == -1) { + i = -1; + do { + pScrn->displayWidth += 32; + i = partprod500TX[pScrn->displayWidth >> 5]; + } while (i == -1); + } + } + + /* Check Virtual resolution */ + if (pScrn->virtualX > maxwidth) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "GLINTModeInit: virtual width (%d) too big for hardware\n", + pScrn->virtualX); + return FALSE; + } + if (pScrn->virtualY > maxheight) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "GLINTModeInit: virtual height (%d) too big for hardware\n", + pScrn->virtualY); + return FALSE; + } + + switch (pGlint->Chipset) + { /* Now we know displaywidth, so set linepitch data */ + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5]; + pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1]; + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_MX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + pGlint->pprod = partprod500TX[pScrn->displayWidth >> 5]; + pGlint->bppalign = 0; + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_MX: + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + pGlint->pprod = partprod500TX[pScrn->displayWidth >> 5]; + pGlint->bppalign = 0; + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5]; + pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1]; + break; + } + break; + } + + if ( ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2)) && + (pGlint->numMultiDevices == 2) ) { + int bytesPerPixel, realWidthBytes, inputXSpanBytes; + CARD32 postMultiply, productEnable, use16xProduct, inputXSpan; + CARD32 binaryEval, glintApSize; + + /* setup multi glint framebuffer aperture */ + bytesPerPixel = (pScrn->bitsPerPixel >> 3); + realWidthBytes = pScrn->displayWidth * bytesPerPixel; + + /* compute Input X Span field */ + binaryEval = ((realWidthBytes << 1) - 1); + if (binaryEval & (8 << 10)) { /* 8K */ + inputXSpan = 3; + inputXSpanBytes = 8 * 1024; + } + else if (binaryEval & (4 << 10)) { /* 4K */ + inputXSpan = 2; + inputXSpanBytes = 4 * 1024; + } + else if (binaryEval & (2 << 10)) { /* 2K */ + inputXSpan = 1; + inputXSpanBytes = 2 * 1024; + } + else { /* 1K */ + inputXSpan = 0; + inputXSpanBytes = 1024; + } + + /* compute post multiply */ + binaryEval = realWidthBytes >> 3; + postMultiply = 0; + while ((postMultiply < 5) && !(binaryEval & 1)) { + postMultiply++; + binaryEval >>= 1; + } + postMultiply <<= 7; + + /* compute product enable fields */ + if (binaryEval & ~0x1f) { /* too big */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "GLINTModeInit: width (%d) too big\n", + pScrn->displayWidth); + return FALSE; + } + if ((binaryEval & 0x12) == 0x12) { /* clash between x2 and x16 */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "GLINTModeInit: width (%d) is mult 18, not supported\n", + pScrn->displayWidth); + return FALSE; + } + if (binaryEval & 0x10) { + productEnable = (((binaryEval & 0xf) | 0x2) << 3); + use16xProduct = (1 << 2); + } + else { + productEnable = ((binaryEval & 0xf) << 3); + use16xProduct = 0; + } + + /* compute GLINT Aperture Size field */ + binaryEval = ((pScrn->videoRam << 11) - 1); + if (binaryEval & (32 << 20)) { /* 32M */ + glintApSize = 3 << 10; + } + else if (binaryEval & (16 << 20)) { /* 16M */ + glintApSize = 2 << 10; + } + else if (binaryEval & (8 << 20)) { /* 8M */ + glintApSize = 1 << 10; + } + else { /* 4M */ + glintApSize = 0 << 10; + } + + pGlint->realWidth = ( glintApSize | + postMultiply | + productEnable | + use16xProduct | + inputXSpan ); + + /* set the MULTI width for software rendering */ + pScrn->displayWidth = inputXSpanBytes / bytesPerPixel; + } + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 24: + mod = "fb"; + syms = fbSymbols; + break; + case 32: + if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { + mod = "xf8_32bpp"; + syms = xf8_32bppSymbols; + } else { + mod = "fb"; + syms = fbSymbols; + } + break; + } + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + GLINTFreeRec(pScrn); + return FALSE; + } + if (mod && syms) { + xf86LoaderReqSymLists(syms, NULL); + } + + /* Load XAA if needed */ + if (!pGlint->NoAccel) { + if (!xf86LoadSubModule(pScrn, "xaa")) { + GLINTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + /* Load shadowfb if needed */ + if (pGlint->ShadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + GLINTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + /* Load DDC */ + if (!xf86LoadSubModule(pScrn, "ddc")) { + GLINTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ddcSymbols, NULL); + /* Load I2C if needed */ + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) || + (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) { + if (xf86LoadSubModule(pScrn, "i2c")) { + I2CBusPtr pBus; + + xf86LoaderReqSymLists(i2cSymbols, NULL); + if ((pBus = xf86CreateI2CBusRec())) { + pBus->BusName = "DDC"; + pBus->scrnIndex = pScrn->scrnIndex; + pBus->I2CUDelay = Permedia2I2CUDelay; + pBus->I2CPutBits = Permedia2I2CPutBits; + pBus->I2CGetBits = Permedia2I2CGetBits; + pBus->DriverPrivate.ptr = pGlint; + if (!xf86I2CBusInit(pBus)) { + xf86DestroyI2CBusRec(pBus, TRUE, TRUE); + } else + pGlint->DDCBus = pBus; + } + + if ((pBus = xf86CreateI2CBusRec())) { + pBus->BusName = "Video"; + pBus->scrnIndex = pScrn->scrnIndex; + pBus->I2CUDelay = Permedia2I2CUDelay; + pBus->I2CPutBits = Permedia2I2CPutBits; + pBus->I2CGetBits = Permedia2I2CGetBits; + pBus->DriverPrivate.ptr = pGlint; + if (!xf86I2CBusInit(pBus)) { + xf86DestroyI2CBusRec(pBus, TRUE, TRUE); + } else + pGlint->VSBus = pBus; + } + } + } + + TRACE_EXIT("GLINTPreInit"); + return TRUE; +} + + +/* + * Map the framebuffer and MMIO memory. + */ + +static Bool +GLINTMapMem(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + + pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("GLINTMapMem"); + if (pGlint->FBDev) { + pGlint->FbBase = fbdevHWMapVidmem(pScrn); + if (pGlint->FbBase == NULL) + return FALSE; + + pGlint->IOBase = fbdevHWMapMMIO(pScrn); + if (pGlint->IOBase == NULL) + return FALSE; + + TRACE_EXIT("GLINTMapMem"); + return TRUE; + } + + /* + * Map IO registers to virtual address space + * We always map VGA IO registers - even if we don't need them + */ + pGlint->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pGlint->PciTag, pGlint->IOAddress, 0x20000); + + if (pGlint->IOBase == NULL) + return FALSE; + + if (pGlint->FbMapSize != 0) { + pGlint->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pGlint->PciTag, + pGlint->FbAddress, + pGlint->FbMapSize); + if (pGlint->FbBase == NULL) + return FALSE; + } + + TRACE_EXIT("GLINTMapMem"); + return TRUE; +} + + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +GLINTUnmapMem(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + + pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("GLINTUnmapMem"); + if (pGlint->FBDev) { + fbdevHWUnmapVidmem(pScrn); + pGlint->FbBase = NULL; + fbdevHWUnmapMMIO(pScrn); + pGlint->IOBase = NULL; + + TRACE_EXIT("GLINTUnmapMem"); + return TRUE; + } + + /* + * Unmap IO registers to virtual address space + */ + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->IOBase, 0x20000); + pGlint->IOBase = NULL; + + if (pGlint->FbBase != NULL) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->FbBase, pGlint->FbMapSize); + pGlint->FbBase = NULL; + + TRACE_EXIT("GLINTUnmapMem"); + return TRUE; +} + +/* + * This function saves the video state. + */ +static void +GLINTSave(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + GLINTRegPtr glintReg; + GLINTRegPtr glintReg2; + RamDacHWRecPtr pRAMDAC; + RamDacRegRecPtr RAMDACreg; + + pGlint = GLINTPTR(pScrn); + pRAMDAC = RAMDACHWPTR(pScrn); + glintReg = &pGlint->SavedReg[0]; + glintReg2 = &pGlint->SavedReg[1]; + RAMDACreg = &pRAMDAC->SavedReg; + TRACE_ENTER("GLINTSave"); + + switch (pGlint->Chipset) + { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + Permedia2Save(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VSave(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3Save(pScrn, glintReg); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaSave(pScrn, glintReg); + (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXSave(pScrn, glintReg); + (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + case PCI_CHIP_MX: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2() + TXSave(pScrn, glintReg2); +#if 0 + (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg2); +#endif + ACCESSCHIP1(); + } + TXSave(pScrn, glintReg); + (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaSave(pScrn, glintReg); + (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + Permedia3Save(pScrn, glintReg2); + ACCESSCHIP1(); + } + Permedia3Save(pScrn, glintReg); + break; + } + break; + } + TRACE_EXIT("GLINTSave"); +} + + +/* + * Initialise a new mode. This is currently still using the old + * "initialise struct, restore/write struct to HW" model. That could + * be changed. + */ + +static Bool +GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int ret = -1; + GLINTPtr pGlint = GLINTPTR(pScrn); + RamDacHWRecPtr pRAMDAC = RAMDACHWPTR(pScrn); + RamDacRegRecPtr RAMDACreg; + GLINTRegPtr glintReg = &pGlint->ModeReg[0]; + GLINTRegPtr glintReg2 = &pGlint->ModeReg[1]; + + pScrn->vtSema = TRUE; + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + ret = Permedia2Init(pScrn, mode); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + ret = Permedia2VInit(pScrn, mode); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + ret = Permedia3Init(pScrn, mode, glintReg); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + ret = PermediaInit(pScrn, mode); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + ret = TXInit(pScrn, mode, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_MX: + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + ret = TXInit(pScrn, mode, glintReg2); + ACCESSCHIP1(); + } + ret = TXInit(pScrn, mode, glintReg); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + ret = PermediaInit(pScrn, mode); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + ret = Permedia3Init(pScrn, mode, glintReg2); + ACCESSCHIP1(); + } + ret = Permedia3Init(pScrn, mode, glintReg); + break; + } + break; + } + + if (!ret) + return FALSE; + + glintReg = &pGlint->ModeReg[0]; + glintReg2 = &pGlint->ModeReg[1]; + RAMDACreg = &pRAMDAC->ModeReg; + + pGlint->STATE = FALSE; + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + Permedia2Restore(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VRestore(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3Restore(pScrn, glintReg); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + case PCI_CHIP_MX: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + TXRestore(pScrn, glintReg2); +#if 0 + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec,RAMDACreg2); +#endif + ACCESSCHIP1(); + } + TXRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + Permedia3Restore(pScrn, glintReg2); + ACCESSCHIP1(); + } + Permedia3Restore(pScrn, glintReg); + break; + } + break; + } + + if (xf86IsPc98()) + outb(0xfac, 0x01); + + return TRUE; +} + +/* + * Restore the initial (text) mode. + */ +static void +GLINTRestore(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint; + GLINTRegPtr glintReg; + GLINTRegPtr glintReg2; + RamDacHWRecPtr pRAMDAC; + RamDacRegRecPtr RAMDACreg; + + pGlint = GLINTPTR(pScrn); + pRAMDAC = RAMDACHWPTR(pScrn); + glintReg = &pGlint->SavedReg[0]; + glintReg2 = &pGlint->SavedReg[1]; + RAMDACreg = &pRAMDAC->SavedReg; + + TRACE_ENTER("GLINTRestore"); + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + Permedia2VideoLeaveVT(pScrn); + Permedia2Restore(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VideoLeaveVT(pScrn); + Permedia2VRestore(pScrn, glintReg); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3Restore(pScrn, glintReg); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_MX: + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + TXRestore(pScrn, glintReg2); +#if 0 + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec,RAMDACreg2); +#endif + ACCESSCHIP1(); + } + TXRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaRestore(pScrn, glintReg); + (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + if (pGlint->numMultiDevices == 2) { + ACCESSCHIP2(); + Permedia3Restore(pScrn, glintReg2); + ACCESSCHIP1(); + } + Permedia3Restore(pScrn, glintReg); + break; + } + break; + } + + TRACE_EXIT("GLINTRestore"); +} + + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + int ret, displayWidth; + int init_picture = 0; + unsigned char *FBStart; + VisualPtr visual; + + TRACE_ENTER("GLINTScreenInit"); + /* Map the GLINT memory and MMIO areas */ + if (!GLINTMapMem(pScrn)) + return FALSE; + + if (pGlint->FBDev) { + fbdevHWSave(pScrn); + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid mode\n"); + return FALSE; + } + } else + /* Save the current state */ + GLINTSave(pScrn); + + /* DDC */ + { + xf86MonPtr pMon = NULL; + + if (pGlint->DDCBus) + pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pGlint->DDCBus); + + if (!pMon) + /* Try DDC1 */; + + xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon)); + } + + /* Initialise the first mode */ + if ( (!pGlint->FBDev) && !(GLINTModeInit(pScrn, pScrn->currentMode))) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid mode\n"); + return FALSE; + } + + /* Darken the screen for aesthetic reasons and set the viewport */ + GLINTSaveScreen(pScreen, SCREEN_SAVER_ON); + GLINTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that cfb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + /* + * For bpp > 8, the default visuals are not acceptable because we only + * support TrueColor and not DirectColor. To deal with this, call + * miSetVisualTypes for each visual supported. + */ + + if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && + (pScrn->bitsPerPixel == 32)) { + if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask, + pScrn->rgbBits, PseudoColor)) + return FALSE; + if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + } + +#ifdef XF86DRI + /* + * Setup DRI after visuals have been established, but before fbScreenInit + * is called. fbScreenInit will eventually call into the drivers + * InitGLXVisuals call back. + */ + if (!pGlint->NoAccel && pGlint->HWCursor) { + pGlint->directRenderingEnabled = GLINTDRIScreenInit(pScreen); + } else { + pGlint->directRenderingEnabled = FALSE; + } +#endif + + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + if(pGlint->ShadowFB) { + pGlint->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * pScrn->virtualX); + pGlint->ShadowPtr = xalloc(pGlint->ShadowPitch * pScrn->virtualY); + displayWidth = pGlint->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pGlint->ShadowPtr; + } else { + pGlint->ShadowPtr = NULL; + displayWidth = pScrn->displayWidth; + FBStart = pGlint->FbBase; + } + + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 24: + ret = fbScreenInit(pScreen, FBStart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + init_picture = 1; + break; + case 32: + if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + ret = cfb8_32ScreenInit(pScreen, FBStart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + displayWidth); + else { + ret = fbScreenInit(pScreen, FBStart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + init_picture = 1; + } + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in GLINTScrnInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + + pGlint->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = GLINTBlockHandler; + +#if !defined(__sparc__) + if (!pGlint->ShadowFB) + GLINTDGAInit(pScreen); +#endif + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + /* must be after RGB ordering fixed */ + if (init_picture) + fbPictureInit(pScreen, 0, 0); + if (!pGlint->NoAccel) { + switch (pGlint->Chipset) + { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2AccelInit(pScreen); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3AccelInit(pScreen); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaAccelInit(pScreen); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXAccelInit(pScreen); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_MX: + TXAccelInit(pScreen); + break; + case PCI_CHIP_300SX: + SXAccelInit(pScreen); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaAccelInit(pScreen); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + Permedia3AccelInit(pScreen); + break; + } + break; + case PCI_VENDOR_3DLABS_CHIP_300SX: + SXAccelInit(pScreen); + break; + } + } + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Initialise cursor functions */ + if (pGlint->HWCursor) { + /* Handle VGA chipsets first */ + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) + Permedia2HWCursorInit(pScreen); + else + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) && + (pGlint->MultiChip == PCI_CHIP_R4)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) + Permedia2vHWCursorInit(pScreen); + else + /* If we get here pGlint->Ramdac should have been set */ + if ( ((pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC)) || + (pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) || + (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))) ) + glintIBMHWCursorInit(pScreen); + else + if ( (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) ) + glintTIHWCursorInit(pScreen); + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) && + (pGlint->MultiChip == PCI_CHIP_R4)) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) { + if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, + (pGlint->FBDev) ? fbdevHWLoadPalette : + ((pScrn->depth == 16) ? Permedia3LoadPalette16:Permedia3LoadPalette), + NULL, + CMAP_RELOAD_ON_MODE_SWITCH | + ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + ? 0 : CMAP_PALETTED_TRUECOLOR))) + return FALSE; + } else + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) || + (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) { + if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, + (pGlint->FBDev) ? fbdevHWLoadPalette : + ((pScrn->depth == 16) ? Permedia2LoadPalette16:Permedia2LoadPalette), + NULL, + CMAP_RELOAD_ON_MODE_SWITCH | + ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + ? 0 : CMAP_PALETTED_TRUECOLOR))) + return FALSE; + } else { + if (pScrn->rgbBits == 10) { + if (!RamDacHandleColormaps(pScreen, 1024, pScrn->rgbBits, + CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) + return FALSE; + } else { + if (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits, + CMAP_RELOAD_ON_MODE_SWITCH | + ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + ? 0 : CMAP_PALETTED_TRUECOLOR))) + return FALSE; + } + } + + if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && + (pScrn->bitsPerPixel == 32)) { + if(!xf86Overlay8Plus32Init(pScreen)) + return FALSE; + } + + if(pGlint->ShadowFB) + ShadowFBInit(pScreen, GLINTRefreshArea); + + xf86DPMSInit(pScreen, (DPMSSetProcPtr)GLINTDisplayPowerManagementSet, 0); + +#ifdef XF86DRI + if (pGlint->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have done their thing, + * complete the DRI setup. + */ + pGlint->directRenderingEnabled = GLINTDRIFinishScreenInit(pScreen); + } + if (pGlint->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "direct rendering disabled\n"); + } +#endif + + pScrn->memPhysBase = pGlint->FbAddress; + pScrn->fbOffset = 0; + + pGlint->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = GLINTCloseScreen; + pScreen->SaveScreen = GLINTSaveScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VideoInit(pScreen); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3InitVideo(pScreen); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + switch (pGlint->MultiChip) { + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + Permedia3InitVideo(pScreen); + } + } + +#if 0 + /* Enable the screen */ + GLINTSaveScreen(pScreen, SCREEN_SAVER_OFF); +#endif + + /* Done */ + TRACE_EXIT("GLINTScreenInit"); + return TRUE; +} + +/* Usually mandatory */ +Bool +GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn; + GLINTPtr pGlint; + + pScrn = xf86Screens[scrnIndex]; + pGlint = GLINTPTR(pScrn); + TRACE_ENTER("GLINTSwitchMode"); + + if (pGlint->FBDev) { + Bool ret = fbdevHWSwitchMode(scrnIndex, mode, flags); + + if (!pGlint->NoAccel) { + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2InitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3InitializeEngine(pScrn); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_300SX: + SXInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_MX: + TXInitializeEngine(pScrn); + break; + case PCI_CHIP_300SX: + SXInitializeEngine(pScrn); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaInitializeEngine(pScrn); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + Permedia3InitializeEngine(pScrn); + break; + } + break; + } + } + + TRACE_EXIT("GLINTSwitchMode (fbdev ?)"); + return ret; + } + + TRACE_EXIT("GLINTSwitchMode (normal)"); + return GLINTModeInit(xf86Screens[scrnIndex], mode); +} + + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +void +GLINTAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn; + CARD32 base; + GLINTPtr pGlint; + + pScrn = xf86Screens[scrnIndex]; + pGlint = GLINTPTR(pScrn); + TRACE_ENTER("GLINTAdjustFrame"); + + if (pGlint->FBDev) { + fbdevHWAdjustFrame(scrnIndex, x, y, flags); + TRACE_EXIT("GLINTAdjustFrame (fbdev)"); + return; + } + + base = ((y * pScrn->displayWidth + x) >> 1) >> pGlint->BppShift; + if (pScrn->bitsPerPixel == 24) base *= 3; + + switch (pGlint->Chipset) + { + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + GLINT_SLOW_WRITE_REG(base, PMScreenBase); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + base = (y * pScrn->displayWidth + x) >> pGlint->BppShift; + GLINT_SLOW_WRITE_REG(base, PMScreenBase); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + base = (y * pScrn->displayWidth + x) >> pGlint->BppShift; + GLINT_SLOW_WRITE_REG(base, PMScreenBase); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + GLINT_SLOW_WRITE_REG(base, PMScreenBase); + break; + } + break; + } + TRACE_EXIT("GLINTAdjustFrame (normal)"); +} + + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + * + * We may wish to unmap video/MMIO memory too. + */ + +/* Mandatory */ +static Bool +GLINTEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("GLINTEnterVT"); + + if (pGlint->FBDev) + fbdevHWEnterVT(scrnIndex, flags); + else + /* Should we re-save the text mode on each VT enter? */ + if (!GLINTModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VideoEnterVT(pScrn); + break; + } + + if (!pGlint->NoAccel) { + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2InitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + Permedia3InitializeEngine(pScrn); + break; + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + PermediaInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_MX: + TXInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_300SX: + SXInitializeEngine(pScrn); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_MX: + TXInitializeEngine(pScrn); + break; + case PCI_CHIP_300SX: + SXInitializeEngine(pScrn); + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + PermediaInitializeEngine(pScrn); + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + Permedia3InitializeEngine(pScrn); + break; + } + break; + } + } + + TRACE_EXIT("GLINTEnterVTFBDev"); + return TRUE; +} + + +/* + * This is called when VT switching away from the X server. Its job is + * to restore the previous (text) mode. + * + * We may wish to remap video/MMIO memory too. + */ + +/* Mandatory */ +static void +GLINTLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("GLINTLeaveVT"); + pGlint->STATE = TRUE; + GLINTRestore(pScrn); + + if (xf86IsPc98()) + outb(0xfac, 0x00); + + TRACE_EXIT("GLINTLeaveVT"); +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should really also unmap the video memory too. + */ + +/* Mandatory */ +static Bool +GLINTCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("GLINTCloseScreen"); +#ifdef XF86DRI + if (pGlint->directRenderingEnabled) { + GLINTDRICloseScreen(pScreen); + } +#endif + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + Permedia2VideoUninit(pScrn); + break; + } + + if (pScrn->vtSema) { + if(pGlint->CursorInfoRec) + pGlint->CursorInfoRec->HideCursor(pScrn); + if (pGlint->FBDev) + fbdevHWRestore(pScrn); + else { + pGlint->STATE = TRUE; + GLINTRestore(pScrn); + } + GLINTUnmapMem(pScrn); + } + if(pGlint->AccelInfoRec) + XAADestroyInfoRec(pGlint->AccelInfoRec); + if(pGlint->CursorInfoRec) + xf86DestroyCursorInfoRec(pGlint->CursorInfoRec); + if (pGlint->ShadowPtr) + xfree(pGlint->ShadowPtr); + if (pGlint->DGAModes) + xfree(pGlint->DGAModes); + if (pGlint->ScratchBuffer) + xfree(pGlint->ScratchBuffer); + pScrn->vtSema = FALSE; + + if (xf86IsPc98()) + outb(0xfac, 0x00); + + if(pGlint->BlockHandler) + pScreen->BlockHandler = pGlint->BlockHandler; + + pScreen->CloseScreen = pGlint->CloseScreen; + TRACE_EXIT("GLINTCloseScreen"); + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + +/* Free up any per-generation data structures */ + +/* Optional */ +static void +GLINTFreeScreen(int scrnIndex, int flags) +{ +#if DEBUG + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +#endif + TRACE_ENTER("GLINTFreeScreen"); + if (xf86LoaderCheckSymbol("fbdevHWFreeRec")) + fbdevHWFreeRec(xf86Screens[scrnIndex]); + if (xf86LoaderCheckSymbol("RamDacFreeRec")) + RamDacFreeRec(xf86Screens[scrnIndex]); + GLINTFreeRec(xf86Screens[scrnIndex]); + TRACE_EXIT("GLINTFreeScreen"); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static int +GLINTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (mode->Flags & V_INTERLACE) + return(MODE_NO_INTERLACE); + + if (pScrn->bitsPerPixel == 24) { + /* A restriction on the PM2 where a black strip on the left hand + * side appears if not aligned properly */ + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + if (mode->HDisplay % 8) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HDisplay %d not divisible by 8, fixing...\n", mode->HDisplay); + mode->HDisplay -= (mode->HDisplay % 8); + mode->CrtcHDisplay = mode->CrtcHBlankStart = mode->HDisplay; + } + + if (mode->HSyncStart % 8) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HSyncStart %d not divisible by 8, fixing...\n", mode->HSyncStart); + mode->HSyncStart -= (mode->HSyncStart % 8); + mode->CrtcHSyncStart = mode->HSyncStart; + } + + if (mode->HSyncEnd % 8) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HSyncEnd %d not divisible by 8, fixing...\n", mode->HSyncEnd); + mode->HSyncEnd -= (mode->HSyncEnd % 8); + mode->CrtcHSyncEnd = mode->HSyncEnd; + } + + if (mode->HTotal % 8) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HTotal %d not divisible by 8, fixing...\n", mode->HTotal); + mode->HTotal -= (mode->HTotal % 8); + mode->CrtcHBlankEnd = mode->CrtcHTotal = mode->HTotal; + } + break; + } + } + + return(MODE_OK); +} + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +GLINTSaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 temp; + Bool unblank; + + TRACE_ENTER("GLINTSaveScreen"); + + unblank = xf86IsUnblank(mode); + + if (unblank) + SetTimeSinceLastInputEvent(); + + if ((pScrn != NULL ) && pScrn->vtSema) { + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + temp = GLINT_READ_REG(PMVideoControl); + if (unblank) temp |= 1; + else temp &= 0xFFFFFFFE; + GLINT_SLOW_WRITE_REG(temp, PMVideoControl); + break; + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_MX: + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + temp = GLINT_READ_REG(PMVideoControl); + if (unblank) temp |= 1; + else temp &= 0xFFFFFFFE; + GLINT_SLOW_WRITE_REG(temp, PMVideoControl); + break; + } + break; + } + } + + TRACE_EXIT("GLINTSaveScreen"); + return TRUE; +} + +static void +GLINTBlockHandler ( + int i, + pointer blockData, + pointer pTimeout, + pointer pReadmask +){ + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; + GLINTPtr pGlint = GLINTPTR(pScrn); + int sigstate = xf86BlockSIGIO(); + + if(pGlint->CursorColorCallback) + (*pGlint->CursorColorCallback)(pScrn); + + if(pGlint->LoadCursorCallback) + (*pGlint->LoadCursorCallback)(pScrn); + + xf86UnblockSIGIO(sigstate); + + pScreen->BlockHandler = pGlint->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = GLINTBlockHandler; + + if(pGlint->VideoTimerCallback) { + UpdateCurrentTime(); + (*pGlint->VideoTimerCallback)(pScrn, currentTime.milliseconds); + } +} + +#ifdef DEBUG +void +GLINT_VERB_WRITE_REG(GLINTPtr pGlint, CARD32 v, int r, char *file, int line) +{ + if (xf86GetVerbosity() > 2) + ErrorF("[0x%04x] <- 0x%08x (%s, %d)\n", r, v, file, line); + *(volatile CARD32 *)((char *) pGlint->IOBase + pGlint->IOOffset + r) = v; +} + +CARD32 +GLINT_VERB_READ_REG(GLINTPtr pGlint, CARD32 r, char *file, int line) +{ + CARD32 v = + *(volatile CARD32 *)((char *) pGlint->IOBase + pGlint->IOOffset + r); + + if (xf86GetVerbosity() > 2) + ErrorF("[0x%04x] -> 0x%08x (%s, %d)\n", r, v, file, line); + return v; +} +#endif + +void GLINT_MoveBYTE( + register CARD32* dest, + register unsigned char* src, + register int dwords) +{ +#ifdef __alpha__ + write_mem_barrier(); +#endif + while(dwords) { + *dest = *src; + src += 1; + dest += 1; + dwords -= 1; + } +} + +void GLINT_MoveWORDS( + register CARD32* dest, + register unsigned short* src, + register int dwords) +{ +#ifdef __alpha__ + write_mem_barrier(); +#endif + while(dwords & ~0x01) { + *dest = *src; + *(dest + 1) = *(src + 1); + src += 2; + dest += 2; + dwords -= 2; + } + if (dwords) + *dest = *src; +} + +void GLINT_MoveDWORDS( + register CARD32* dest, + register CARD32* src, + register int dwords) +{ +#ifdef __alpha__ + write_mem_barrier(); +#endif + if ((unsigned long)src & 0x3UL) { + unsigned char *pchar; + while (dwords & ~0x03) { + pchar = (unsigned char *)(src + 0); + *(dest + 0) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + pchar = (unsigned char *)(src + 1); + *(dest + 1) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + pchar = (unsigned char *)(src + 2); + *(dest + 2) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + pchar = (unsigned char *)(src + 3); + *(dest + 3) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + src += 4; + dest += 4; + dwords -= 4; + } + if (!dwords) + return; + pchar = (unsigned char *)(src + 0); + *(dest + 0) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + if (dwords == 1) + return; + pchar = (unsigned char *)(src + 1); + *(dest + 1) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + if (dwords == 2) + return; + pchar = (unsigned char *)(src + 2); + *(dest + 2) = (((CARD32)pchar[0] << 24) | + ((CARD32)pchar[1] << 16) | + ((CARD32)pchar[2] << 8) | + ((CARD32)pchar[3] << 0)); + } else { + while (dwords & ~0x03) { + *dest = *src; + *(dest + 1) = *(src + 1); + *(dest + 2) = *(src + 2); + *(dest + 3) = *(src + 3); + src += 4; + dest += 4; + dwords -= 4; + } + if (!dwords) + return; + *dest = *src; + if (dwords == 1) + return; + *(dest + 1) = *(src + 1); + if (dwords == 2) + return; + *(dest + 2) = *(src + 2); + } +} + +int +Shiftbpp(ScrnInfoPtr pScrn, int value) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int logbytesperaccess = 2; /* default */ + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + logbytesperaccess = 2; + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + logbytesperaccess = 4; + break; + case PCI_VENDOR_3DLABS_CHIP_300SX: + case PCI_VENDOR_3DLABS_CHIP_500TX: + case PCI_VENDOR_3DLABS_CHIP_MX: + if ( (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ) + logbytesperaccess = 4; + else + logbytesperaccess = 3; + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + case PCI_VENDOR_3DLABS_CHIP_GAMMA2: + case PCI_VENDOR_3DLABS_CHIP_DELTA: + switch (pGlint->MultiChip) { + case PCI_CHIP_500TX: + case PCI_CHIP_300SX: + case PCI_CHIP_MX: + if ( (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) || + (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ) + logbytesperaccess = 4; + else + logbytesperaccess = 3; + break; + case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: + logbytesperaccess = 2; + break; + case PCI_CHIP_R4: + case PCI_CHIP_PERMEDIA3: + logbytesperaccess = 4; + break; + } + } + + switch (pScrn->bitsPerPixel) { + case 8: + value >>= logbytesperaccess; + pGlint->BppShift = logbytesperaccess; + break; + case 16: + if (pGlint->DoubleBuffer) { + value >>= (logbytesperaccess-2); + pGlint->BppShift = logbytesperaccess-2; + } else { + value >>= (logbytesperaccess-1); + pGlint->BppShift = logbytesperaccess-1; + } + break; + case 24: + value *= 3; + value >>= logbytesperaccess; + pGlint->BppShift = logbytesperaccess; + break; + case 32: + value >>= (logbytesperaccess-2); + pGlint->BppShift = logbytesperaccess-2; + break; + } + return (value); +} diff --git a/src/glint_regs.h b/src/glint_regs.h new file mode 100644 index 0000000..122832d --- /dev/null +++ b/src/glint_regs.h @@ -0,0 +1,1361 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.36 2003/01/12 03:55:47 tsi Exp $ */ + +/* + * glint register file + * + * Copyright by Stefan Dirsch, Dirk Hohndel, Alan Hourihane + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Simon P., <sim@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + * + */ + +#ifndef _GLINTREG_H_ +#define _GLINTREG_H_ + +#include "compiler.h" + +/* The chips we know */ +#define PCI_CHIP_3DLABS_300SX 0x01 +#define PCI_CHIP_3DLABS_500TX 0x02 +#define PCI_CHIP_3DLABS_DELTA 0x03 +#define PCI_CHIP_3DLABS_PERMEDIA 0x04 +#define PCI_CHIP_3DLABS_MX 0x06 +#define PCI_CHIP_3DLABS_PERMEDIA2 0x07 +#define PCI_CHIP_3DLABS_GAMMA 0x08 +#define PCI_CHIP_3DLABS_PERMEDIA2V 0x09 +#define PCI_CHIP_3DLABS_PERMEDIA3 0x0A +#define PCI_CHIP_3DLABS_PERMEDIA4 0x0C +#define PCI_CHIP_3DLABS_R4 0x0D +#define PCI_CHIP_3DLABS_GAMMA2 0x0E + +/* The boards we know */ +#define IS_GLORIAXXL ((pGlint->PciInfo->subsysVendor == 0x1048) && \ + (pGlint->PciInfo->subsysCard == 0x0a42)) + +#define IS_GLORIASYNERGY ((pGlint->PciInfo->subsysVendor == 0x1048) && \ + (pGlint->PciInfo->subsysCard == 0x0a32)) + +#define IS_GMX2000 ((pGlint->PciInfo->subsysVendor == 0x3d3d) && \ + (pGlint->PciInfo->subsysCard == 0x0106)) + +#define IS_J2000 ((pGlint->PciInfo->subsysVendor == 0x1097) && \ + (pGlint->PciInfo->subsysCard == 0x3d32)) + +#define IS_JPRO ((pGlint->PciInfo->subsysVendor == 0x1097) && \ + (pGlint->PciInfo->subsysCard == 0x3db3)) + +/* COMPAQ OEM VX1 PCI + * subsys == 0x0121 if VGA is enabled + * subsys == 0x000a if VGA has never been enabled + */ +#define IS_PCI_QVX1 (pGlint->PciInfo->subsysVendor == 0x3d3d && \ + ((pGlint->PciInfo->subsysCard == 0x0121) || \ + (pGlint->PciInfo->subsysCard == 0x000a))) + +/* COMPAQ OEM VX1 AGP + * subsys == 0x0144 if VGA is enabled + * subsys == 0x000c if VGA has never been enabled + */ +#define IS_AGP_QVX1 (pGlint->PciInfo->subsysVendor == 0x3d3d && \ + ((pGlint->PciInfo->subsysCard == 0x0144) || \ + (pGlint->PciInfo->subsysCard == 0x000c))) + +#define IS_QVX1 (IS_PCI_QVX1 || IS_AGP_QVX1) + +#define IS_ELSA_SYNERGY ((pGlint->PciInfo->subsysVendor == 0x1048) && \ + (pGlint->PciInfo->subsysCard == 0x0a32)) + +/* COMPAQ OEM Permedia 2V with VGA disable jumper - 0x13e9 ? */ +#define IS_QPM2V ((pGlint->PciInfo->subsysVendor == 0x13e9) && \ + ((pGlint->PciInfo->subsysCard == 0x0100) || \ + (pGlint->PciInfo->subsysCard == 0x0002))) + +/********************************************** +* GLINT 500TX Configuration Region Registers * +***********************************************/ + +/* Device Identification */ +#define CFGVendorId 0x0000 +#define PCI_VENDOR_3DLABS 0x3D3D +#define PCI_VENDOR_TI 0x104C +#define CFGDeviceId 0x0002 + +#define CFGRevisionId 0x08 +#define CFGClassCode 0x09 +#define CFGHeaderType 0x0E + +/* Device Control/Status */ +#define CFGCommand 0x04 +#define CFGStatus 0x06 + +/* Miscellaneous Functions */ +#define CFGBist 0x0f +#define CFGLatTimer 0x0d +#define CFGCacheLine 0x0c +#define CFGMaxLat 0x3f +#define CFGMinGrant 0x3e +#define CFGIntPin 0x3d +#define CFGIntLine 0x3c + +/* Base Adresses */ +#define CFGBaseAddr0 0x10 +#define CFGBaseAddr1 0x14 +#define CFGBaseAddr2 0x18 +#define CFGBaseAddr3 0x1C +#define CFGBaseAddr4 0x20 +#define CFGRomAddr 0x30 + + + +/********************************** + * GLINT 500TX Region 0 Registers * + **********************************/ + +/* Control Status Registers */ +#define ResetStatus 0x0000 +#define IntEnable 0x0008 +#define IntFlags 0x0010 +#define InFIFOSpace 0x0018 +#define OutFIFOWords 0x0020 +#define DMAAddress 0x0028 +#define DMACount 0x0030 +#define ErrorFlags 0x0038 +#define VClkCtl 0x0040 +#define TestRegister 0x0048 +#define Aperture0 0x0050 +#define Aperture1 0x0058 +#define DMAControl 0x0060 +#define FIFODis 0x0068 + +/* GLINT PerMedia Region 0 additional Registers */ +#define ChipConfig 0x0070 +#define SCLK_SEL_MASK (3 << 10) +#define SCLK_SEL_MCLK_HALF (3 << 10) +#define ByDMAControl 0x00D8 + +/* GLINT 500TX LocalBuffer Registers */ +#define LBMemoryCtl 0x1000 +#define LBNumBanksMask 0x00000001 +#define LBNumBanks1 (0) +#define LBNumBanks2 (1) +#define LBPageSizeMask 0x00000006 +#define LBPageSize256 (0<<1) +#define LBPageSize512 (1<<1) +#define LBPageSize1024 (2<<1) +#define LBPageSize2048 (3<<1) +#define LBRASCASLowMask 0x00000018 +#define LBRASCASLow2 (0<<3) +#define LBRASCASLow3 (1<<3) +#define LBRASCASLow4 (2<<3) +#define LBRASCASLow5 (3<<3) +#define LBRASPrechargeMask 0x00000060 +#define LBRASPrecharge2 (0<<5) +#define LBRASPrecharge3 (1<<5) +#define LBRASPrecharge4 (2<<5) +#define LBRASPrecharge5 (3<<5) +#define LBCASLowMask 0x00000180 +#define LBCASLow1 (0<<7) +#define LBCASLow2 (1<<7) +#define LBCASLow3 (2<<7) +#define LBCASLow4 (3<<7) +#define LBPageModeMask 0x00000200 +#define LBPageModeEnabled (0<<9) +#define LBPageModeDisabled (1<<9) +#define LBRefreshCountMask 0x0003fc00 +#define LBRefreshCountShift 10 + +#define LBMemoryEDO 0x1008 +#define LBEDOMask 0x00000001 +#define LBEDODisabled (0) +#define LBEDOEnabled (1) +#define LBEDOBankSizeMask 0x0000000e +#define LBEDOBankSizeDiabled (0<<1) +#define LBEDOBankSize256K (1<<1) +#define LBEDOBankSize512K (2<<1) +#define LBEDOBankSize1M (3<<1) +#define LBEDOBankSize2M (4<<1) +#define LBEDOBankSize4M (5<<1) +#define LBEDOBankSize8M (6<<1) +#define LBEDOBankSize16M (7<<1) +#define LBTwoPageDetectorMask 0x00000010 +#define LBSinglePageDetector (0<<4) +#define LBTwoPageDetector (1<<4) + +/* GLINT PerMedia Memory Control Registers */ +#define PMReboot 0x1000 +#define PMRomControl 0x1040 +#define PMBootAddress 0x1080 +#define PMMemConfig 0x10C0 +# define RowCharge8 1 << 10 +# define TimeRCD8 1 << 7 +# define TimeRC8 0x6 << 3 +# define TimeRP8 1 +# define CAS3Latency8 0 << 16 +# define BootAdress8 0x10 +# define NumberBanks8 0x3 << 29 +# define RefreshCount8 0x41 << 21 +# define TimeRASMin8 1 << 13 +# define DeadCycle8 1 << 17 +# define BankDelay8 0 << 18 +# define Burst1Cycle8 1 << 31 +# define SDRAM8 0 << 4 + +# define RowCharge6 1 << 10 +# define TimeRCD6 1 << 7 +# define TimeRC6 0x6 << 3 +# define TimeRP6 0x2 +# define CAS3Latency6 1 << 16 +# define BootAdress6 0x60 +# define NumberBanks6 0x2 << 29 +# define RefreshCount6 0x41 << 21 +# define TimeRASMin6 1 << 13 +# define DeadCycle6 1 << 17 +# define BankDelay6 0 << 18 +# define Burst1Cycle6 1 << 31 +# define SDRAM6 0 << 4 + +# define RowCharge4 0 << 10 +# define TimeRCD4 0 << 7 +# define TimeRC4 0x4 << 3 +# define TimeRP4 1 +# define CAS3Latency4 0 << 16 +# define BootAdress4 0x10 +# define NumberBanks4 1 << 29 +# define RefreshCount4 0x30 << 21 +# define TimeRASMin4 1 << 13 +# define DeadCycle4 0 << 17 +# define BankDelay4 0 << 18 +# define Burst1Cycle4 1 << 31 +# define SDRAM4 0 << 4 + +/* Permedia 2 Control */ +#define MemControl 0x1040 + +#define PMBypassWriteMask 0x1100 +#define PMFramebufferWriteMask 0x1140 +#define PMCount 0x1180 + +/* Framebuffer Registers */ +#define FBMemoryCtl 0x1800 +#define FBModeSel 0x1808 +#define FBGCWrMask 0x1810 +#define FBGCColorLower 0x1818 +#define FBTXMemCtl 0x1820 +#define FBWrMaskk 0x1830 +#define FBGCColorUpper 0x1838 + +/* Core FIFO */ +#define OutputFIFO 0x2000 + +/* 500TX Internal Video Registers */ +#define VTGHLimit 0x3000 +#define VTGHSyncStart 0x3008 +#define VTGHSyncEnd 0x3010 +#define VTGHBlankEnd 0x3018 +#define VTGVLimit 0x3020 +#define VTGVSyncStart 0x3028 +#define VTGVSyncEnd 0x3030 +#define VTGVBlankEnd 0x3038 +#define VTGHGateStart 0x3040 +#define VTGHGateEnd 0x3048 +#define VTGVGateStart 0x3050 +#define VTGVGateEnd 0x3058 +#define VTGPolarity 0x3060 +#define VTGFrameRowAddr 0x3068 +#define VTGVLineNumber 0x3070 +#define VTGSerialClk 0x3078 +#define VTGModeCtl 0x3080 + +/* Permedia Video Control Registers */ +#define PMScreenBase 0x3000 +#define PMScreenStride 0x3008 +#define PMHTotal 0x3010 +#define PMHgEnd 0x3018 +#define PMHbEnd 0x3020 +#define PMHsStart 0x3028 +#define PMHsEnd 0x3030 +#define PMVTotal 0x3038 +#define PMVbEnd 0x3040 +#define PMVsStart 0x3048 +#define PMVsEnd 0x3050 +#define PMVideoControl 0x3058 +#define PMInterruptLine 0x3060 +#define PMDDCData 0x3068 +#define DataIn (1<<0) +#define ClkIn (1<<1) +#define DataOut (1<<2) +#define ClkOut (1<<3) +#define PMLineCount 0x3070 +#define PMFifoControl 0x3078 + +/* Permedia 2 RAMDAC Registers */ +#define PM2DACWriteAddress 0x4000 +#define PM2DACIndexReg 0x4000 +#define PM2DACData 0x4008 +#define PM2DACReadMask 0x4010 +#define PM2DACReadAddress 0x4018 +#define PM2DACCursorColorAddress 0x4020 +#define PM2DACCursorColorData 0x4028 +#define PM2DACIndexData 0x4050 +#define PM2DACCursorData 0x4058 +#define PM2DACCursorXLsb 0x4060 +#define PM2DACCursorXMsb 0x4068 +#define PM2DACCursorYLsb 0x4070 +#define PM2DACCursorYMsb 0x4078 +#define PM2DACCursorControl 0x06 +#define PM2DACIndexCMR 0x18 +#define PM2DAC_TRUECOLOR 0x80 +#define PM2DAC_RGB 0x20 +#define PM2DAC_GRAPHICS 0x10 +#define PM2DAC_PACKED 0x09 +#define PM2DAC_8888 0x08 +#define PM2DAC_565 0x06 +#define PM2DAC_4444 0x05 +#define PM2DAC_5551 0x04 +#define PM2DAC_2321 0x03 +#define PM2DAC_2320 0x02 +#define PM2DAC_332 0x01 +#define PM2DAC_CI8 0x00 +#define PM2DACIndexMDCR 0x19 +#define PM2DACIndexPalettePage 0x1c +#define PM2DACIndexMCR 0x1e +#define PM2DACIndexClockAM 0x20 +#define PM2DACIndexClockAN 0x21 +#define PM2DACIndexClockAP 0x22 +#define PM2DACIndexClockBM 0x23 +#define PM2DACIndexClockBN 0x24 +#define PM2DACIndexClockBP 0x25 +#define PM2DACIndexClockCM 0x26 +#define PM2DACIndexClockCN 0x27 +#define PM2DACIndexClockCP 0x28 +#define PM2DACIndexClockStatus 0x29 +#define PM2DACIndexMemClockM 0x30 +#define PM2DACIndexMemClockN 0x31 +#define PM2DACIndexMemClockP 0x32 +#define PM2DACIndexMemClockStatus 0x33 +#define PM2DACIndexColorKeyControl 0x40 +#define PM2DACIndexColorKeyOverlay 0x41 +#define PM2DACIndexColorKeyRed 0x42 +#define PM2DACIndexColorKeyGreen 0x43 +#define PM2DACIndexColorKeyBlue 0x44 + +/* Permedia 2V extensions */ +#define PM2VDACRDMiscControl 0x000 +#define PM2VDACRDSyncControl 0x001 +#define PM2VDACRDDACControl 0x002 +#define PM2VDACRDPixelSize 0x003 +#define PM2VDACRDColorFormat 0x004 +#define PM2VDACRDCursorMode 0x005 +#define PM2VDACRDCursorXLow 0x007 +#define PM2VDACRDCursorXHigh 0x008 +#define PM2VDACRDCursorYLow 0x009 +#define PM2VDACRDCursorYHigh 0x00A +#define PM2VDACRDCursorHotSpotX 0x00B +#define PM2VDACRDCursorHotSpotY 0x00C +#define PM2VDACRDOverlayKey 0x00D +#define PM2VDACRDPan 0x00E +#define PM2VDACRDSense 0x00F +#define PM2VDACRDCheckControl 0x018 +#define PM2VDACIndexClockControl 0x200 +#define PM2VDACRDDClk0PreScale 0x201 +#define PM2VDACRDDClk0FeedbackScale 0x202 +#define PM2VDACRDDClk0PostScale 0x203 +#define PM2VDACRDDClk1PreScale 0x204 +#define PM2VDACRDDClk1FeedbackScale 0x205 +#define PM2VDACRDDClk1PostScale 0x206 +#define PM2VDACRDMClkControl 0x20D +#define PM2VDACRDMClkPreScale 0x20E +#define PM2VDACRDMClkFeedbackScale 0x20F +#define PM2VDACRDMClkPostScale 0x210 +#define PM2VDACRDCursorPalette 0x303 +#define PM2VDACRDCursorPattern 0x400 +#define PM2VDACIndexRegLow 0x4020 +#define PM2VDACIndexRegHigh 0x4028 +#define PM2VDACIndexData 0x4030 +#define PM2VDACRDIndexControl 0x4038 + +/* Permedia 2 Video Streams Unit Registers */ +#define VSBIntFlag (1<<8) +#define VSAIntFlag (1<<9) + +#define VSConfiguration 0x5800 +#define VS_UnitMode_ROM 0 +#define VS_UnitMode_AB8 3 +#define VS_UnitMode_Mask 7 +#define VS_GPBusMode_A (1<<3) +#define VS_HRefPolarityA (1<<9) +#define VS_VRefPolarityA (1<<10) +#define VS_VActivePolarityA (1<<11) +#define VS_UseFieldA (1<<12) +#define VS_FieldPolarityA (1<<13) +#define VS_FieldEdgeA (1<<14) +#define VS_VActiveVBIA (1<<15) +#define VS_InterlaceA (1<<16) +#define VS_ReverseDataA (1<<17) +#define VS_HRefPolarityB (1<<18) +#define VS_VRefPolarityB (1<<19) +#define VS_VActivePolarityB (1<<20) +#define VS_UseFieldB (1<<21) +#define VS_FieldPolarityB (1<<22) +#define VS_FieldEdgeB (1<<23) +#define VS_VActiveVBIB (1<<24) +#define VS_InterlaceB (1<<25) +#define VS_ColorSpaceB_RGB (1<<26) +#define VS_ReverseDataB (1<<27) +#define VS_DoubleEdgeB (1<<28) + +#define VSStatus 0x5808 +#define VS_FieldOne0A (1<<9) +#define VS_FieldOne1A (1<<10) +#define VS_FieldOne2A (1<<11) +#define VS_InvalidInterlaceA (1<<12) +#define VS_FieldOne0B (1<<17) +#define VS_FieldOne1B (1<<18) +#define VS_FieldOne2B (1<<19) +#define VS_InvalidInterlaceB (1<<20) + +#define VSSerialBusControl 0x5810 + +#define VSABase 0x5900 +#define VSA_Video (1<<0) +#define VSA_VBI (1<<1) +#define VSA_BufferCtl (1<<2) +#define VSA_MirrorX (1<<7) +#define VSA_MirrorY (1<<8) +#define VSA_Discard_None (0<<9) +#define VSA_Discard_FieldOne (1<<9) +#define VSA_Discard_FieldTwo (2<<9) +#define VSA_CombineFields (1<<11) +#define VSA_LockToStreamB (1<<12) +#define VSBBase 0x5A00 +#define VSB_Video (1<<0) +#define VSB_VBI (1<<1) +#define VSB_BufferCtl (1<<2) +#define VSB_CombineFields (1<<3) +#define VSB_RGBOrder (1<<11) +#define VSB_GammaCorrect (1<<12) +#define VSB_LockToStreamA (1<<13) + +#define VSControl 0x0000 +#define VSInterrupt 0x0008 +#define VSCurrentLine 0x0010 +#define VSVideoAddressHost 0x0018 +#define VSVideoAddressIndex 0x0020 +#define VSVideoAddress0 0x0028 +#define VSVideoAddress1 0x0030 +#define VSVideoAddress2 0x0038 +#define VSVideoStride 0x0040 +#define VSVideoStartLine 0x0048 +#define VSVideoEndLine 0x0050 +#define VSVideoStartData 0x0058 +#define VSVideoEndData 0x0060 +#define VSVBIAddressHost 0x0068 +#define VSVBIAddressIndex 0x0070 +#define VSVBIAddress0 0x0078 +#define VSVBIAddress1 0x0080 +#define VSVBIAddress2 0x0088 +#define VSVBIStride 0x0090 +#define VSVBIStartLine 0x0098 +#define VSVBIEndLine 0x00A0 +#define VSVBIStartData 0x00A8 +#define VSVBIEndData 0x00B0 +#define VSFifoControl 0x00B8 + +/********************************** + * GLINT Delta Region 0 Registers * + **********************************/ + +/* Control Status Registers */ +#define DResetStatus 0x0800 +#define DIntEnable 0x0808 +#define DIntFlags 0x0810 +#define DErrorFlags 0x0838 +#define DTestRegister 0x0848 +#define DFIFODis 0x0868 + + + +/********************************** + * GLINT Gamma Region 0 Registers * + **********************************/ + +/* Control Status Registers */ +#define GInFIFOSpace 0x0018 +#define GDMAAddress 0x0028 +#define GDMACount 0x0030 +#define GDMAControl 0x0060 +#define GOutDMA 0x0080 +#define GOutDMACount 0x0088 +#define GResetStatus 0x0800 +#define GIntEnable 0x0808 +#define GIntFlags 0x0810 +#define GErrorFlags 0x0838 +#define GTestRegister 0x0848 +#define GFIFODis 0x0868 + +#define GChipConfig 0x0870 +#define GChipAGPCapable 1 << 0 +#define GChipAGPSideband 1 << 1 +#define GChipMultiGLINTApMask 3 << 19 +#define GChipMultiGLINTAp_0M 0 << 19 +#define GChipMultiGLINTAp_16M 1 << 19 +#define GChipMultiGLINTAp_32M 2 << 19 +#define GChipMultiGLINTAp_64M 3 << 19 + +#define GCSRAperture 0x0878 +#define GCSRSecondaryGLINTMapEn 1 << 0 +#define GCSRBitSwap 1 << 1 + +#define GPageTableAddr 0x0c00 +#define GPageTableLength 0x0c08 +#define GDelayTimer 0x0c38 +#define GCommandMode 0x0c40 +#define GCommandIntEnable 0x0c48 +#define GCommandIntFlags 0x0c50 +#define GCommandErrorFlags 0x0c58 +#define GCommandStatus 0x0c60 +#define GCommandFaultingAddr 0x0c68 +#define GVertexFaultingAddr 0x0c70 +#define GWriteFaultingAddr 0x0c88 +#define GFeedbackSelectCount 0x0c98 +#define GGammaProcessorMode 0x0cb8 +#define GVGAShadow 0x0d00 +#define GMultGLINTAperture 0x0d08 +#define GMultGLINT1 0x0d10 +#define GMultGLINT2 0x0d18 + +/************************ + * GLINT Core Registers * + ************************/ + +#define GLINT_TAG(major,offset) (((major) << 7) | ((offset) << 3)) +#define GLINT_TAG_ADDR(major,offset) (0x8000 | GLINT_TAG((major),(offset))) + +#define UNIT_DISABLE 0 +#define UNIT_ENABLE 1 + +#define StartXDom GLINT_TAG_ADDR(0x00,0x00) +#define dXDom GLINT_TAG_ADDR(0x00,0x01) +#define StartXSub GLINT_TAG_ADDR(0x00,0x02) +#define dXSub GLINT_TAG_ADDR(0x00,0x03) +#define StartY GLINT_TAG_ADDR(0x00,0x04) +#define dY GLINT_TAG_ADDR(0x00,0x05) +#define GLINTCount GLINT_TAG_ADDR(0x00,0x06) +#define Render GLINT_TAG_ADDR(0x00,0x07) +# define AreaStippleEnable 0x00001 +# define LineStippleEnable 0x00002 +# define ResetLineStipple 0x00004 +# define FastFillEnable 0x00008 +# define PrimitiveLine 0 +# define PrimitiveTrapezoid 0x00040 +# define PrimitivePoint 0x00080 +# define PrimitiveRectangle 0x000C0 +# define AntialiasEnable 0x00100 +# define AntialiasingQuality 0x00200 +# define UsePointTable 0x00400 +# define SyncOnBitMask 0x00800 +# define SyncOnHostData 0x01000 +# define TextureEnable 0x02000 +# define FogEnable 0x04000 +# define CoverageEnable 0x08000 +# define SubPixelCorrectionEnable 0x10000 +# define SpanOperation 0x40000 +# define XPositive 1<<21 +# define YPositive 1<<22 + + +#define ContinueNewLine GLINT_TAG_ADDR(0x00,0x08) +#define ContinueNewDom GLINT_TAG_ADDR(0x00,0x09) +#define ContinueNewSub GLINT_TAG_ADDR(0x00,0x0a) +#define Continue GLINT_TAG_ADDR(0x00,0x0b) +#define FlushSpan GLINT_TAG_ADDR(0x00,0x0c) +#define BitMaskPattern GLINT_TAG_ADDR(0x00,0x0d) + +#define PointTable0 GLINT_TAG_ADDR(0x01,0x00) +#define PointTable1 GLINT_TAG_ADDR(0x01,0x01) +#define PointTable2 GLINT_TAG_ADDR(0x01,0x02) +#define PointTable3 GLINT_TAG_ADDR(0x01,0x03) +#define RasterizerMode GLINT_TAG_ADDR(0x01,0x04) +#define RMMultiGLINT 1<<17 +#define BitMaskPackingEachScanline 1<<9 +#define ForceBackgroundColor 1<<6 +#define InvertBitMask 1<<1 +#define YLimits GLINT_TAG_ADDR(0x01,0x05) +#define ScanLineOwnership GLINT_TAG_ADDR(0x01,0x06) +#define WaitForCompletion GLINT_TAG_ADDR(0x01,0x07) +#define PixelSize GLINT_TAG_ADDR(0x01,0x08) +#define XLimits GLINT_TAG_ADDR(0x01,0x09) /* PM only */ + +#define RectangleOrigin GLINT_TAG_ADDR(0x01,0x0A) /* PM2 only */ +#define RectangleSize GLINT_TAG_ADDR(0x01,0x0B) /* PM2 only */ + +#define PackedDataLimits GLINT_TAG_ADDR(0x02,0x0a) /* PM only */ + +#define ScissorMode GLINT_TAG_ADDR(0x03,0x00) +# define SCI_USER 0x01 +# define SCI_SCREEN 0x02 +# define SCI_USERANDSCREEN 0x03 + +#define ScissorMinXY GLINT_TAG_ADDR(0x03,0x01) +#define ScissorMaxXY GLINT_TAG_ADDR(0x03,0x02) +#define ScreenSize GLINT_TAG_ADDR(0x03,0x03) +#define AreaStippleMode GLINT_TAG_ADDR(0x03,0x04) + /* 0: */ + /* NoMirrorY */ + /* NoMirrorX */ + /* NoInvertPattern */ + /* YAddress_1bit */ + /* XAddress_1bit */ + /* UNIT_DISABLE */ + +# define ASM_XAddress_2bit 1 << 1 +# define ASM_XAddress_3bit 2 << 1 +# define ASM_XAddress_4bit 3 << 1 +# define ASM_XAddress_5bit 4 << 1 +# define ASM_YAddress_2bit 1 << 4 +# define ASM_YAddress_3bit 2 << 4 +# define ASM_YAddress_4bit 3 << 4 +# define ASM_YAddress_5bit 4 << 4 +# define ASM_InvertPattern 1 << 17 +# define ASM_MirrorX 1 << 18 +# define ASM_MirrorY 1 << 19 + +#define LineStippleMode GLINT_TAG_ADDR(0x03,0x05) +#define LoadLineStippleCounters GLINT_TAG_ADDR(0x03,0x06) +#define UpdateLineStippleCounters GLINT_TAG_ADDR(0x03,0x07) +#define SaveLineStippleState GLINT_TAG_ADDR(0x03,0x08) +#define WindowOrigin GLINT_TAG_ADDR(0x03,0x09) + +#define AreaStipplePattern0 GLINT_TAG_ADDR(0x04,0x00) +#define AreaStipplePattern1 GLINT_TAG_ADDR(0x04,0x01) +#define AreaStipplePattern2 GLINT_TAG_ADDR(0x04,0x02) +#define AreaStipplePattern3 GLINT_TAG_ADDR(0x04,0x03) +#define AreaStipplePattern4 GLINT_TAG_ADDR(0x04,0x04) +#define AreaStipplePattern5 GLINT_TAG_ADDR(0x04,0x05) +#define AreaStipplePattern6 GLINT_TAG_ADDR(0x04,0x06) +#define AreaStipplePattern7 GLINT_TAG_ADDR(0x04,0x07) + +#define TextureAddressMode GLINT_TAG_ADDR(0x07,0x00) +#define SStart GLINT_TAG_ADDR(0x07,0x01) +#define dSdx GLINT_TAG_ADDR(0x07,0x02) +#define dSdyDom GLINT_TAG_ADDR(0x07,0x03) +#define TStart GLINT_TAG_ADDR(0x07,0x04) +#define dTdx GLINT_TAG_ADDR(0x07,0x05) +#define dTdyDom GLINT_TAG_ADDR(0x07,0x06) +#define QStart GLINT_TAG_ADDR(0x07,0x07) +#define dQdx GLINT_TAG_ADDR(0x07,0x08) +#define dQdyDom GLINT_TAG_ADDR(0x07,0x09) +#define LOD GLINT_TAG_ADDR(0x07,0x0A) +#define dSdy GLINT_TAG_ADDR(0x07,0x0B) +#define dTdy GLINT_TAG_ADDR(0x07,0x0C) +#define dQdy GLINT_TAG_ADDR(0x07,0x0D) + +#define TextureReadMode GLINT_TAG_ADDR(0x09,0x00) +#define TextureFormat GLINT_TAG_ADDR(0x09,0x01) +# define Texture_4_Components 3 << 3 +# define Texture_Texel 0 + +#define TextureCacheControl GLINT_TAG_ADDR(0x09,0x02) +# define TextureCacheControlEnable 2 +# define TextureCacheControlInvalidate 1 + +#define GLINTBorderColor GLINT_TAG_ADDR(0x09,0x05) + +#define TexelLUTIndex GLINT_TAG_ADDR(0x09,0x08) +#define TexelLUTData GLINT_TAG_ADDR(0x09,0x09) +#define TexelLUTAddress GLINT_TAG_ADDR(0x09,0x0A) +#define TexelLUTTransfer GLINT_TAG_ADDR(0x09,0x0B) +#define TextureFilterMode GLINT_TAG_ADDR(0x09,0x0C) +#define TextureChromaUpper GLINT_TAG_ADDR(0x09,0x0D) +#define TextureChromaLower GLINT_TAG_ADDR(0x09,0x0E) + +#define TxBaseAddr0 GLINT_TAG_ADDR(0x0A,0x00) +#define TxBaseAddr1 GLINT_TAG_ADDR(0x0A,0x01) +#define TxBaseAddr2 GLINT_TAG_ADDR(0x0A,0x02) +#define TxBaseAddr3 GLINT_TAG_ADDR(0x0A,0x03) +#define TxBaseAddr4 GLINT_TAG_ADDR(0x0A,0x04) +#define TxBaseAddr5 GLINT_TAG_ADDR(0x0A,0x05) +#define TxBaseAddr6 GLINT_TAG_ADDR(0x0A,0x06) +#define TxBaseAddr7 GLINT_TAG_ADDR(0x0A,0x07) +#define TxBaseAddr8 GLINT_TAG_ADDR(0x0A,0x08) +#define TxBaseAddr9 GLINT_TAG_ADDR(0x0A,0x09) +#define TxBaseAddr10 GLINT_TAG_ADDR(0x0A,0x0A) +#define TxBaseAddr11 GLINT_TAG_ADDR(0x0A,0x0B) + +#define PMTextureBaseAddress GLINT_TAG_ADDR(0x0b,0x00) +#define PMTextureMapFormat GLINT_TAG_ADDR(0x0b,0x01) +#define PMTextureDataFormat GLINT_TAG_ADDR(0x0b,0x02) + +#define Texel0 GLINT_TAG_ADDR(0x0c,0x00) +#define Texel1 GLINT_TAG_ADDR(0x0c,0x01) +#define Texel2 GLINT_TAG_ADDR(0x0c,0x02) +#define Texel3 GLINT_TAG_ADDR(0x0c,0x03) +#define Texel4 GLINT_TAG_ADDR(0x0c,0x04) +#define Texel5 GLINT_TAG_ADDR(0x0c,0x05) +#define Texel6 GLINT_TAG_ADDR(0x0c,0x06) +#define Texel7 GLINT_TAG_ADDR(0x0c,0x07) +#define Interp0 GLINT_TAG_ADDR(0x0c,0x08) +#define Interp1 GLINT_TAG_ADDR(0x0c,0x09) +#define Interp2 GLINT_TAG_ADDR(0x0c,0x0a) +#define Interp3 GLINT_TAG_ADDR(0x0c,0x0b) +#define Interp4 GLINT_TAG_ADDR(0x0c,0x0c) +#define TextureFilter GLINT_TAG_ADDR(0x0c,0x0d) +#define PMTextureReadMode GLINT_TAG_ADDR(0x0c,0x0e) +#define TexelLUTMode GLINT_TAG_ADDR(0x0c,0x0f) + +#define TextureColorMode GLINT_TAG_ADDR(0x0d,0x00) +# define TextureTypeOpenGL 0 +# define TextureTypeApple 1 << 4 +# define TextureKsDDA 1 << 5 /* only Apple-Mode */ +# define TextureKdDDA 1 << 6 /* only Apple-Mode */ + +#define TextureEnvColor GLINT_TAG_ADDR(0x0d,0x01) +#define FogMode GLINT_TAG_ADDR(0x0d,0x02) + /* 0: */ + /* FOG RGBA */ + /* UNIT_DISABLE */ + +# define FOG_CI 0x0002 + +#define FogColor GLINT_TAG_ADDR(0x0d,0x03) +#define FStart GLINT_TAG_ADDR(0x0d,0x04) +#define dFdx GLINT_TAG_ADDR(0x0d,0x05) +#define dFdyDom GLINT_TAG_ADDR(0x0d,0x06) +#define KsStart GLINT_TAG_ADDR(0x0d,0x09) +#define dKsdx GLINT_TAG_ADDR(0x0d,0x0a) +#define dKsdyDom GLINT_TAG_ADDR(0x0d,0x0b) +#define KdStart GLINT_TAG_ADDR(0x0d,0x0c) +#define dKdStart GLINT_TAG_ADDR(0x0d,0x0d) +#define dKddyDom GLINT_TAG_ADDR(0x0d,0x0e) + +#define RStart GLINT_TAG_ADDR(0x0f,0x00) +#define dRdx GLINT_TAG_ADDR(0x0f,0x01) +#define dRdyDom GLINT_TAG_ADDR(0x0f,0x02) +#define GStart GLINT_TAG_ADDR(0x0f,0x03) +#define dGdx GLINT_TAG_ADDR(0x0f,0x04) +#define dGdyDom GLINT_TAG_ADDR(0x0f,0x05) +#define BStart GLINT_TAG_ADDR(0x0f,0x06) +#define dBdx GLINT_TAG_ADDR(0x0f,0x07) +#define dBdyDom GLINT_TAG_ADDR(0x0f,0x08) +#define AStart GLINT_TAG_ADDR(0x0f,0x09) +#define dAdx GLINT_TAG_ADDR(0x0f,0x0a) +#define dAdyDom GLINT_TAG_ADDR(0x0f,0x0b) +#define ColorDDAMode GLINT_TAG_ADDR(0x0f,0x0c) + /* 0: */ +# define CDDA_FlatShading 0 + /* UNIT_DISABLE */ +# define CDDA_GouraudShading 0x0002 + + +#define ConstantColor GLINT_TAG_ADDR(0x0f,0x0d) +#define GLINTColor GLINT_TAG_ADDR(0x0f,0x0e) +#define AlphaTestMode GLINT_TAG_ADDR(0x10,0x00) +#define AntialiasMode GLINT_TAG_ADDR(0x10,0x01) +#define AlphaBlendMode GLINT_TAG_ADDR(0x10,0x02) + /* 0: */ + /* SrcZERO */ + /* DstZERO */ + /* ColorFormat8888 */ + /* AlphaBuffer present */ + /* ColorOrderBGR */ + /* TypeOpenGL */ + /* DstFBData */ + /* UNIT_DISABLE */ + +# define ABM_SrcONE 1 << 1 +# define ABM_SrcDST_COLOR 2 << 1 +# define ABM_SrcONE_MINUS_DST_COLOR 3 << 1 +# define ABM_SrcSRC_ALPHA 4 << 1 +# define ABM_SrcONE_MINUS_SRC_ALPHA 5 << 1 +# define ABM_SrcDST_ALPHA 6 << 1 +# define ABM_SrcONE_MINUS_DST_ALPHA 7 << 1 +# define ABM_SrcSRC_ALPHA_SATURATE 8 << 1 +# define ABM_DstONE 1 << 5 +# define ABM_DstSRC_COLOR 2 << 5 +# define ABM_DstONE_MINUS_SRC_COLOR 3 << 5 +# define ABM_DstSRC_ALPHA 4 << 5 +# define ABM_DstONE_MINUS_SRC_ALPHA 5 << 5 +# define ABM_DstDST_ALPHA 6 << 5 +# define ABM_DstONE_MINUS_DST_ALPHA 7 << 5 +# define ABM_ColorFormat5555 1 << 8 +# define ABM_ColorFormat4444 2 << 8 +# define ABM_ColorFormat4444_Front 3 << 8 +# define ABM_ColorFormat4444_Back 4 << 8 +# define ABM_ColorFormat332_Front 5 << 8 +# define ABM_ColorFormat332_Back 6 << 8 +# define ABM_ColorFormat121_Front 7 << 8 +# define ABM_ColorFormat121_Back 8 << 8 +# define ABM_ColorFormat555_Back 13 << 8 +# define ABM_ColorFormat_CI8 14 << 8 +# define ABM_ColorFormat_CI4 15 << 8 +# define ABM_NoAlphaBuffer 0x1000 +# define ABM_ColorOrderRGB 0x2000 +# define ABM_TypeQuickDraw3D 0x4000 +# define ABM_DstFBSourceData 0x8000 + +#define DitherMode GLINT_TAG_ADDR(0x10,0x03) + /* 0: */ + /* ColorOrder BGR */ + /* AlphaDitherDefault */ + /* ColorFormat8888 */ + /* TruncateMode */ + /* DitherDisable */ + /* UNIT_DISABLE */ + +# define DTM_DitherEnable 1 << 1 +# define DTM_ColorFormat5555 1 << 2 +# define DTM_ColorFormat4444 2 << 2 +# define DTM_ColorFormat4444_Front 3 << 2 +# define DTM_ColorFormat4444_Back 4 << 2 +# define DTM_ColorFormat332_Front 5 << 2 +# define DTM_ColorFormat332_Back 6 << 2 +# define DTM_ColorFormat121_Front 7 << 2 +# define DTM_ColorFormat121_Back 8 << 2 +# define DTM_ColorFormat555_Back 13 << 2 +# define DTM_ColorFormat_CI8 14 << 2 +# define DTM_ColorFormat_CI4 15 << 2 +# define DTM_ColorOrderRGB 1 << 10 +# define DTM_NoAlphaDither 1 << 14 +# define DTM_RoundMode 1 << 15 + +#define FBSoftwareWriteMask GLINT_TAG_ADDR(0x10,0x04) +#define LogicalOpMode GLINT_TAG_ADDR(0x10,0x05) +# define Use_ConstantFBWriteData 0x40 + + +#define FBWriteData GLINT_TAG_ADDR(0x10,0x06) +#define RouterMode GLINT_TAG_ADDR(0x10,0x08) +# define ROUTER_Depth_Texture 1 +# define ROUTER_Texture_Depth 0 + + +#define LBReadMode GLINT_TAG_ADDR(0x11,0x00) + /* 0: */ + /* SrcNoRead */ + /* DstNoRead */ + /* DataLBDefault */ + /* WinTopLeft */ + /* NoPatch */ + /* ScanlineInterval1 */ + +# define LBRM_SrcEnable 1 << 9 +# define LBRM_DstEnable 1 << 10 +# define LBRM_DataLBStencil 1 << 16 +# define LBRM_DataLBDepth 2 << 16 +# define LBRM_WinBottomLeft 1 << 18 +# define LBRM_DoPatch 1 << 19 + +# define LBRM_ScanlineInt2 1 << 20 +# define LBRM_ScanlineInt4 2 << 20 +# define LBRM_ScanlineInt8 3 << 20 + + +#define LBReadFormat GLINT_TAG_ADDR(0x11,0x01) +# define LBRF_DepthWidth15 0x03 /* only permedia */ +# define LBRF_DepthWidth16 0x00 +# define LBRF_DepthWidth24 0x01 +# define LBRF_DepthWidth32 0x02 + +# define LBRF_StencilWidth0 (0 << 2) +# define LBRF_StencilWidth4 (1 << 2) +# define LBRF_StencilWidth8 (2 << 2) + +# define LBRF_StencilPos16 (0 << 4) +# define LBRF_StencilPos20 (1 << 4) +# define LBRF_StencilPos24 (2 << 4) +# define LBRF_StencilPos28 (3 << 4) +# define LBRF_StencilPos32 (4 << 4) + +# define LBRF_FrameCount0 (0 << 7) +# define LBRF_FrameCount4 (1 << 7) +# define LBRF_FrameCount8 (2 << 7) + +# define LBRF_FrameCountPos16 (0 << 9) +# define LBRF_FrameCountPos20 (1 << 9) +# define LBRF_FrameCountPos24 (2 << 9) +# define LBRF_FrameCountPos28 (3 << 9) +# define LBRF_FrameCountPos32 (4 << 9) +# define LBRF_FrameCountPos36 (5 << 9) +# define LBRF_FrameCountPos40 (6 << 9) + +# define LBRF_GIDWidth0 (0 << 12) +# define LBRF_GIDWidth4 (1 << 12) + +# define LBRF_GIDPos16 (0 << 13) +# define LBRF_GIDPos20 (1 << 13) +# define LBRF_GIDPos24 (2 << 13) +# define LBRF_GIDPos28 (3 << 13) +# define LBRF_GIDPos32 (4 << 13) +# define LBRF_GIDPos36 (5 << 13) +# define LBRF_GIDPos40 (6 << 13) +# define LBRF_GIDPos44 (7 << 13) +# define LBRF_GIDPos48 (8 << 13) + +# define LBRF_Compact32 (1 << 17) + + + +#define LBSourceOffset GLINT_TAG_ADDR(0x11,0x02) +#define LBStencil GLINT_TAG_ADDR(0x11,0x05) +#define LBDepth GLINT_TAG_ADDR(0x11,0x06) +#define LBWindowBase GLINT_TAG_ADDR(0x11,0x07) +#define LBWriteMode GLINT_TAG_ADDR(0x11,0x08) +# define LBWM_WriteEnable 0x1 +# define LBWM_UpLoad_LBDepth 0x2 +# define LBWM_UpLoad_LBStencil 0x4 + +#define LBWriteFormat GLINT_TAG_ADDR(0x11,0x09) + + +#define TextureData GLINT_TAG_ADDR(0x11,0x0d) +#define TextureDownloadOffset GLINT_TAG_ADDR(0x11,0x0e) +#define LBWindowOffset GLINT_TAG_ADDR(0x11,0x0f) + +#define GLINTWindow GLINT_TAG_ADDR(0x13,0x00) +# define GWIN_UnitEnable (1 << 0) +# define GWIN_ForceLBUpdate (1 << 3) +# define GWIN_LBUpdateSourceREG (1 << 4) +# define GWIN_LBUpdateSourceLB (0 << 4) +# define GWIN_StencilFCP (1 << 17) +# define GWIN_DepthFCP (1 << 18) +# define GWIN_OverrideWriteFilter (1 << 19) + + /* ??? is this needed, set by permedia (2) modules */ +# define GWIN_DisableLBUpdate 0x40000 + +#define StencilMode GLINT_TAG_ADDR(0x13,0x01) +#define StencilData GLINT_TAG_ADDR(0x13,0x02) +#define GLINTStencil GLINT_TAG_ADDR(0x13,0x03) +#define DepthMode GLINT_TAG_ADDR(0x13,0x04) + /* 0: */ + /* WriteDisable */ + /* SrcCompFragment */ + /* CompFuncNEVER */ + /* UNIT_DISABLE */ + +# define DPM_WriteEnable 1 << 1 +# define DPM_SrcCompLBData 1 << 2 +# define DPM_SrcCompDregister 2 << 2 +# define DPM_SrcCompLBSourceData 3 << 2 +# define DPM_CompFuncLESS 1 << 4 +# define DPM_CompFuncEQUAL 2 << 4 +# define DPM_CompFuncLESS_OR_EQ 3 << 4 +# define DPM_CompFuncGREATER 4 << 4 +# define DPM_CompFuncNOT_EQ 5 << 4 +# define DPM_CompFuncGREATER_OR_EQ 6 << 4 +# define DPM_CompFuncALWAYS 7 << 4 + +#define GLINTDepth GLINT_TAG_ADDR(0x13,0x05) +#define ZStartU GLINT_TAG_ADDR(0x13,0x06) +#define ZStartL GLINT_TAG_ADDR(0x13,0x07) +#define dZdxU GLINT_TAG_ADDR(0x13,0x08) +#define dZdxL GLINT_TAG_ADDR(0x13,0x09) +#define dZdyDomU GLINT_TAG_ADDR(0x13,0x0a) +#define dZdyDomL GLINT_TAG_ADDR(0x13,0x0b) +#define FastClearDepth GLINT_TAG_ADDR(0x13,0x0c) + +#define FBReadMode GLINT_TAG_ADDR(0x15,0x00) + /* 0: */ + /* SrcNoRead */ + /* DstNoRead */ + /* DataFBDefault */ + /* WinTopLeft */ + /* ScanlineInterval1 */ + +# define FBRM_SrcEnable 1 << 9 +# define FBRM_DstEnable 1 << 10 +# define FBRM_DataFBColor 1 << 15 +# define FBRM_WinBottomLeft 1 << 16 +# define FBRM_Packed 1 << 19 +# define FBRM_ScanlineInt2 1 << 23 +# define FBRM_ScanlineInt4 2 << 23 +# define FBRM_ScanlineInt8 3 << 23 + + +#define FBSourceOffset GLINT_TAG_ADDR(0x15,0x01) +#define FBPixelOffset GLINT_TAG_ADDR(0x15,0x02) +#define FBColor GLINT_TAG_ADDR(0x15,0x03) +#define FBData GLINT_TAG_ADDR(0x15,0x04) +#define FBSourceData GLINT_TAG_ADDR(0x15,0x05) + +#define FBWindowBase GLINT_TAG_ADDR(0x15,0x06) +#define FBWriteMode GLINT_TAG_ADDR(0x15,0x07) + /* 0: */ + /* FBWM_NoColorUpload */ + /* FBWM_WriteDisable */ +# define FBWM_WriteEnable 1 +# define FBWM_UploadColor 1 << 3 +/* Permedia3 extensions */ +# define FBWM_Enable0 1 << 12 + +#define FBHardwareWriteMask GLINT_TAG_ADDR(0x15,0x08) +#define FBBlockColor GLINT_TAG_ADDR(0x15,0x09) +#define FBReadPixel GLINT_TAG_ADDR(0x15,0x0a) /* PM */ +#define PatternRamMode GLINT_TAG_ADDR(0x15,0x0f) + +#define PatternRamData0 GLINT_TAG_ADDR(0x16,0x00) +#define PatternRamData1 GLINT_TAG_ADDR(0x16,0x01) +#define PatternRamData2 GLINT_TAG_ADDR(0x16,0x02) +#define PatternRamData3 GLINT_TAG_ADDR(0x16,0x03) +#define PatternRamData4 GLINT_TAG_ADDR(0x16,0x04) +#define PatternRamData5 GLINT_TAG_ADDR(0x16,0x05) +#define PatternRamData6 GLINT_TAG_ADDR(0x16,0x06) +#define PatternRamData7 GLINT_TAG_ADDR(0x16,0x07) + +#define FilterMode GLINT_TAG_ADDR(0x18,0x00) + /* 0: */ + /* CullDepthTags */ + /* CullDepthData */ + /* CullStencilTags */ + /* CullStencilData */ + /* CullColorTag */ + /* CullColorData */ + /* CullSyncTag */ + /* CullSyncData */ + /* CullStatisticTag */ + /* CullStatisticData */ + +# define FM_PassDepthTags 0x0010 +# define FM_PassDepthData 0x0020 +# define FM_PassStencilTags 0x0040 +# define FM_PassStencilData 0x0080 +# define FM_PassColorTag 0x0100 +# define FM_PassColorData 0x0200 +# define FM_PassSyncTag 0x0400 +# define FM_PassSyncData 0x0800 +# define FM_PassStatisticTag 0x1000 +# define FM_PassStatisticData 0x2000 + +#define Sync_tag 0x0188 + +#define StatisticMode GLINT_TAG_ADDR(0x18,0x01) +#define MinRegion GLINT_TAG_ADDR(0x18,0x02) +#define MaxRegion GLINT_TAG_ADDR(0x18,0x03) +#define ResetPickResult GLINT_TAG_ADDR(0x18,0x04) +#define MitHitRegion GLINT_TAG_ADDR(0x18,0x05) +#define MaxHitRegion GLINT_TAG_ADDR(0x18,0x06) +#define PickResult GLINT_TAG_ADDR(0x18,0x07) +#define GlintSync GLINT_TAG_ADDR(0x18,0x08) + +#define FBBlockColorU GLINT_TAG_ADDR(0x18,0x0d) +#define FBBlockColorL GLINT_TAG_ADDR(0x18,0x0e) +#define SuspendUntilFrameBlank GLINT_TAG_ADDR(0x18,0x0f) + +#define KsRStart GLINT_TAG_ADDR(0x19,0x00) +#define dKsRdx GLINT_TAG_ADDR(0x19,0x01) +#define dKsRdyDom GLINT_TAG_ADDR(0x19,0x02) +#define KsGStart GLINT_TAG_ADDR(0x19,0x03) +#define dKsGdx GLINT_TAG_ADDR(0x19,0x04) +#define dKsGdyDom GLINT_TAG_ADDR(0x19,0x05) +#define KsBStart GLINT_TAG_ADDR(0x19,0x06) +#define dKsBdx GLINT_TAG_ADDR(0x19,0x07) +#define dKsBdyDom GLINT_TAG_ADDR(0x19,0x08) + +#define KdRStart GLINT_TAG_ADDR(0x1A,0x00) +#define dKdRdx GLINT_TAG_ADDR(0x1A,0x01) +#define dKdRdyDom GLINT_TAG_ADDR(0x1A,0x02) +#define KdGStart GLINT_TAG_ADDR(0x1A,0x03) +#define dKdGdx GLINT_TAG_ADDR(0x1A,0x04) +#define dKdGdyDom GLINT_TAG_ADDR(0x1A,0x05) +#define KdBStart GLINT_TAG_ADDR(0x1A,0x06) +#define dKdBdx GLINT_TAG_ADDR(0x1A,0x07) +#define dKdBdyDom GLINT_TAG_ADDR(0x1A,0x08) + +#define FBSourceBase GLINT_TAG_ADDR(0x1B,0x00) +#define FBSourceDelta GLINT_TAG_ADDR(0x1B,0x01) +#define Config GLINT_TAG_ADDR(0x1B,0x02) +#define CFBRM_SrcEnable 1<<0 +#define CFBRM_DstEnable 1<<1 +#define CFBRM_Packed 1<<2 +#define CWM_Enable 1<<3 +#define CCDDA_Enable 1<<4 +#define CLogOp_Enable 1<<5 +#define ContextDump GLINT_TAG_ADDR(0x1B,0x08) +#define ContextRestore GLINT_TAG_ADDR(0x1B,0x09) +#define ContextData GLINT_TAG_ADDR(0x1B,0x0a) + +#define TexelLUT0 GLINT_TAG_ADDR(0x1D,0x00) +#define TexelLUT1 GLINT_TAG_ADDR(0x1D,0x01) +#define TexelLUT2 GLINT_TAG_ADDR(0x1D,0x02) +#define TexelLUT3 GLINT_TAG_ADDR(0x1D,0x03) +#define TexelLUT4 GLINT_TAG_ADDR(0x1D,0x04) +#define TexelLUT5 GLINT_TAG_ADDR(0x1D,0x05) +#define TexelLUT6 GLINT_TAG_ADDR(0x1D,0x06) +#define TexelLUT7 GLINT_TAG_ADDR(0x1D,0x07) +#define TexelLUT8 GLINT_TAG_ADDR(0x1D,0x08) +#define TexelLUT9 GLINT_TAG_ADDR(0x1D,0x09) +#define TexelLUT10 GLINT_TAG_ADDR(0x1D,0x0A) +#define TexelLUT11 GLINT_TAG_ADDR(0x1D,0x0B) +#define TexelLUT12 GLINT_TAG_ADDR(0x1D,0x0C) +#define TexelLUT13 GLINT_TAG_ADDR(0x1D,0x0D) +#define TexelLUT14 GLINT_TAG_ADDR(0x1D,0x0E) +#define TexelLUT15 GLINT_TAG_ADDR(0x1D,0x0F) + +#define YUVMode GLINT_TAG_ADDR(0x1E,0x00) +#define ChromaUpper GLINT_TAG_ADDR(0x1E,0x01) +#define ChromaLower GLINT_TAG_ADDR(0x1E,0x02) +#define ChromaTestMode GLINT_TAG_ADDR(0x1E,0x03) + + +/****************************** + * GLINT Delta Core Registers * + ******************************/ + +#define V0FixedTag GLINT_TAG_ADDR(0x20,0x00) +#define V1FixedTag GLINT_TAG_ADDR(0x21,0x00) +#define V2FixedTag GLINT_TAG_ADDR(0x22,0x00) +#define V0FloatTag GLINT_TAG_ADDR(0x23,0x00) +#define V1FloatTag GLINT_TAG_ADDR(0x24,0x00) +#define V2FloatTag GLINT_TAG_ADDR(0x25,0x00) + +#define VPAR_s 0x00 +#define VPAR_t 0x08 +#define VPAR_q 0x10 +#define VPAR_Ks 0x18 +#define VPAR_Kd 0x20 + +/* have changed colors in ramdac ! +#define VPAR_R 0x28 +#define VPAR_G 0x30 +#define VPAR_B 0x38 +#define VPAR_A 0x40 +*/ +#define VPAR_B 0x28 +#define VPAR_G 0x30 +#define VPAR_R 0x38 +#define VPAR_A 0x40 + +#define VPAR_f 0x48 + +#define VPAR_x 0x50 +#define VPAR_y 0x58 +#define VPAR_z 0x60 + +#define DeltaModeTag GLINT_TAG_ADDR(0x26,0x00) + /* 0: */ + /* GLINT_300SX */ + + /* DeltaMode Register Bit Field Assignments */ +# define DM_GLINT_300SX 0x0000 +# define DM_GLINT_500TX 0x0001 +# define DM_PERMEDIA 0x0002 +# define DM_Depth_16BPP (1 << 2) +# define DM_Depth_24BPP (2 << 2) +# define DM_Depth_32BPP (3 << 2) +# define DM_FogEnable 0x0010 +# define DM_TextureEnable 0x0020 +# define DM_SmoothShadingEnable 0x0040 +# define DM_DepthEnable 0x0080 +# define DM_SpecularTextureEnable 0x0100 +# define DM_DiffuseTextureEnable 0x0200 +# define DM_SubPixelCorrectionEnable 0x0400 +# define DM_DiamondExit 0x0800 +# define DM_NoDraw 0x1000 +# define DM_ClampEnable 0x2000 +# define DM_ClampedTexParMode 0x4000 +# define DM_NormalizedTexParMode 0xC000 + + +# define DDCMD_AreaStrippleEnable 0x0001 +# define DDCMD_LineStrippleEnable 0x0002 +# define DDCMD_ResetLineStripple 1 << 2 +# define DDCMD_FastFillEnable 1 << 3 + /* 2 Bits reserved */ +# define DDCMD_PrimitiveType_Point 2 << 6 +# define DDCMD_PrimitiveType_Line 0 << 6 +# define DDCMD_PrimitiveType_Trapezoid 1 << 6 +# define DDCMD_AntialiasEnable 1 << 8 +# define DDCMD_AntialiasingQuality 1 << 9 +# define DDCMD_UsePointTable 1 << 10 +# define DDCMD_SyncOnBitMask 1 << 11 +# define DDCMD_SyncOnHostDate 1 << 12 +# define DDCMD_TextureEnable 1 << 13 +# define DDCMD_FogEnable 1 << 14 +# define DDCMD_CoverageEnable 1 << 15 +# define DDCMD_SubPixelCorrectionEnable 1 << 16 + + + +#define DrawTriangle GLINT_TAG_ADDR(0x26,0x01) +#define RepeatTriangle GLINT_TAG_ADDR(0x26,0x02) +#define DrawLine01 GLINT_TAG_ADDR(0x26,0x03) +#define DrawLine10 GLINT_TAG_ADDR(0x26,0x04) +#define RepeatLine GLINT_TAG_ADDR(0x26,0x05) +#define BroadcastMask GLINT_TAG_ADDR(0x26,0x0F) + +/* Permedia 3 - Accelerator Extensions */ +#define FillRectanglePosition 0x8348 +#define FillRender2D 0x8350 +#define FBDstReadBufAddr0 0xAE80 +#define FBDstReadBufOffset0 0xAEA0 +#define FBDstReadBufWidth0 0xAEC0 +#define FBDstReadMode 0xAEE0 +#define FBDRM_Enable0 1<<8 +#define FBDRM_Blocking 1<<24 +#define FBDstReadEnables 0xAEE8 +#define FBSrcReadMode 0xAF00 +#define FBSRM_Blocking 1<<11 +#define FBSrcReadBufAddr 0xAF08 +#define FBSrcReadBufOffset0 0xAF10 +#define FBSrcReadBufWidth 0xAF18 +#define FBWriteBufAddr0 0xB000 +#define FBWriteBufOffset0 0xB020 +#define FBWriteBufWidth0 0xB040 +#define FBBlockColorBack 0xB0A0 +#define ForegroundColor 0xB0C0 +#define BackgroundColor 0xB0C8 +#define RectanglePosition 0xB600 +#define Render2D 0xB640 + +/* Colorformats */ +#define BGR555 1 +#define BGR565 16 +#define CI8 14 +#define CI4 15 + +#ifdef DEBUG +#define GLINT_WRITE_REG(v,r) \ + GLINT_VERB_WRITE_REG(pGlint,v,r,__FILE__,__LINE__) +#define GLINT_READ_REG(r) \ + GLINT_VERB_READ_REG(pGlint,r,__FILE__,__LINE__) +#else + +#define GLINT_WRITE_REG(v,r) \ + MMIO_OUT32(pGlint->IOBase + pGlint->IOOffset,(unsigned long)(r), (v)) +#define GLINT_READ_REG(r) \ + MMIO_IN32(pGlint->IOBase + pGlint->IOOffset,(unsigned long)(r)) + +#endif /* DEBUG */ + +#define GLINT_WAIT(n) \ +do{ \ + if (pGlint->InFifoSpace>=(n)) \ + pGlint->InFifoSpace -= (n); \ + else { \ + int tmp; \ + while((tmp=GLINT_READ_REG(InFIFOSpace))<(n)); \ + /* Clamp value due to bugs in PM3 */ \ + if (tmp > pGlint->FIFOSize) \ + tmp = pGlint->FIFOSize; \ + pGlint->InFifoSpace = tmp - (n); \ + } \ +}while(0) + +#define GLINTDACDelay(x) do { \ + int delay = x; \ + unsigned char tmp; \ + while(delay--){tmp = GLINT_READ_REG(InFIFOSpace);}; \ + } while(0) + +#define GLINT_MASK_WRITE_REG(v,m,r) \ + GLINT_WRITE_REG((GLINT_READ_REG(r)&(m))|(v),r) + +#define GLINT_SLOW_WRITE_REG(v,r) \ +do{ \ + mem_barrier(); \ + GLINT_WAIT(pGlint->FIFOSize); \ + mem_barrier(); \ + GLINT_WRITE_REG(v,r); \ +}while(0) + +#define GLINT_SET_INDEX(index) \ +do{ \ + GLINT_SLOW_WRITE_REG(((index)>>8)&0xff,PM2VDACIndexRegHigh); \ + GLINT_SLOW_WRITE_REG((index)&0xff,PM2VDACIndexRegLow); \ +} while(0) + +#define REPLICATE(r) \ +{ \ + if (pScrn->bitsPerPixel == 16) { \ + r &= 0xFFFF; \ + r |= (r<<16); \ + } else \ + if (pScrn->bitsPerPixel == 8) { \ + r &= 0xFF; \ + r |= (r<<8); \ + r |= (r<<16); \ + } \ +} + +#ifndef XF86DRI +#define LOADROP(rop) \ +{ \ + if (pGlint->ROP != rop) { \ + GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \ + pGlint->ROP = rop; \ + } \ +} +#else +#define LOADROP(rop) \ + { \ + GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \ + pGlint->ROP = rop; \ + } +#endif + +#define CHECKCLIPPING \ +{ \ + if (pGlint->ClippingOn) { \ + pGlint->ClippingOn = FALSE; \ + GLINT_WAIT(1); \ + GLINT_WRITE_REG(0, ScissorMode); \ + } \ +} + +#ifndef XF86DRI +#define DO_PLANEMASK(planemask) \ +{ \ + if (planemask != pGlint->planemask) { \ + pGlint->planemask = planemask; \ + REPLICATE(planemask); \ + GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\ + } \ +} +#else +#define DO_PLANEMASK(planemask) \ + { \ + pGlint->planemask = planemask; \ + REPLICATE(planemask); \ + GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\ + } +#endif + +/* Permedia Save/Restore functions */ + +#define STOREREG(address,value) \ + pReg->glintRegs[address >> 3] = value; + +#define SAVEREG(address) \ + pReg->glintRegs[address >> 3] = GLINT_READ_REG(address); + +#define RESTOREREG(address) \ + GLINT_SLOW_WRITE_REG(pReg->glintRegs[address >> 3], address); + +#define STOREDAC(address,value) \ + pReg->DacRegs[address] = value; + +#define P2VOUT(address) \ + Permedia2vOutIndReg(pScrn, address, 0x00, pReg->DacRegs[address]); + +#define P2VIN(address) \ + pReg->DacRegs[address] = Permedia2vInIndReg(pScrn, address); + +/* RamDac Save/Restore functions, used by external DAC's */ + +#define STORERAMDAC(address,value) \ + ramdacReg->DacRegs[address] = value; + +/* Multi Chip access */ + +#define ACCESSCHIP1() \ + pGlint->IOOffset = 0; + +#define ACCESSCHIP2() \ + pGlint->IOOffset = 0x10000; + +#endif diff --git a/src/glint_shadow.c b/src/glint_shadow.c new file mode 100644 index 0000000..2dfcef8 --- /dev/null +++ b/src/glint_shadow.c @@ -0,0 +1,46 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_shadow.c,v 1.1 1999/11/19 13:54:32 hohndel Exp $ */ + +/* + Copyright (c) 1999, The XFree86 Project Inc. + Code adapted from mga/mga_shadow.c (Mark Vojkovich <markv@valinux.com>) + by Michel Dänzer <michdaen@iiic.ethz.ch> +*/ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "glint.h" +#include "shadowfb.h" +#include "servermd.h" + + + +void +GLINTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pGlint->ShadowPtr + (pbox->y1 * pGlint->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pGlint->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pGlint->ShadowPitch; + } + + pbox++; + } +} diff --git a/src/pm2_accel.c b/src/pm2_accel.c new file mode 100644 index 0000000..583fbc1 --- /dev/null +++ b/src/pm2_accel.c @@ -0,0 +1,1487 @@ +/* + * Copyright 1997-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Mark Vojkovich, <mvojkovi@ucsd.edu> + * Michel Dänzer, <michdaen@iiic.ethz.ch> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + * + * Permedia 2 accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c,v 1.31 2001/10/28 03:33:30 tsi Exp $ */ + +#include "Xarch.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "fb.h" + +#include "glint_regs.h" +#include "glint.h" + +#include "xaalocal.h" /* For replacements */ + +#define DEBUG 0 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("pm2_accel: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("pm2_accel: " str " done\n") +# define TRACE(str) ErrorF("pm2_accel trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +# define TRACE(str) +#endif + +static void Permedia2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void Permedia2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void Permedia2SetupForFillRectSolid24bpp(ScrnInfoPtr pScrn,int color, + int rop, unsigned int planemask); +static void Permedia2SubsequentFillRectSolid24bpp(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void Permedia2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void Permedia2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void Permedia2SubsequentScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int w, int h); +static void Permedia2SetupForScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void Permedia2SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void Permedia2DisableClipping(ScrnInfoPtr pScrn); +static void Permedia2SetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void Permedia2SubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y, + int len, int dir); +static void Permedia2SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void Permedia2WriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int skipleft, + int fg, int bg, int rop,unsigned int planemask); +static void Permedia2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void Permedia2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +static void Permedia2SetupForMono8x8PatternFill24bpp(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void Permedia2SubsequentMono8x8PatternFillRect24bpp(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +static void Permedia2WritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void Permedia2WritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void Permedia2WritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void Permedia2SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void Permedia2SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void Permedia2SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +static void Permedia2LoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h); +static void Permedia2PolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts); +static void Permedia2PolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int nseg, xSegment *pSeg); + +#if X_BYTE_ORDER == X_BIG_ENDIAN +# define STIPPLE_SWAP 1<<18 /* Mirror stipple pattern horizontally */ +#else +# define STIPPLE_SWAP 0 +#endif + +void +Permedia2InitializeEngine(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* Initialize the Accelerator Engine to defaults */ + + TRACE_ENTER("Permedia2InitializeEngine"); + + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); + GLINT_SLOW_WRITE_REG(0, dXSub); + GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); + GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(0x400, FilterMode); + GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap = 1; +#else + pGlint->RasterizerSwap = 0; +#endif + + switch (pScrn->bitsPerPixel) { + case 8: + pGlint->PixelWidth = 0x0; /* 8 Bits */ + pGlint->TexMapFormat = pGlint->pprod; +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap |= 3<<15; /* Swap host data */ +#endif + break; + case 16: + pGlint->PixelWidth = 0x1; /* 16 Bits */ + pGlint->TexMapFormat = pGlint->pprod | 1<<19; +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap |= 2<<15; /* Swap host data */ +#endif + break; + case 24: + pGlint->PixelWidth = 0x4; /* 24 Bits */ + pGlint->TexMapFormat = pGlint->pprod | 2<<19; + break; + case 32: + pGlint->PixelWidth = 0x2; /* 32 Bits */ + pGlint->TexMapFormat = pGlint->pprod | 2<<19; + break; + } + pGlint->ClippingOn = FALSE; + pGlint->startxdom = 0; + pGlint->startxsub = 0; + pGlint->starty = 0; + pGlint->count = 0; + pGlint->dy = 1<<16; + pGlint->dxdom = 0; + pGlint->x = 0; + pGlint->y = 0; + pGlint->h = 0; + pGlint->w = 0; + pGlint->ROP = 0xFF; + GLINT_SLOW_WRITE_REG(pGlint->PixelWidth, FBReadPixel); + GLINT_SLOW_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat); + GLINT_SLOW_WRITE_REG(0, RectangleSize); + GLINT_SLOW_WRITE_REG(0, RectangleOrigin); + GLINT_SLOW_WRITE_REG(0, dXDom); + GLINT_SLOW_WRITE_REG(1<<16, dY); + GLINT_SLOW_WRITE_REG(0, StartXDom); + GLINT_SLOW_WRITE_REG(0, StartXSub); + GLINT_SLOW_WRITE_REG(0, StartY); + GLINT_SLOW_WRITE_REG(0, GLINTCount); + + TRACE_EXIT("Permedia2InitializeEngine"); +} + +Bool +Permedia2AccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + BoxRec AvailFBArea; + + pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + Permedia2InitializeEngine(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + infoPtr->Sync = Permedia2Sync; + + infoPtr->SetClippingRectangle = Permedia2SetClippingRectangle; + infoPtr->DisableClipping = Permedia2DisableClipping; + infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL; + + infoPtr->SolidFillFlags = 0; + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + infoPtr->WriteBitmapFlags = 0; + if (pScrn->bitsPerPixel == 24) { + infoPtr->SetupForSolidFill = + Permedia2SetupForFillRectSolid24bpp; + infoPtr->SubsequentSolidFillRect = + Permedia2SubsequentFillRectSolid24bpp; + } else { + infoPtr->SolidLineFlags = 0; + infoPtr->PolySegmentThinSolidFlags = 0; + infoPtr->PolylinesThinSolidFlags = 0; + infoPtr->SetupForSolidLine = Permedia2SetupForSolidLine; + infoPtr->SubsequentSolidHorVertLine = Permedia2SubsequentHorVertLine; + if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)) + { + infoPtr->SubsequentSolidBresenhamLine = + Permedia2SubsequentSolidBresenhamLine; + } + infoPtr->PolySegmentThinSolid = Permedia2PolySegmentThinSolidWrapper; + infoPtr->PolylinesThinSolid = Permedia2PolylinesThinSolidWrapper; + infoPtr->SetupForSolidFill = Permedia2SetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = Permedia2SubsequentFillRectSolid; + } + + if (pScrn->bitsPerPixel >= 24) { + infoPtr->SetupForScreenToScreenCopy = + Permedia2SetupForScreenToScreenCopy2432bpp; + infoPtr->SubsequentScreenToScreenCopy = + Permedia2SubsequentScreenToScreenCopy2432bpp; + } else { + infoPtr->SetupForScreenToScreenCopy = + Permedia2SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + Permedia2SubsequentScreenToScreenCopy; + } + + infoPtr->Mono8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_SCREEN_ORIGIN; + + if (pScrn->bitsPerPixel == 24) { + infoPtr->SetupForMono8x8PatternFill = + Permedia2SetupForMono8x8PatternFill24bpp; + infoPtr->SubsequentMono8x8PatternFillRect = + Permedia2SubsequentMono8x8PatternFillRect24bpp; + } else { + infoPtr->SetupForMono8x8PatternFill = + Permedia2SetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + Permedia2SubsequentMono8x8PatternFillRect; + } + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_LSBFIRST; + + infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->ScanlineColorExpandBuffers = + pGlint->XAAScanlineColorExpandBuffers; + pGlint->XAAScanlineColorExpandBuffers[0] = + pGlint->IOBase + OutputFIFO + 4; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + Permedia2SetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + Permedia2SubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + Permedia2SubsequentColorExpandScanline; + + infoPtr->WriteBitmap = Permedia2WriteBitmap; + + if (pScrn->bitsPerPixel == 8) { + infoPtr->WritePixmap = Permedia2WritePixmap8bpp; + infoPtr->WritePixmapFlags = NO_GXCOPY; + } else + if (pScrn->bitsPerPixel == 16) { + infoPtr->WritePixmap = Permedia2WritePixmap16bpp; + infoPtr->WritePixmapFlags = NO_GXCOPY; + } else + if (pScrn->bitsPerPixel == 32) + infoPtr->WritePixmap = Permedia2WritePixmap32bpp; + + /* Now fixup if we are 24bpp */ + if (pScrn->bitsPerPixel == 24) { + infoPtr->SolidFillFlags |= NO_PLANEMASK; + infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK; + infoPtr->WriteBitmapFlags |= NO_PLANEMASK; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags |= NO_PLANEMASK; + infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK; + } + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047; + + xf86InitFBManager(pScreen, &AvailFBArea); + + return(XAAInit(pScreen, infoPtr)); +} + +static void Permedia2LoadCoord( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if ((h != pGlint->h) || (w != pGlint->w)) { + pGlint->w = w; + pGlint->h = h; + GLINT_WRITE_REG(((h&0x0FFF)<<16)|(w&0x0FFF), RectangleSize); + } + if ((y != pGlint->y) || (x != pGlint->x)) { + pGlint->x = x; + pGlint->y = y; + GLINT_WRITE_REG(((y&0x0FFF)<<16)|(x&0x0FFF), RectangleOrigin); + } +} + + +void +Permedia2Sync(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(2); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); +} + +static void +Permedia2SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WAIT(3); + GLINT_WRITE_REG(((y1&0x0fff)<<16)|(x1&0x0fff), ScissorMinXY); + GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG(1, ScissorMode); + pGlint->ClippingOn = TRUE; +} + +static void +Permedia2DisableClipping(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CHECKCLIPPING; +} + +static void +Permedia2SetupForScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->BltScanDirection = 0; + if (xdir == 1) pGlint->BltScanDirection |= XPositive; + if (ydir == 1) pGlint->BltScanDirection |= YPositive; + + if (pScrn->bitsPerPixel == 24) { + GLINT_WAIT(4); + } else { + GLINT_WAIT(5); + DO_PLANEMASK(planemask); + } + + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if ((rop == GXset) || (rop == GXclear)) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + if ((rop == GXcopy) || (rop == GXcopyInverted)) { + GLINT_WRITE_REG(pGlint->pprod|FBRM_SrcEnable, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod|FBRM_SrcEnable|FBRM_DstEnable, + FBReadMode); + } + } + LOADROP(rop); +} + +static void +Permedia2SubsequentScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn, int x1, + int y1, int x2, int y2, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(4); + Permedia2LoadCoord(pScrn, x2, y2, w, h); + GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | ((x1-x2)&0x0FFF), FBSourceDelta); + GLINT_WRITE_REG(PrimitiveRectangle | pGlint->BltScanDirection, Render); +} + +static void +Permedia2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia2SetupForScreenToScreenCopy"); + + pGlint->BltScanDirection = 0; + if (xdir == 1) pGlint->BltScanDirection |= XPositive; + if (ydir == 1) pGlint->BltScanDirection |= YPositive; + + GLINT_WAIT(4); + DO_PLANEMASK(planemask); + + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if ((rop == GXset) || (rop == GXclear)) { + pGlint->FrameBufferReadMode = pGlint->pprod; + } else + if ((rop == GXcopy) || (rop == GXcopyInverted)) { + pGlint->FrameBufferReadMode = pGlint->pprod |FBRM_SrcEnable; + } else { + pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable | + FBRM_DstEnable; + } + LOADROP(rop); + TRACE_EXIT("Permedia2SetupForScreenToScreenCopy"); +} + +static void +Permedia2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + char align; + + TRACE_ENTER("Permedia2SubsequentScreenToScreenCopy"); + /* We can only use GXcopy for Packed modes */ + if (pGlint->ROP != GXcopy) { + GLINT_WAIT(5); + GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode); + Permedia2LoadCoord(pScrn, x2, y2, w, h); + GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | ((x1-x2)&0x0FFF), FBSourceDelta); + } else { + align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign); + GLINT_WAIT(6); + GLINT_WRITE_REG(pGlint->FrameBufferReadMode|FBRM_Packed, FBReadMode); + Permedia2LoadCoord(pScrn, x2>>pGlint->BppShift, y2, + (w+7)>>pGlint->BppShift, h); + GLINT_WRITE_REG(align<<29|x2<<16|(x2+w), PackedDataLimits); + GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | (((x1 & ~pGlint->bppalign)-(x2 & ~pGlint->bppalign))&0x0FFF), FBSourceDelta); + } + + GLINT_WRITE_REG(PrimitiveRectangle | pGlint->BltScanDirection, Render); + TRACE_EXIT("Permedia2SubsequentScreenToScreenCopy"); +} + + + +static void +Permedia2PolylinesThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolyLines(pDraw, pGC, mode, npt, pPts); +} + +static void +Permedia2PolySegmentThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolySegment(pDraw, pGC, nseg, pSeg); +} + +static void +Permedia2SetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(color, GLINTColor); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +Permedia2SubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(6); + GLINT_WRITE_REG(x<<16, StartXDom); + GLINT_WRITE_REG(y<<16, StartY); + if (dir == DEGREES_0) { + GLINT_WRITE_REG(1<<16, dXDom); + GLINT_WRITE_REG(0<<16, dY); + } else { + GLINT_WRITE_REG(0<<16, dXDom); + GLINT_WRITE_REG(1<<16, dY); + } + + GLINT_WRITE_REG(len, GLINTCount); + GLINT_WRITE_REG(PrimitiveLine, Render); +} + +static void +Permedia2SubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if(dmaj == dmin) { + GLINT_WAIT(6); + if(octant & YDECREASING) { + GLINT_WRITE_REG(-1<<16, dY); + } else { + GLINT_WRITE_REG(1<<16, dY); + } + + if(octant & XDECREASING) { + GLINT_WRITE_REG(-1<<16, dXDom); + } else { + GLINT_WRITE_REG(1<<16, dXDom); + } + + GLINT_WRITE_REG(x<<16, StartXDom); + GLINT_WRITE_REG(y<<16, StartY); + GLINT_WRITE_REG(len,GLINTCount); + GLINT_WRITE_REG(PrimitiveLine, Render); + return; + } + + fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0, + (octant & XDECREASING) ? -1 : 1, + (octant & YDECREASING) ? -1 : 1, + (octant & YMAJOR) ? Y_AXIS : X_AXIS, + x, y, dmin + e, dmin, -dmaj, len); +} + +static void +Permedia2SetupForFillRectSolid24bpp(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + pGlint->ForeGroundColor = color; + + GLINT_WAIT(5); + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(color, ConstantColor); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +Permedia2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia2SetupForFillRectSolid"); + + REPLICATE(color); + + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + if (rop == GXcopy) { + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(color, FBBlockColor); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(color, ConstantColor); + /* We can use Packed mode for filling solid non-GXcopy rasters */ + GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable|FBRM_Packed, FBReadMode); + } + LOADROP(rop); + TRACE_EXIT("Permedia2SetupForFillRectSolid"); +} + +static void +Permedia2SubsequentFillRectSolid24bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WAIT(3); + Permedia2LoadCoord(pScrn, x, y, w, h); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive, Render); +} + +static void +Permedia2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int speed = 0; + TRACE_ENTER("Permedia2SubsequentFillRectSolid"); + + if (pGlint->ROP == GXcopy) { + GLINT_WAIT(3); + Permedia2LoadCoord(pScrn, x, y, w, h); + speed = FastFillEnable; + } else { + GLINT_WAIT(4); + Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y, + (w+7)>>pGlint->BppShift, h); + GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits); + speed = 0; + } + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | speed, Render); + TRACE_EXIT("Permedia2SubsequentFillRectSolid"); +} + +static void +Permedia2SetupForMono8x8PatternFill24bpp(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (bg == -1) pGlint->FrameBufferReadMode = -1; + else pGlint->FrameBufferReadMode = 0; + + pGlint->ForeGroundColor = fg; + pGlint->BackGroundColor = bg; + REPLICATE(pGlint->ForeGroundColor); + REPLICATE(pGlint->BackGroundColor); + + GLINT_WAIT(12); + GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0); + GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4); + GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); + + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +Permedia2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia2SetupForMono8x8PatternFill"); + + if (bg == -1) pGlint->FrameBufferReadMode = -1; + else pGlint->FrameBufferReadMode = 0; + + pGlint->ForeGroundColor = fg; + pGlint->BackGroundColor = bg; + REPLICATE(pGlint->ForeGroundColor); + REPLICATE(pGlint->BackGroundColor); + +#if DEBUG + ErrorF("patternx: %x patterny: %x\n", patternx, patterny); +#endif + + GLINT_WAIT(13); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0); + GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4); + GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); + + if (rop == GXcopy) { + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); + TRACE_EXIT("Permedia2SetupForMono8x8PatternFill"); +} + +static void +Permedia2SubsequentMono8x8PatternFillRect24bpp(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(8); + Permedia2LoadCoord(pScrn, x, y, w, h); + + if (pGlint->FrameBufferReadMode != -1) { + GLINT_WRITE_REG(pGlint->BackGroundColor, ConstantColor); + GLINT_WRITE_REG(patternx<<7|patterny<<12| ASM_InvertPattern | + STIPPLE_SWAP | UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | XPositive | + YPositive | PrimitiveRectangle, Render); + } + + GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); + GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | XPositive | YPositive | + PrimitiveRectangle, Render); +} + +static void +Permedia2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("Permedia2SubsequentMono8x8PatternFillRect()"); + + GLINT_WAIT(9); + Permedia2LoadCoord(pScrn, x, y, w, h); + + if (pGlint->FrameBufferReadMode != -1) { + if (pGlint->ROP == GXcopy) { + GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor); + GLINT_WRITE_REG(ASM_InvertPattern|patternx<<7|patterny<<12| + STIPPLE_SWAP | UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | FastFillEnable | + XPositive | YPositive | PrimitiveRectangle, Render); + } else { + GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); + GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0); + GLINT_WRITE_REG(patternx<<7|patterny<<12| + STIPPLE_SWAP | UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | XPositive | TextureEnable | + YPositive | PrimitiveRectangle, Render); + return; + } + } + + if (pGlint->ROP == GXcopy) { + GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor); + pGlint->FrameBufferReadMode = FastFillEnable; + } else { + GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); + pGlint->FrameBufferReadMode = 0; + } + GLINT_WRITE_REG(patternx<<7|patterny<<12|STIPPLE_SWAP|UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | pGlint->FrameBufferReadMode | + XPositive | YPositive | PrimitiveRectangle, Render); + + TRACE_EXIT("Permedia2SubsequentMono8x8PatternFillRect()"); +} + +static void +Permedia2SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dobackground = 0; + + TRACE_ENTER("Permedia2SetupForScanlineCPUToScreenColorExpandFill"); + if (bg != -1) dobackground |= ForceBackgroundColor; + pGlint->BackGroundColor = bg; + pGlint->ForeGroundColor = fg; + REPLICATE(fg); + REPLICATE(bg); + GLINT_WAIT(7); + DO_PLANEMASK(planemask); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode); + } + if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) { + pGlint->FrameBufferReadMode = FastFillEnable; + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, FBBlockColor); + GLINT_WRITE_REG(pGlint->RasterizerSwap,RasterizerMode); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, ConstantColor); + GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground| + pGlint->RasterizerSwap,RasterizerMode); + if (dobackground) { + GLINT_WRITE_REG(bg, Texel0); + pGlint->FrameBufferReadMode = TextureEnable; + } else { + pGlint->FrameBufferReadMode = 0; + } + } + LOADROP(rop); + TRACE_EXIT("Permedia2SetupForScanlineCPUToScreenColorExpandFill"); +} + +static void +Permedia2SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("Permedia2SubsequentScanlineCPUToScreenColorExpandFill"); + + pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ + + pGlint->cpucount = h; + + GLINT_WAIT(6); + Permedia2LoadCoord(pScrn, x, y, w, h); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | pGlint->FrameBufferReadMode | SyncOnBitMask, Render); + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); + GLINT_WAIT(pGlint->dwords); + pGlint->cpucount--; + TRACE_EXIT("Permedia2SubsequentScanlineCPUToScreenColorExpandFill"); +} + +static void +Permedia2SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (pGlint->cpucount--) + GLINT_WAIT(pGlint->dwords); +} + + +static void +Permedia2WriteBitmap(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char *srcpntr; + int dwords, height, mode; + Bool SecondPass = FALSE; + + TRACE_ENTER("Permedia2WriteBitmap"); + + w += skipleft; + x -= skipleft; + dwords = (w + 31) >> 5; + + Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h); + + if (pScrn->bitsPerPixel == 24) { + GLINT_WAIT(10); + } else { + GLINT_WAIT(11); + DO_PLANEMASK(planemask); + } + LOADROP(rop); + Permedia2LoadCoord(pScrn, x&0xFFFF, y, w, h); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) { + mode = FastFillEnable; + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->RasterizerSwap,RasterizerMode); + } else { + mode = 0; + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(BitMaskPackingEachScanline| + pGlint->RasterizerSwap,RasterizerMode); + } + + if(bg == -1) { + REPLICATE(fg); + if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, ConstantColor); + } + } else if((rop == GXcopy) && (pScrn->bitsPerPixel != 24)) { + REPLICATE(bg); + GLINT_WRITE_REG(bg, FBBlockColor); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive |YPositive |mode,Render); + REPLICATE(fg); + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + SecondPass = TRUE; + REPLICATE(fg); + if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, ConstantColor); + } + } + +SECOND_PASS: + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | mode | SyncOnBitMask, Render); + + height = h; + srcpntr = src; + while(height--) { + GLINT_WAIT(dwords + 1); + /* 0x0D is the TAG value for BitMaskPattern */ + GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32 *)srcpntr, dwords); + srcpntr += srcwidth; + } + + if(SecondPass) { + SecondPass = FALSE; + REPLICATE(bg); + GLINT_WAIT(3); + if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) { + GLINT_WRITE_REG(InvertBitMask|pGlint->RasterizerSwap,RasterizerMode); + GLINT_WRITE_REG(bg, FBBlockColor); + } else { + GLINT_WRITE_REG(InvertBitMask|BitMaskPackingEachScanline| + pGlint->RasterizerSwap, RasterizerMode); + GLINT_WRITE_REG(bg, ConstantColor); + } + goto SECOND_PASS; + } + + GLINT_WAIT(1); + GLINT_WRITE_REG(pGlint->RasterizerSwap, RasterizerMode); + Permedia2DisableClipping(pScrn); + SET_SYNC_FLAG(infoRec); + TRACE_EXIT("Permedia2WriteBitmap"); +} + + +static void +Permedia2WritePixmap8bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + unsigned char *srcpbyte; + Bool FastTexLoad = FALSE; + + GLINT_WAIT(3); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->RasterizerSwap,RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + + dwords = (w + 3) >> 2; +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE; +#endif + if((rop != GXcopy) || (planemask != ~0)) + FastTexLoad = FALSE; + + if (rop == GXcopy) { + skipleft = 0; + } else { + if((skipleft = (long)src & 0x03)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03); + } + } + + + if(FastTexLoad) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + Permedia2Sync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = ((y * pScrn->displayWidth) + x) >> 2; + srcp = (CARD32*)src; + GLINT_WAIT(1); /*??*/ + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x11 << 4) | + 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + address += pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + char align = (x & pGlint->bppalign); + + + GLINT_WAIT(1); /*??*/ + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if (rop == GXcopy) { + GLINT_WAIT(6); + Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y, + (w+pGlint->bppalign)>>pGlint->BppShift, h); + GLINT_WRITE_REG(align<<29|x<<16|(x+w), PackedDataLimits); + } else { + Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h); + GLINT_WAIT(5); + Permedia2LoadCoord(pScrn, x, y, w, h); + } + LOADROP(rop); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | + SyncOnHostData, Render); + + if (rop == GXcopy) { + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + } else { + while(h--) { + count = w; + srcpbyte = (unsigned char *)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveBYTE( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned char *)srcpbyte, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcpbyte += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveBYTE( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned char *)srcpbyte, count); + } + src += srcwidth; + } + } + } + + Permedia2DisableClipping(pScrn); + SET_SYNC_FLAG(infoRec); +} + +static void +Permedia2WritePixmap16bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + unsigned short* srcpword; + Bool FastTexLoad; + + TRACE_ENTER("Permedia2WritePixmap16bpp"); + GLINT_WAIT(3); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->RasterizerSwap,RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + + FastTexLoad = FALSE; + dwords = (w + 1) >> 1; +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE; +#endif + if((rop != GXcopy) || (planemask != ~0)) + FastTexLoad = FALSE; + + if (rop == GXcopy) { + skipleft = 0; + } else { + if((skipleft = (long)src & 0x03L)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + } + + if(FastTexLoad) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + Permedia2Sync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = ((y * pScrn->displayWidth) + x) >> 1; + srcp = (CARD32*)src; + GLINT_WAIT(1); /*??*/ + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x11 << 4) | + 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + address += pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + char align = (x & pGlint->bppalign); + + + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if (rop == GXcopy) { + GLINT_WAIT(6); + Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y, + (w+pGlint->bppalign)>>pGlint->BppShift, h); + GLINT_WRITE_REG(align<<29|x<<16|(x+w), PackedDataLimits); + } else { + Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h); + GLINT_WAIT(5); + Permedia2LoadCoord(pScrn, x, y, w, h); + } + LOADROP(rop); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | + SyncOnHostData, Render); + + if (rop == GXcopy) { + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + } else { + while(h--) { + count = w; + srcpword = (unsigned short *)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned short *)srcpword, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcpword += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned short *)srcpword, count); + } + src += srcwidth; + } + } + } + + Permedia2DisableClipping(pScrn); + SET_SYNC_FLAG(infoRec); + TRACE_EXIT("Permedia2WritePixmap16bpp"); +} + +static void +Permedia2WritePixmap32bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + + GLINT_WAIT(3); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->RasterizerSwap,RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + + dwords = w; + + if((rop == GXcopy) && (planemask == ~0)) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + Permedia2Sync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = (y * pScrn->displayWidth) + x; + srcp = (CARD32*)src; + GLINT_WAIT(1); /*??*/ + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x11 << 4) | + 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + address += pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + if((skipleft = (long)src & 0x03L)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + + Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h); + + GLINT_WAIT(6); + Permedia2LoadCoord(pScrn, x, y, w, h); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + LOADROP(rop); + GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | + SyncOnHostData, Render); + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + } + + Permedia2DisableClipping(pScrn); + SET_SYNC_FLAG(infoRec); +} diff --git a/src/pm2_dac.c b/src/pm2_dac.c new file mode 100644 index 0000000..6df6e08 --- /dev/null +++ b/src/pm2_dac.c @@ -0,0 +1,506 @@ +/* + * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Helmut Fahrion, <hf@suse.de> + * Michel Dänzer, <michdaen@iiic.ethz.ch> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c,v 1.26 2001/12/06 15:16:40 tsi Exp $ */ + +#include "Xarch.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "glint_regs.h" +#include "glint.h" + +#define INITIALFREQERR 100000 +#define MINCLK 110000 /* VCO frequency range */ +#define MAXCLK 250000 + +static unsigned long +PM2DAC_CalculateMNPCForClock +( + unsigned long reqclock, /* In kHz units */ + unsigned long refclock, /* In kHz units */ + unsigned char *rm, /* M Out */ + unsigned char *rn, /* N Out */ + unsigned char *rp /* P Out */ + ) +{ + unsigned char m, n, p; + unsigned long f; + long freqerr, lowestfreqerr = INITIALFREQERR; + unsigned long clock,actualclock = 0; + + for (n = 2; n <= 14; n++) { + for (m = 2; m != 0; m++) { /* this is a char, so this counts to 255 */ + f = refclock * m / n; + if ( (f < MINCLK) || (f > MAXCLK) ) + continue; + for (p = 0; p <= 4; p++) { + clock = f >> p; + freqerr = reqclock - clock; + if (freqerr < 0) + freqerr = -freqerr; + if (freqerr < lowestfreqerr) { + *rn = n; + *rm = m; + *rp = p; + lowestfreqerr = freqerr; + actualclock = clock; +#ifdef DEBUG + ErrorF("Best %ld diff %ld\n",actualclock,freqerr); +#endif + } + } + } + } + + return(actualclock); +} + +Bool +Permedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTRegPtr pReg = &pGlint->ModeReg[0]; + CARD32 temp1, temp2, temp3, temp4; + + pReg->glintRegs[Aperture0 >> 3] = 0; + pReg->glintRegs[Aperture1 >> 3] = 0; + pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; + pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; + + pReg->glintRegs[DFIFODis >> 3] = 0; + pReg->glintRegs[FIFODis >> 3] = 1; + + if (pGlint->UseBlockWrite) + pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21; + + + temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; + temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; + temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); + pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); + pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); + pReg->glintRegs[PMHbEnd >> 3] = + Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay); + pReg->glintRegs[PMScreenStride >> 3] = + Shiftbpp(pScrn,pScrn->displayWidth>>1); + + pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; + pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; + pReg->glintRegs[PMVsStart >> 3] = temp2; + pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; + + /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick + both sync lines to active high here and if needed invert them + using the RAMDAC's MCR below. */ + pReg->glintRegs[PMVideoControl >> 3] = + (1 << 5) | (1 << 3) | 1; + + if (pScrn->bitsPerPixel > 8) { + /* When != 8bpp then we stick the RAMDAC into 64bit mode */ + /* And reduce the horizontal timings by half */ + pReg->glintRegs[PMVideoControl >> 3] |= 1<<16; + pReg->glintRegs[PMHTotal >> 3] >>= 1; + pReg->glintRegs[PMHsEnd >> 3] >>= 1; + pReg->glintRegs[PMHsStart >> 3] >>= 1; + pReg->glintRegs[PMHbEnd >> 3] >>= 1; + } + + pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); + pReg->glintRegs[PMScreenBase >> 3] = 0; + pReg->glintRegs[PMHTotal >> 3] -= 1; + pReg->glintRegs[PMHsStart >> 3] -= 1; + pReg->glintRegs[PMVTotal >> 3] -= 1; + + pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD; + + pReg->DacRegs[PM2DACIndexMDCR] = 0x00; /* Disable Overlay */ + + { + /* Get the programmable clock values */ + unsigned char m,n,p; + unsigned long clockused; + + clockused = PM2DAC_CalculateMNPCForClock(mode->Clock,pGlint->RefClock, + &m,&n,&p); + pReg->DacRegs[PM2DACIndexClockAM] = m; + pReg->DacRegs[PM2DACIndexClockAN] = n; + pReg->DacRegs[PM2DACIndexClockAP] = p|0x08; + } + + if (pScrn->rgbBits == 8) + pReg->DacRegs[PM2DACIndexMCR] = 0x02; /* 8bit DAC */ + else + pReg->DacRegs[PM2DACIndexMCR] = 0x00; /* 6bit DAC */ + + if (!(mode->Flags & V_PHSYNC)) + pReg->DacRegs[PM2DACIndexMCR] |= 0x04; /* invert hsync */ + if (!(mode->Flags & V_PVSYNC)) + pReg->DacRegs[PM2DACIndexMCR] |= 0x08; /* invert vsync */ + + switch (pScrn->bitsPerPixel) + { + case 8: + pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_GRAPHICS | + PM2DAC_CI8; + break; + case 16: + if (pScrn->depth == 15) { + pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| + PM2DAC_GRAPHICS | PM2DAC_5551; + } else { + pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| + PM2DAC_GRAPHICS | PM2DAC_565; + } + break; + case 24: + pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| + PM2DAC_GRAPHICS | PM2DAC_PACKED; + break; + case 32: + pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | + PM2DAC_GRAPHICS | PM2DAC_8888; + if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { + pReg->DacRegs[PM2DACIndexColorKeyControl] = 0x11; + pReg->DacRegs[PM2DACIndexColorKeyOverlay] = pScrn->colorKey; + } else + pReg->DacRegs[PM2DACIndexCMR] |= PM2DAC_TRUECOLOR; + break; + } + + return(TRUE); +} + +void +Permedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536); + + glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); + glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); + glintReg->glintRegs[PMFramebufferWriteMask >> 3] = + GLINT_READ_REG(PMFramebufferWriteMask); + glintReg->glintRegs[PMBypassWriteMask >> 3] = GLINT_READ_REG(PMBypassWriteMask); + glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); + glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); + /* We only muck about with PMMemConfig, if user wants to */ + if (pGlint->UseBlockWrite) + glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig); + glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); + glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); + glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd); + glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); + glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); + glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); + glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); + glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); + glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); + glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); + glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); + glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); + glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); + glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); + + for (i=0;i<768;i++) { + Permedia2ReadAddress(pScrn, i); + glintReg->cmap[i] = Permedia2ReadData(pScrn); + } + + glintReg->DacRegs[PM2DACIndexColorKeyOverlay] = + Permedia2InIndReg(pScrn, PM2DACIndexColorKeyOverlay); + glintReg->DacRegs[PM2DACIndexColorKeyControl] = + Permedia2InIndReg(pScrn, PM2DACIndexColorKeyControl); + glintReg->DacRegs[PM2DACIndexMCR] = + Permedia2InIndReg(pScrn, PM2DACIndexMCR); + glintReg->DacRegs[PM2DACIndexMDCR] = + Permedia2InIndReg(pScrn, PM2DACIndexMDCR); + glintReg->DacRegs[PM2DACIndexCMR] = + Permedia2InIndReg(pScrn, PM2DACIndexCMR); + + glintReg->DacRegs[PM2DACIndexClockAM] = + Permedia2InIndReg(pScrn, PM2DACIndexClockAM); + glintReg->DacRegs[PM2DACIndexClockAN] = + Permedia2InIndReg(pScrn, PM2DACIndexClockAN); + glintReg->DacRegs[PM2DACIndexClockAP] = + Permedia2InIndReg(pScrn, PM2DACIndexClockAP); +} + +void +Permedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + if (pGlint->STATE) + xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536); + +#if 0 + GLINT_SLOW_WRITE_REG(0, ResetStatus); + while(GLINT_READ_REG(ResetStatus) != 0) { + xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n"); + }; +#endif + + GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask); + + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3], + PMFramebufferWriteMask); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3], + PMBypassWriteMask); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis); + /* We only muck about with PMMemConfig, if user wants to */ + if (pGlint->UseBlockWrite) + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3], + PMVideoControl); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3], + PMScreenStride); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig); + + Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyOverlay, 0x00, + glintReg->DacRegs[PM2DACIndexColorKeyOverlay]); + Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyControl, 0x00, + glintReg->DacRegs[PM2DACIndexColorKeyControl]); + Permedia2OutIndReg(pScrn, PM2DACIndexMCR, 0x00, + glintReg->DacRegs[PM2DACIndexMCR]); + Permedia2OutIndReg(pScrn, PM2DACIndexMDCR, 0x00, + glintReg->DacRegs[PM2DACIndexMDCR]); + Permedia2OutIndReg(pScrn, PM2DACIndexCMR, 0x00, + glintReg->DacRegs[PM2DACIndexCMR]); + + Permedia2OutIndReg(pScrn, PM2DACIndexClockAM, 0x00, + glintReg->DacRegs[PM2DACIndexClockAM]); + Permedia2OutIndReg(pScrn, PM2DACIndexClockAN, 0x00, + glintReg->DacRegs[PM2DACIndexClockAN]); + Permedia2OutIndReg(pScrn, PM2DACIndexClockAP, 0x00, + glintReg->DacRegs[PM2DACIndexClockAP]); + + for (i=0;i<768;i++) { + Permedia2WriteAddress(pScrn, i); + Permedia2WriteData(pScrn, glintReg->cmap[i]); + } +} + +static void +Permedia2ShowCursor(ScrnInfoPtr pScrn) +{ + /* Enable cursor - X11 mode */ + Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x43); +} + +static void +Permedia2HideCursor(ScrnInfoPtr pScrn) +{ + /* Disable cursor */ + Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00); +} + +static void +Permedia2LoadCursorImage( + ScrnInfoPtr pScrn, + unsigned char *src +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + GLINT_SLOW_WRITE_REG(0x00, PM2DACWriteAddress); + for (i=0; i<1024; i++) { + GLINT_SLOW_WRITE_REG(*(src++), PM2DACCursorData); + } +} + +static void +Permedia2SetCursorPosition( + ScrnInfoPtr pScrn, + int x, int y +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + x += 64; + y += 64; + + /* Output position - "only" 11 bits of location documented */ + + GLINT_WRITE_REG(x & 0xFF, PM2DACCursorXLsb); + GLINT_WRITE_REG((x>>8) & 0x07, PM2DACCursorXMsb); + GLINT_WRITE_REG(y & 0xFF, PM2DACCursorYLsb); + GLINT_WRITE_REG((y>>8) & 0x07, PM2DACCursorYMsb); +} + +static void +Permedia2SetCursorColors( + ScrnInfoPtr pScrn, + int bg, int fg +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + /* The Permedia2 cursor is always 8 bits so shift 8, not 10 */ + + GLINT_SLOW_WRITE_REG(1, PM2DACCursorColorAddress); + /* Background color */ + GLINT_SLOW_WRITE_REG(bg >> 0, PM2DACCursorColorData); + GLINT_SLOW_WRITE_REG(bg >> 8, PM2DACCursorColorData); + GLINT_SLOW_WRITE_REG(bg >> 16, PM2DACCursorColorData); + + /* Foreground color */ + GLINT_SLOW_WRITE_REG(fg >> 0, PM2DACCursorColorData); + GLINT_SLOW_WRITE_REG(fg >> 8, PM2DACCursorColorData); + GLINT_SLOW_WRITE_REG(fg >> 16, PM2DACCursorColorData); +} + +static Bool +Permedia2UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) +{ + return TRUE; +} + +Bool +Permedia2HWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pGlint->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | +#endif + HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; + infoPtr->SetCursorColors = Permedia2SetCursorColors; + infoPtr->SetCursorPosition = Permedia2SetCursorPosition; + infoPtr->LoadCursorImage = Permedia2LoadCursorImage; + infoPtr->HideCursor = Permedia2HideCursor; + infoPtr->ShowCursor = Permedia2ShowCursor; + infoPtr->UseHWCursor = Permedia2UseHWCursor; + + return(xf86InitCursor(pScreen, infoPtr)); +} + +/* I2C Functions */ + +void +Permedia2I2CUDelay(I2CBusPtr b, int usec) +{ + GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; + CARD32 ct1 = GLINT_READ_REG(PMCount); + CARD32 ct2 = usec * 100; + + if (GLINT_READ_REG(PMCount) != ct1) + while ((GLINT_READ_REG(PMCount) - ct1) < ct2); +} + +void +Permedia2I2CPutBits(I2CBusPtr b, int scl, int sda) +{ + GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; + int r = (pGlint->DDCBus == b) ? PMDDCData : VSSerialBusControl; + CARD32 v = GLINT_READ_REG(r) & ~(ClkOut | DataOut); + + if (scl > 0) v |= ClkOut; + if (sda > 0) v |= DataOut; + + GLINT_WRITE_REG(v, r); +} + +void +Permedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda) +{ + GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; + CARD32 v = GLINT_READ_REG((pGlint->DDCBus == b) ? + PMDDCData : VSSerialBusControl); + + *scl = (v & ClkIn) > 0; + *sda = (v & DataIn) > 0; +} + +void +Permedia2PreInit(ScrnInfoPtr pScrn) +{ +#if defined(__alpha__) + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* + * On Alpha, we have to init secondary PM2 cards, since + * int10 cannot be run on the OEMed cards with VGA disable + * jumpers. + */ + if (!xf86IsPrimaryPci(pGlint->PciInfo)) { + if ( IS_GLORIASYNERGY ) { + + /* PM2DAC_CalculateMNPCForClock(80000, 14318, &m, &n, &p); */ + Permedia2OutIndReg(pScrn, PM2DACIndexMemClockM, 0x00, 0x7b); + Permedia2OutIndReg(pScrn, PM2DACIndexMemClockN, 0x00, 0x0b); + Permedia2OutIndReg(pScrn, PM2DACIndexMemClockP, 0x00, 0x09); + + GLINT_SLOW_WRITE_REG( 0x20, PMBootAddress); + GLINT_SLOW_WRITE_REG( 0xe6002021, PMMemConfig); + } + } +#endif /* __alpha__ */ +} diff --git a/src/pm2_video.c b/src/pm2_video.c new file mode 100644 index 0000000..869906e --- /dev/null +++ b/src/pm2_video.c @@ -0,0 +1,3204 @@ +/* + * Permedia 2 Xv Driver + * + * Copyright (C) 1998-2000 Michael H. Schimek <m.schimek@netway.at> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c,v 1.23 2002/12/02 22:52:30 tsi Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xf86fbman.h" +#include "xf86i2c.h" +#include "xf86xv.h" +#include "Xv.h" + +#include "glint_regs.h" +#include "glint.h" + +#ifndef XvExtension + +void Permedia2VideoInit(ScreenPtr pScreen) {} +void Permedia2VideoUninit(ScrnInfoPtr pScrn) {} +void Permedia2VideoEnterVT(ScrnInfoPtr pScrn) {} +void Permedia2VideoLeaveVT(ScrnInfoPtr pScrn) {} + +#else + +#undef MIN +#undef ABS +#undef CLAMP +#undef ENTRIES + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define ABS(n) (((n) < 0) ? -(n) : (n)) +#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max)) +#define ENTRIES(array) (sizeof(array) / sizeof((array)[0])) + +#define ADAPTORS 3 +#define PORTS 6 + +#define PCI_SUBSYSTEM_ID_WINNER_2000_P2C 0x0a311048 +#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C 0x0a321048 +#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A 0x0a351048 +#define PCI_SUBSYSTEM_ID_WINNER_2000_P2A 0x0a441048 + +/* + * Proprietary kernel backbone interface + */ + +#define XVIPC_MAGIC 0x6A5D70E6 +#define XVIPC_VERSION 1 +#define VIDIOC_PM2_XVIPC 0x00007F7F + +typedef enum { + OP_ATTR = 0, + OP_RESET = 8, /* unused */ + OP_START, + OP_STOP, + OP_PLUG, + OP_VIDEOSTD, + OP_WINDOW, /* unused */ + OP_CONNECT, + OP_EVENT, + OP_ALLOC, + OP_FREE, + OP_UPDATE, + OP_NOP, /* ignored */ + OP_ENTER, + OP_LEAVE, + OP_DISCONNECT +} xvipc_op; + +typedef struct _pm2_xvipc { + int magic; + void *pm2p, *pAPriv; + int port, op, time, block; + int a, b, c, d, e, f; +} pm2_xvipc; + +static pm2_xvipc xvipc; +static int xvipc_fd = -1; + + +#define MAX_BUFFERS 2 + +typedef struct { + CARD32 xy, wh; /* 16.0 16.0 */ + INT32 s, t; /* 12.20 fp */ + short y1, y2; +} CookieRec, *CookiePtr; + +typedef struct _PortPrivRec { + struct _AdaptorPrivRec * pAdaptor; + I2CDevRec I2CDev; + + INT32 Attribute[8]; /* Brig, Con, Sat, Hue, Int, Filt, BkgCol, Alpha */ + + int BuffersRequested; + int BuffersAllocated; + FBAreaPtr pFBArea[MAX_BUFFERS]; + CARD32 BufferBase[MAX_BUFFERS]; /* FB byte offset */ + CARD32 BufferStride; /* bytes */ + CARD32 BufferPProd; /* PProd(BufferStride in buffer pixels) */ + + INT32 vx, vy, vw, vh; /* 12.10 fp */ + int dx, dy, dw, dh; + int fw, fh; + + CookiePtr pCookies; + int nCookies; + INT32 dS, dT; /* 12.20 fp */ + + int Id, Bpp; /* Scaler */ + + int Plug; + int BkgCol; /* RGB 5:6:5; 5:6:5 */ + Bool StreamOn; /* buffer <-> hardware */ + int VideoOn; /* buffer <-> screen */ + int VideoStdReq; + + int StopDelay; + + int FramesPerSec, FrameAcc; + +} PortPrivRec, *PortPrivPtr; + +enum { VIDEO_OFF, VIDEO_ONE_SHOT, VIDEO_ON }; + +typedef struct _LFBAreaRec { + struct _LFBAreaRec * Next; + int Linear; + FBAreaPtr pFBArea; +} LFBAreaRec, *LFBAreaPtr; + +typedef struct _AdaptorPrivRec { + struct _AdaptorPrivRec * Next; + ScrnInfoPtr pScrn; + + void * pm2p; + LFBAreaPtr LFBList; + + CARD32 dFifoControl; + CARD32 dDitherMode; + CARD32 dAlphaBlendMode; + CARD32 dTextureDataFormat; + + OsTimerPtr Timer; + int TimerUsers; + int Delay, Instant; + + int FramesPerSec; + int FrameLines; + int IntLine; /* Frame, not field */ + int LinePer; /* nsec */ + + Bool VideoIO; + int VideoStd; + + PortPrivRec Port[PORTS]; + +} AdaptorPrivRec, *AdaptorPrivPtr; + +static AdaptorPrivPtr AdaptorPrivList = NULL; + +#define FreeCookies(pPPriv) \ +do { \ + if ((pPPriv)->pCookies) { \ + xfree((pPPriv)->pCookies); \ + (pPPriv)->pCookies = NULL; \ + } \ +} while (0) + +#define PORTNUM(p) ((int)((p) - &pAPriv->Port[0])) +#define BPPSHIFT(g) (2 - (g)->BppShift) /* Bytes per pixel = 1 << BPPSHIFT(pGlint) */ + +#define DEBUG(x) + +static const Bool ColorBars = FALSE; + + +/* + * XF86Config VideoAdaptor options + */ + +typedef enum { + OPTION_DEVICE, + OPTION_FPS, + OPTION_BUFFERS, + OPTION_ENCODING, + OPTION_EXPOSE /* obsolete, ignored */ +} OptToken; + +/* XXX These should be made const, and per-screen/adaptor copies processed. */ +static OptionInfoRec AdaptorOptions[] = { + { OPTION_DEVICE, "Device", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; +static OptionInfoRec InputOptions[] = { + { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE }, + { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE }, + { OPTION_ENCODING, "Encoding", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; +static OptionInfoRec OutputOptions[] = { + { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE }, + { OPTION_EXPOSE, "Expose", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE }, + { OPTION_ENCODING, "Encoding", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + + +/* + * Attributes + */ + +#define XV_ENCODING "XV_ENCODING" +#define XV_BRIGHTNESS "XV_BRIGHTNESS" +#define XV_CONTRAST "XV_CONTRAST" +#define XV_SATURATION "XV_SATURATION" +#define XV_HUE "XV_HUE" + +/* Proprietary */ + +#define XV_INTERLACE "XV_INTERLACE" /* Interlaced (bool) */ +#define XV_FILTER "XV_FILTER" /* Bilinear filter (bool) */ +#define XV_BKGCOLOR "XV_BKGCOLOR" /* Output background (0x00RRGGBB) */ +#define XV_ALPHA "XV_ALPHA" /* Scaler alpha channel (bool) */ + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue; +static Atom xvInterlace, xvFilter, xvBkgColor, xvAlpha; + +/* Input */ + +static XF86VideoEncodingRec +InputVideoEncodings[] = +{ + { 0, "pal-composite", 704, 576, { 1, 50 }}, + { 1, "pal-composite_adaptor", 704, 576, { 1, 50 }}, + { 2, "pal-svideo", 704, 576, { 1, 50 }}, + { 3, "ntsc-composite", 704, 480, { 1001, 60000 }}, + { 4, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }}, + { 5, "ntsc-svideo", 704, 480, { 1001, 60000 }}, + { 6, "secam-composite", 704, 576, { 1, 50 }}, + { 7, "secam-composite_adaptor", 704, 576, { 1, 50 }}, + { 8, "secam-svideo", 704, 576, { 1, 50 }}, +}; + +static XF86AttributeRec +InputVideoAttributes[] = +{ + { XvSettable | XvGettable, -1000, +1000, XV_BRIGHTNESS }, + { XvSettable | XvGettable, -3000, +1000, XV_CONTRAST }, + { XvSettable | XvGettable, -3000, +1000, XV_SATURATION }, + { XvSettable | XvGettable, -1000, +1000, XV_HUE }, + { XvSettable | XvGettable, 0, 2, XV_INTERLACE }, + { XvSettable | XvGettable, 0, 1, XV_FILTER }, +}; + +static XF86VideoFormatRec +InputVideoFormats[] = +{ + { 8, TrueColor }, /* Dithered */ + { 15, TrueColor }, + { 16, TrueColor }, + { 24, TrueColor }, +}; + +/* Output */ + +static XF86VideoEncodingRec +OutputVideoEncodings[] = +{ + { 0, "pal-composite_adaptor", 704, 576, { 1, 50 }}, + { 1, "pal-svideo", 704, 576, { 1, 50 }}, + { 2, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }}, + { 3, "ntsc-svideo", 704, 480, { 1001, 60000 }}, +}; + +static XF86AttributeRec +OutputVideoAttributes[] = +{ + { XvSettable | XvGettable, 0, 2, XV_INTERLACE }, + { XvSettable | XvGettable, 0, 1, XV_FILTER }, + { XvSettable | XvGettable, 0x000000, 0xFFFFFF, XV_BKGCOLOR }, +}; + +static XF86VideoFormatRec +OutputVideoFormats[] = +{ + { 8, TrueColor }, + { 8, PseudoColor }, /* Using .. */ + { 8, StaticColor }, + { 8, GrayScale }, + { 8, StaticGray }, /* .. TexelLUT */ + { 15, TrueColor }, + { 16, TrueColor }, + { 24, TrueColor }, +}; + +/* Scaler */ + +static XF86VideoEncodingRec +ScalerEncodings[] = +{ + { 0, "XV_IMAGE", 2047, 2047, { 1, 1 }}, +}; + +static XF86AttributeRec +ScalerAttributes[] = +{ + { XvSettable | XvGettable, 0, 1, XV_FILTER }, + { XvSettable | XvGettable, 0, 1, XV_ALPHA }, +}; + +#define ScalerVideoFormats InputVideoFormats + +/* + * FOURCC from http://www.webartz.com/fourcc + * Generic GUID for legacy FOURCC XXXXXXXX-0000-0010-8000-00AA00389B71 + */ +#define LE4CC(a,b,c,d) (((CARD32)(a)&0xFF)|(((CARD32)(b)&0xFF)<<8)|(((CARD32)(c)&0xFF)<<16)|(((CARD32)(d)&0xFF)<<24)) +#define GUID4CC(a,b,c,d) { a,b,c,d,0,0,0,0x10,0x80,0,0,0xAA,0,0x38,0x9B,0x71 } + +#define NoOrder LSBFirst + +static XF86ImageRec +ScalerImages[] = +{ + /* Planar YVU 4:2:0 (emulated) */ + { LE4CC('Y','V','1','2'), XvYUV, NoOrder, GUID4CC('Y','V','1','2'), + 12, XvPlanar, 3, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU", XvTopToBottom }, + + /* Packed YUYV 4:2:2 */ + { LE4CC('Y','U','Y','2'), XvYUV, NoOrder, GUID4CC('Y','U','Y','2'), + 16, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV", XvTopToBottom }, + + /* Packed UYVY 4:2:2 */ + { LE4CC('U','Y','V','Y'), XvYUV, NoOrder, GUID4CC('U','Y','V','Y'), + 16, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY", XvTopToBottom }, + + /* Packed YUVA 4:4:4 */ + { LE4CC('Y','U','V','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, + 32, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUVA", XvTopToBottom }, + + /* Packed VUYA 4:4:4 */ + { LE4CC('V','U','Y','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, + 32, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 1, 1, 1, 1, 1, "VUYA", XvTopToBottom }, + + /* RGBA 8:8:8:8 */ + { 0x41, XvRGB, LSBFirst, { 0 }, + 32, XvPacked, 1, 24, 0x0000FF, 0x00FF00, 0xFF0000, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGB 5:6:5 */ + { 0x42, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 16, 0x001F, 0x07E0, 0xF800, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, + + /* RGBA 5:5:5:1 */ + { 0x43, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 15, 0x001F, 0x03E0, 0x7C00, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGBA 4:4:4:4 */ + { 0x44, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 12, 0x000F, 0x00F0, 0x0F00, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGBA 2:3:2:1 */ + { 0x45, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 7, 0x03, 0x1C, 0x60, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGB 3:3:2 */ + { 0x46, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 8, 0x07, 0x38, 0xC0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, + + /* BGRA 8:8:8:8 */ + { 0x47, XvRGB, LSBFirst, { 0 }, + 32, XvPacked, 1, 24, 0xFF0000, 0x00FF00, 0x0000FF, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGR 5:6:5 */ + { 0x48, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, + + /* BGRA 5:5:5:1 */ + { 0x49, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 15, 0x7C00, 0x03E0, 0x001F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGRA 4:4:4:4 */ + { 0x4A, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 12, 0x0F00, 0x00F0, 0x000F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGRA 2:3:2:1 */ + { 0x4B, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 7, 0x60, 0x1C, 0x03, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGR 2:3:3 */ + { 0x4C, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 8, 0xC0, 0x38, 0x07, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, +}; + + +/* + * Video codec tables + */ + +#define SAA7111_SLAVE_ADDRESS 0x48 +#define SAA7125_SLAVE_ADDRESS 0x88 + +static I2CByte +DecInitVec[] = +{ + 0x11, 0x00, + 0x02, 0xC1, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x4A, + 0x0A, 0x80, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x00, + 0x0E, 0x01, 0x10, 0xC8, 0x12, 0x20, + 0x13, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, +}; + +static I2CByte +EncInitVec[] = +{ + 0x3A, 0x83, 0x61, 0xC2, + 0x5A, 119, 0x5B, 0x7D, + 0x5C, 0xAF, 0x5D, 0x3C, 0x5E, 0x3F, 0x5F, 0x3F, + 0x60, 0x70, 0x62, 0x4B, 0x67, 0x00, + 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x20, + 0x6C, 0x03, 0x6D, 0x30, 0x6E, 0xA0, 0x6F, 0x00, + 0x70, 0x80, 0x71, 0xE8, 0x72, 0x10, + 0x7A, 0x13, 0x7B, 0xFB, 0x7C, 0x00, 0x7D, 0x00, +}; + +static I2CByte Dec02[3] = { 0xC1, 0xC0, 0xC4 }; +static I2CByte Dec09[3] = { 0x4A, 0x4A, 0xCA }; +static I2CByte Enc3A[3] = { 0x03, 0x03, 0x23 }; +static I2CByte Enc61[3] = { 0x06, 0x01, 0xC2 }; + +static I2CByte +DecVS[3][8] = +{ + { 0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01 }, + { 0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x01 }, + { 0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51 } +}; + +#define FSC(n) ((CARD32)((n) / 27e6 * 4294967296.0 + .5)) +#define SUBCARRIER_FREQ_PAL (4.433619e6) +#define SUBCARRIER_FREQ_NTSC (3.579545e6) + +static I2CByte +EncVS[2][14] = +{ + { 0x62, 0x4B, 0x6B, 0x28, 0x6E, 0xA0, + 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 0), + 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 8), + 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 16), + 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 24) }, + { 0x62, 0x6A, 0x6B, 0x20, 0x6E, 0x20, + 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 0), + 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 8), + 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 16), + 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 24) } +}; + +/* Forward */ +static void StopVideoStream(PortPrivPtr pPPriv, Bool shutdown); +static void RestoreVideoStd(AdaptorPrivPtr pAPriv); +static Bool xvipcHandshake(PortPrivPtr pPPriv, int op, Bool block); + + +/* + * Video codec controls + */ + +static int +SetAttr(PortPrivPtr pPPriv, int i, int value) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int v; + + if (value < InputVideoAttributes[i].min_value) + value = InputVideoAttributes[i].min_value; + else + if (value > InputVideoAttributes[i].max_value) + value = InputVideoAttributes[i].max_value; + + switch (i) { + case 0: + v = 128 + (MIN(value, 999) * 128) / 1000; + break; + + case 1: + case 2: + v = 64 + (MIN(value, 999) * 64) / 1000; + break; + + default: + v = (MIN(value, 999) * 128) / 1000; + break; + } + + if (pAPriv->pm2p) { + xvipc.a = v << 8; + + if (!xvipcHandshake(pPPriv, OP_ATTR + i, TRUE)) + return XvBadAlloc; + } else + if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x0A + i, v)) + return XvBadAlloc; + + pPPriv->Attribute[i] = value; + + return Success; +} + +static int +SetPlug(PortPrivPtr pPPriv, int Plug) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + + if (pAPriv->pm2p) { + xvipc.a = Plug - (pPPriv == &pAPriv->Port[1]); + + if (!xvipcHandshake(pPPriv, OP_PLUG, TRUE)) + return XvBadAlloc; + } else { + if (pPPriv == &pAPriv->Port[0]) { + if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x02, Dec02[Plug]) || + !xf86I2CWriteByte(&pPPriv->I2CDev, 0x09, Dec09[Plug])) + return XvBadAlloc; + } else { + if (pPPriv->StreamOn) { + if (!xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, Enc3A[Plug])) + return XvBadAlloc; + } else + if (ColorBars) + xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, 0x83); + } + } + + pPPriv->Plug = Plug; + + return Success; +} + +enum { PAL, NTSC, SECAM }; + +static int +SetVideoStd(PortPrivPtr pPPriv, int VideoStd) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int r = Success; + + if (pAPriv->pm2p) { + xvipc.a = VideoStd; + + if (!xvipcHandshake(&pAPriv->Port[0], OP_VIDEOSTD, TRUE)) + return XvBadAlloc; + + VideoStd = xvipc.a; /* Actual */ + } else { + if (VideoStd == SECAM) + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); + /* Disable output, SECAM not supported */ + + if (!xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, &DecVS[VideoStd][0], 4)) { + pAPriv->VideoStd = -1; + return XvBadAlloc; + } + + if (VideoStd != SECAM) + if (!xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, &EncVS[VideoStd][0], 7)) { + pAPriv->VideoStd = -1; + return XvBadAlloc; + } + } + + pAPriv->VideoStd = VideoStd; + pPPriv->VideoStdReq = VideoStd; + + if (VideoStd == NTSC) { + pAPriv->FramesPerSec = 30; + pAPriv->FrameLines = 525; + pAPriv->IntLine = 513; + pAPriv->LinePer = 63555; + } else { + pAPriv->FramesPerSec = 25; + pAPriv->FrameLines = 625; + pAPriv->IntLine = 613; + pAPriv->LinePer = 64000; + } + +#if 0 /* XF86Config option */ + + pAPriv->Port[0].FramesPerSec = pAPriv->FramesPerSec; + pAPriv->Port[1].FramesPerSec = pAPriv->FramesPerSec; + +#endif + + return r; +} + + +/* + * Buffer management + */ + +static void +RemoveAreaCallback(FBAreaPtr pFBArea) +{ + PortPrivPtr pPPriv = (PortPrivPtr) pFBArea->devPrivate.ptr; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + DEBUG(ScrnInfoPtr pScrn = pAPriv->pScrn;) + int i; + + for (i = 0; i < MAX_BUFFERS && pPPriv->pFBArea[i] != pFBArea; i++); + + if (i >= MAX_BUFFERS) + return; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "RemoveAreaCallback port #%d, buffer #%d, pFB=%p, off=0x%08x\n", + PORTNUM(pPPriv), i, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); + + if (pAPriv->VideoIO && PORTNUM(pPPriv) < 2) { + StopVideoStream(pPPriv, FALSE); + } + + for (; i < MAX_BUFFERS - 1; i++) + pPPriv->pFBArea[i] = pPPriv->pFBArea[i + 1]; + + pPPriv->pFBArea[MAX_BUFFERS - 1] = NULL; + + pPPriv->BuffersAllocated--; +} + +static void +RemoveableBuffers(PortPrivPtr pPPriv, Bool remove) +{ + int i; + + for (i = 0; i < MAX_BUFFERS; i++) + if (pPPriv->pFBArea[i]) + pPPriv->pFBArea[i]->RemoveAreaCallback = + remove ? RemoveAreaCallback : NULL; +} + +static void +FreeBuffers(PortPrivPtr pPPriv) +{ + DEBUG(AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;) + DEBUG(ScrnInfoPtr pScrn = pAPriv->pScrn;) + int i; + + RemoveableBuffers(pPPriv, FALSE); + + for (i = MAX_BUFFERS - 1; i >= 0; i--) + if (pPPriv->pFBArea[i]) { + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "FreeBuffers port #%d, buffer #%d, pFB=%p, off=0x%08x\n", + PORTNUM(pPPriv), i, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); + + xf86FreeOffscreenArea(pPPriv->pFBArea[i]); + + pPPriv->pFBArea[i] = NULL; + } + + pPPriv->BuffersAllocated = 0; +} + +enum { FORCE_LINEAR = 1, FORCE_RECT }; + +static int +AllocateBuffers(PortPrivPtr pPPriv, + int w, int h, int bytespp, + int num, int force) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + ScrnInfoPtr pScrn = pAPriv->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + Bool linear = (force != FORCE_RECT); + int i, j, retry = 0; + + FreeBuffers(pPPriv); + + for (i = 0; i < num; i++) { + if (linear) { + for (j = (w + 31) >> 5; partprodPermedia[j] < 0; j++); + + pPPriv->BufferStride = j * bytespp * 32; + pPPriv->BufferPProd = partprodPermedia[j]; + + pPPriv->pFBArea[i] = xf86AllocateLinearOffscreenArea(pScrn->pScreen, + (pPPriv->BufferStride * h + (1 << BPPSHIFT(pGlint)) - 1) >> BPPSHIFT(pGlint), + 8 >> BPPSHIFT(pGlint), NULL, NULL, (pointer) pPPriv); + + if (pPPriv->pFBArea[i]) + /* pPPriv->BufferBase[i] = pPPriv->pFBArea[i].linear; */ + pPPriv->BufferBase[i] = + ((pPPriv->pFBArea[i]->box.y1 * pScrn->displayWidth) + + pPPriv->pFBArea[i]->box.x1) << BPPSHIFT(pGlint); + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "New linear buffer %dx%d, rec %dx%d -> pFB=%p, off=0x%08x\n", + w, h, pPPriv->BufferStride, h, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); + } else { + pPPriv->BufferStride = pScrn->displayWidth << BPPSHIFT(pGlint); + + j = pPPriv->BufferStride / bytespp; + + if (j <= w && j <= 2048 && (j & 31) == 0 && + (pPPriv->BufferPProd = partprodPermedia[j >> 5]) >= 0) + { + pPPriv->pFBArea[i] = xf86AllocateOffscreenArea(pScrn->pScreen, + w, h, 8 >> BPPSHIFT(pGlint), NULL, NULL, (pointer) pPPriv); + + if (pPPriv->pFBArea[i]) + pPPriv->BufferBase[i] = + ((pPPriv->pFBArea[i]->box.y1 * pScrn->displayWidth) + + pPPriv->pFBArea[i]->box.x1) << BPPSHIFT(pGlint); + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, + "New rect buffer %dx%d, stride %d, %d -> pFB=%p, off=0x%08x\n", + w, h, pPPriv->BufferStride, j, pPPriv->pFBArea[i], pPPriv->BufferBase[i])); + } + } + + if (pPPriv->pFBArea[i]) + continue; + + if (!force && i == 0 && retry++ < 1) { + linear ^= TRUE; + i = -1; + } else + break; + } + + return pPPriv->BuffersAllocated = i; +} + + +/* + * Blitter + */ + +static Bool +RemakePutCookies(PortPrivPtr pPPriv, RegionPtr pRegion) +{ + BoxPtr pBox; + CookiePtr pCookie; + int nBox; + + if (!pRegion) { + pBox = (BoxPtr) NULL; + nBox = pPPriv->nCookies; + } else { + pBox = REGION_RECTS(pRegion); + nBox = REGION_NUM_RECTS(pRegion); + + if (!pPPriv->pCookies || pPPriv->nCookies < nBox) { + if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec)))) + return FALSE; + + pPPriv->pCookies = pCookie; + } + } + + pPPriv->dS = (pPPriv->vw << 10) / pPPriv->dw; + pPPriv->dT = (pPPriv->vh << 10) / pPPriv->dh; + + for (pCookie = pPPriv->pCookies; nBox--; pCookie++, pBox++) { + if (pRegion) { + pCookie->y1 = pBox->y1; + pCookie->y2 = pBox->x1; + pCookie->xy = (pBox->y1 << 16) | pBox->x1; + pCookie->wh = ((pBox->y2 - pBox->y1) << 16) | + (pBox->x2 - pBox->x1); + } + + pCookie->s = (pPPriv->vx << 10) + (pCookie->y2 - pPPriv->dx) * pPPriv->dS; + pCookie->t = (pPPriv->vy << 10) + (pCookie->y1 - pPPriv->dy) * pPPriv->dT; + } + + pPPriv->nCookies = pCookie - pPPriv->pCookies; + + return TRUE; +} + +#define FORMAT_YUYV ((0 << 5) + (1 << 4) + ((19 & 0x10) << 2) + ((19 & 0x0F) << 0)) +#define FORMAT_UYVY ((1 << 5) + (1 << 4) + ((19 & 0x10) << 2) + ((19 & 0x0F) << 0)) +#define FORMAT_YUVA ((0 << 5) + ((18 & 0x10) << 2) + ((18 & 0x0F) << 0)) +#define FORMAT_VUYA ((1 << 5) + ((18 & 0x10) << 2) + ((18 & 0x0F) << 0)) + +static void +PutYUV(PortPrivPtr pPPriv, int BufferBase, + int format, int bptshift, int alpha) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + ScrnInfoPtr pScrn = pAPriv->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + CookiePtr pCookie = pPPriv->pCookies; + int nCookies = pPPriv->nCookies; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "PutYUV %08x %08x\n", + BufferBase, format)); + + if (!nCookies || (GLINT_READ_REG(InFIFOSpace) < 200)) + return; /* Denial of service fix, N/A for scaler */ + + CHECKCLIPPING; + + GLINT_WRITE_REG(1 << 16, dY); + GLINT_WRITE_REG(0, RasterizerMode); + GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); + GLINT_WRITE_REG(pPPriv->dS, dSdx); + GLINT_WRITE_REG(0, dSdyDom); + GLINT_WRITE_REG(0, dTdx); + GLINT_WRITE_REG(pPPriv->dT, dTdyDom); + GLINT_WRITE_REG(BufferBase >> bptshift, PMTextureBaseAddress); + GLINT_WRITE_REG((bptshift << 19) | pPPriv->BufferPProd, PMTextureMapFormat); + GLINT_WRITE_REG(format, PMTextureDataFormat); + GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ + (11 << 13) | (11 << 9) | /* TextureSize log2 */ + UNIT_ENABLE, PMTextureReadMode); + GLINT_WRITE_REG((0 << 4) /* RGB */ | + (3 << 1) /* Copy */ | + UNIT_ENABLE, TextureColorMode); + if (alpha) + GLINT_WRITE_REG(pAPriv->dAlphaBlendMode, AlphaBlendMode); + GLINT_WRITE_REG(pAPriv->dDitherMode, DitherMode); + GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_WRITE_REG((alpha << 10) | /* ReadDestination */ + pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(0xFFFFFFFF, FBHardwareWriteMask); + GLINT_WRITE_REG(UNIT_ENABLE, YUVMode); + + for (; nCookies--; pCookie++) { + GLINT_WAIT(5); + GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); + GLINT_WRITE_REG(pCookie->wh, RectangleSize); + GLINT_WRITE_REG(pCookie->s, SStart); + GLINT_WRITE_REG(pCookie->t, TStart); + GLINT_WRITE_REG(PrimitiveRectangle | + XPositive | + YPositive | + TextureEnable, Render); + } + + pGlint->x = pGlint->y = -1; /* Force reload */ + pGlint->w = pGlint->h = -1; + pGlint->ROP = 0xFF; + pGlint->planemask = 0xFFFFFFFF; + + GLINT_WAIT(8); + GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat); + GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); + if (alpha) { + GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } + GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); +} + +#define FORMAT_RGB8888 ((0 << 5) + (0 << 4) + ((0 & 0x10) << 2) + ((0 & 0x0F) << 0)) +#define FORMAT_RGB565 ((0 << 5) + (1 << 4) + ((16 & 0x10) << 2) + ((16 & 0x0F) << 0)) +#define FORMAT_RGB5551 ((0 << 5) + (0 << 4) + ((1 & 0x10) << 2) + ((1 & 0x0F) << 0)) +#define FORMAT_RGB4444 ((0 << 5) + (0 << 4) + ((2 & 0x10) << 2) + ((2 & 0x0F) << 0)) +#define FORMAT_RGB332 ((0 << 5) + (1 << 4) + ((5 & 0x10) << 2) + ((5 & 0x0F) << 0)) +#define FORMAT_RGB2321 ((0 << 5) + (0 << 4) + ((9 & 0x10) << 2) + ((9 & 0x0F) << 0)) +#define FORMAT_BGR8888 ((1 << 5) + (0 << 4) + ((0 & 0x10) << 2) + ((0 & 0x0F) << 0)) +#define FORMAT_BGR565 ((1 << 5) + (1 << 4) + ((16 & 0x10) << 2) + ((16 & 0x0F) << 0)) +#define FORMAT_BGR5551 ((1 << 5) + (0 << 4) + ((1 & 0x10) << 2) + ((1 & 0x0F) << 0)) +#define FORMAT_BGR4444 ((1 << 5) + (0 << 4) + ((2 & 0x10) << 2) + ((2 & 0x0F) << 0)) +#define FORMAT_BGR332 ((1 << 5) + (1 << 4) + ((5 & 0x10) << 2) + ((5 & 0x0F) << 0)) +#define FORMAT_BGR2321 ((1 << 5) + (0 << 4) + ((9 & 0x10) << 2) + ((9 & 0x0F) << 0)) + +static void +PutRGB(PortPrivPtr pPPriv, int BufferBase, int format, int bptshift, int alpha) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + ScrnInfoPtr pScrn = pAPriv->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + CookiePtr pCookie = pPPriv->pCookies; + int nCookies = pPPriv->nCookies; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "PutRGB %08x %08x\n", + BufferBase, format)); + + if (!nCookies) + return; + + CHECKCLIPPING; + + GLINT_WRITE_REG(1 << 16, dY); + GLINT_WRITE_REG(0, RasterizerMode); + GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); + GLINT_WRITE_REG(pPPriv->dS, dSdx); + GLINT_WRITE_REG(0, dSdyDom); + GLINT_WRITE_REG(0, dTdx); + GLINT_WRITE_REG(pPPriv->dT, dTdyDom); + GLINT_WRITE_REG(BufferBase >> bptshift, PMTextureBaseAddress); + GLINT_WRITE_REG((bptshift << 19) | pPPriv->BufferPProd, PMTextureMapFormat); + GLINT_WRITE_REG(format, PMTextureDataFormat); + GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ + (11 << 13) | (11 << 9) | /* TextureSize log2 */ + UNIT_ENABLE, PMTextureReadMode); + GLINT_WRITE_REG((0 << 4) /* RGB */ | + (3 << 1) /* Copy */ | + UNIT_ENABLE, TextureColorMode); + if (alpha) + GLINT_WRITE_REG(pAPriv->dAlphaBlendMode, AlphaBlendMode); + GLINT_WRITE_REG(pAPriv->dDitherMode, DitherMode); + GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_WRITE_REG((alpha << 10) | /* ReadDestination */ + pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(0xFFFFFFFF, FBHardwareWriteMask); + + for (; nCookies--; pCookie++) { + GLINT_WAIT(5); + GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); + GLINT_WRITE_REG(pCookie->wh, RectangleSize); + GLINT_WRITE_REG(pCookie->s, SStart); + GLINT_WRITE_REG(pCookie->t, TStart); + GLINT_WRITE_REG(PrimitiveRectangle | + XPositive | + YPositive | + TextureEnable, Render); + } + + pGlint->x = pGlint->y = -1; /* Force reload */ + pGlint->w = pGlint->h = -1; + pGlint->ROP = 0xFF; + pGlint->planemask = 0xFFFFFFFF; + + GLINT_WAIT(7); + GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat); + GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); + if (alpha) { + GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } +} + +static void +BlackOut(PortPrivPtr pPPriv, RegionPtr pRegion) +{ + ScrnInfoPtr pScrn = pPPriv->pAdaptor->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + RegionRec DRegion; + BoxRec DBox; + BoxPtr pBox; + int nBox; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, + "BlackOut %d,%d,%d,%d -- %d,%d,%d,%d\n", + pPPriv->vx, pPPriv->vy, pPPriv->vw, pPPriv->vh, + pPPriv->dx, pPPriv->dy, pPPriv->dw, pPPriv->dh)); + + DBox.x1 = pPPriv->dx - (pPPriv->vx * pPPriv->dw) / pPPriv->vw; + DBox.y1 = pPPriv->dy - (pPPriv->vy * pPPriv->dh) / pPPriv->vh; + DBox.x2 = DBox.x1 + (pPPriv->fw * pPPriv->dw) / pPPriv->vw; + DBox.y2 = DBox.y1 + (pPPriv->fh * pPPriv->dh) / pPPriv->vh; + + REGION_INIT(pScreen, &DRegion, &DBox, 1); + + if (pRegion) + REGION_SUBTRACT(pScreen, &DRegion, &DRegion, pRegion); + + nBox = REGION_NUM_RECTS(&DRegion); + pBox = REGION_RECTS(&DRegion); + + GLINT_WAIT(15); + CHECKCLIPPING; + + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode); + GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */ + GLINT_WRITE_REG(pPPriv->BkgCol, FBBlockColor); + GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase); + GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + + for (; nBox--; pBox++) { + int w = ((pBox->x2 - pBox->x1) * pPPriv->vw + pPPriv->dw) / pPPriv->dw + 1; + int h = ((pBox->y2 - pBox->y1) * pPPriv->vh + pPPriv->dh) / pPPriv->dh + 1; + int x = ((pBox->x1 - DBox.x1) * pPPriv->vw + (pPPriv->dw >> 1)) / pPPriv->dw; + int y = ((pBox->y1 - DBox.y1) * pPPriv->vh + (pPPriv->dh >> 1)) / pPPriv->dh; + + if ((x + w) > pPPriv->fw) + w = pPPriv->fw - x; + if ((y + h) > pPPriv->fh) + h = pPPriv->fh - y; + + GLINT_WAIT(3); + GLINT_WRITE_REG((y << 16) | x, RectangleOrigin); + GLINT_WRITE_REG((h << 16) | w, RectangleSize); + GLINT_WRITE_REG(PrimitiveRectangle | + XPositive | YPositive | FastFillEnable, Render); + } + + REGION_UNINIT(pScreen, &DRegion); + + pGlint->x = pGlint->y = -1; /* Force reload */ + pGlint->w = pGlint->h = -1; + pGlint->ROP = 0xFF; + GLINT_WAIT(3); + GLINT_WRITE_REG(0, FBWindowBase); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel); +} + +static Bool +RemakeGetCookies(PortPrivPtr pPPriv, RegionPtr pRegion) +{ + BoxPtr pBox; + CookiePtr pCookie; + int nBox; + int dw1 = pPPriv->dw - 1; + int dh1 = pPPriv->dh - 1; + + if (!pRegion) { + pBox = (BoxPtr) NULL; + nBox = pPPriv->nCookies; + } else { + pBox = REGION_RECTS(pRegion); + nBox = REGION_NUM_RECTS(pRegion); + + if (!pPPriv->pCookies || pPPriv->nCookies < nBox) { + if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec)))) + return FALSE; + + pPPriv->pCookies = pCookie; + } + } + + pPPriv->dS = (pPPriv->dw << 20) / pPPriv->vw; + pPPriv->dT = (pPPriv->dh << 20) / pPPriv->vh; + + for (pCookie = pPPriv->pCookies; nBox--; pBox++) { + int n1, n2; + + if (pRegion) { + n1 = ((pBox->x1 - pPPriv->dx) * pPPriv->vw + dw1) / pPPriv->dw; + n2 = ((pBox->x2 - pPPriv->dx) * pPPriv->vw - 1) / pPPriv->dw; + + if (n1 > n2) + continue; /* Clip is subpixel */ + + pCookie->xy = n1 + pPPriv->vx; + pCookie->wh = n2 - n1 + 1; + pCookie->s = n1 * pPPriv->dS + (pPPriv->dx << 20); + pCookie->y1 = pBox->y1; + pCookie->y2 = pBox->y2; + } + + n1 = ((pCookie->y1 - pPPriv->dy) * pPPriv->vh + dh1) / pPPriv->dh; + n2 = ((pCookie->y2 - pPPriv->dy) * pPPriv->vh - 1) / pPPriv->dh; + pCookie->xy = (pCookie->xy & 0xFFFF) | ((n1 + pPPriv->vy) << 16); + pCookie->wh = (pCookie->wh & 0xFFFF) | ((n2 - n1 + 1) << 16); + pCookie->t = n1 * pPPriv->dT + (pPPriv->dy << 20); + if (n1 > n2) pCookie->t = -1; + + pCookie++; + } + + pPPriv->nCookies = pCookie - pPPriv->pCookies; + return TRUE; +} + +static void +GetYUV(PortPrivPtr pPPriv) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + ScrnInfoPtr pScrn = pAPriv->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + CookiePtr pCookie = pPPriv->pCookies; + int nCookies = pPPriv->nCookies; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "GetYUV\n")); + + if (!nCookies || (GLINT_READ_REG(InFIFOSpace) < 200)) + return; + + GLINT_WAIT(25); + CHECKCLIPPING; + + GLINT_WRITE_REG(1 << 16, dY); + GLINT_WRITE_REG(0, RasterizerMode); + GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode); + GLINT_WRITE_REG(pPPriv->dS, dSdx); + GLINT_WRITE_REG(0, dSdyDom); + GLINT_WRITE_REG(0, dTdx); + GLINT_WRITE_REG(pPPriv->dT, dTdyDom); + GLINT_WRITE_REG(0, PMTextureBaseAddress); + GLINT_WRITE_REG(pAPriv->dTextureDataFormat, PMTextureDataFormat); + GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */ + (11 << 13) | (11 << 9) | /* TextureSize log2 */ + UNIT_ENABLE, PMTextureReadMode); + if (pScrn->depth == 8) + GLINT_WRITE_REG(UNIT_ENABLE, TexelLUTMode); + GLINT_WRITE_REG((0 << 4) /* RGB */ | + (3 << 1) /* Copy */ | + UNIT_ENABLE, TextureColorMode); + GLINT_WRITE_REG((1 << 10) | /* RGB */ + ((16 & 0x10) << 12) | + ((16 & 0x0F) << 2) | /* 5:6:5f */ + UNIT_ENABLE, DitherMode); + GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode); + GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase); + GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */ + GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); + + for (; nCookies--; pCookie++) + if (pCookie->t >= 0) { + GLINT_WAIT(5); + GLINT_WRITE_REG(pCookie->xy, RectangleOrigin); + GLINT_WRITE_REG(pCookie->wh, RectangleSize); + GLINT_WRITE_REG(pCookie->s, SStart); + GLINT_WRITE_REG(pCookie->t, TStart); + GLINT_WRITE_REG(PrimitiveRectangle | + XPositive | + YPositive | + TextureEnable, Render); + } + + pGlint->x = pGlint->y = -1; /* Force reload */ + pGlint->w = pGlint->h = -1; + pGlint->ROP = 0xFF; + + GLINT_WAIT(9); + GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); + if (pScrn->depth == 8) + GLINT_WRITE_REG(UNIT_DISABLE, TexelLUTMode); + GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(0, FBWindowBase); + GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel); + GLINT_WRITE_REG(UNIT_DISABLE, YUVMode); +} + +static int +SetBkgCol(PortPrivPtr pPPriv, int value) +{ + pPPriv->Attribute[6] = value; + + pPPriv->BkgCol = ((value & 0xF80000) >> 8) | + ((value & 0x00FC00) >> 5) | + ((value & 0x0000F8) >> 3); + + pPPriv->BkgCol += pPPriv->BkgCol << 16; + + if (pPPriv->VideoOn) { + BlackOut(pPPriv, NULL); + GetYUV(pPPriv); + } + + return Success; +} + +/* os/WaitFor.c */ + +static CARD32 +TimerCallback(OsTimerPtr pTim, CARD32 now, pointer p) +{ + AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) p; + GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); + PortPrivPtr pPPriv; + int i, delay; + + if (!pAPriv->pm2p) { + pPPriv = &pAPriv->Port[0]; + + if (pPPriv->VideoOn > VIDEO_OFF) { + pPPriv->FrameAcc += pPPriv->FramesPerSec; + + if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { + pPPriv->FrameAcc -= pAPriv->FramesPerSec; + + PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ? + pPPriv->BufferBase[0] : pPPriv->BufferBase[1 - + GLINT_READ_REG(VSABase + VSVideoAddressIndex)], FORMAT_YUYV, 1, 0); + } + } else + if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { + StopVideoStream(pPPriv, TRUE); + RestoreVideoStd(pAPriv); + } + + pPPriv = &pAPriv->Port[1]; + + if (pPPriv->VideoOn > VIDEO_OFF) { + pPPriv->FrameAcc += pPPriv->FramesPerSec; + + if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { + pPPriv->FrameAcc -= pAPriv->FramesPerSec; + + GetYUV(pPPriv); + } + } else + if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { + StopVideoStream(pPPriv, TRUE); + RestoreVideoStd(pAPriv); + } + } + + for (i = 2; i <= 5; i++) { + if (pAPriv->Port[i].StopDelay >= 0) { + if (!(pAPriv->Port[i].StopDelay--)) { + FreeBuffers(&pAPriv->Port[i]); + FreeCookies(&pAPriv->Port[i]); + pAPriv->TimerUsers &= ~(1 << i); + } + } + } + + if (!pAPriv->pm2p) { + if (pAPriv->Port[0].StreamOn) { + delay = GLINT_READ_REG(VSABase + VSCurrentLine); + + if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0A)) + delay += pAPriv->FrameLines >> 1; + + if (delay > (pAPriv->IntLine - 16)) + delay -= pAPriv->FrameLines; + + return (((pAPriv->IntLine - delay) * pAPriv->LinePer) + 999999) / 1000000; + } else if (pAPriv->Port[1].StreamOn) { + delay = GLINT_READ_REG(VSBBase + VSCurrentLine); + + if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0B)) + delay += pAPriv->FrameLines >> 1; + + if (delay > (pAPriv->IntLine - 16)) + delay -= pAPriv->FrameLines; + + return (((pAPriv->IntLine - delay) * pAPriv->LinePer) + 999999) / 1000000; + } + } + + if (pAPriv->TimerUsers) + return pAPriv->Instant; + + return 0; /* Cancel */ +} + + +/* + * Video stream (bounce buffer <-> hardware) + */ + +static void +StopVideoStream(PortPrivPtr pPPriv, Bool shutdown) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); + int VideoOn; + + pPPriv->StopDelay = -1; + + VideoOn = pPPriv->VideoOn; + pPPriv->VideoOn = VIDEO_OFF; + + if (!pPPriv->StreamOn) + return; + + if (pAPriv->pm2p) { + xvipcHandshake(pPPriv, OP_STOP, TRUE); + + pPPriv->StreamOn = FALSE; + + if (shutdown) + FreeCookies(pPPriv); + + if (VideoOn > VIDEO_OFF && pGlint->NoAccel) + Permedia2Sync(pAPriv->pScrn); + + return; + } + + if (pPPriv == &pAPriv->Port[0]) { + int line, eeek = 0; + + do { + if (eeek++ > 1000000) break; + line = GLINT_READ_REG(VSABase + VSCurrentLine); + } while (line > 15); + + GLINT_WRITE_REG(0, VSABase + VSControl); + + pAPriv->Port[0].StreamOn = FALSE; + + usleep(80000); + } else { + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83); + if (!ColorBars) + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); + + GLINT_WRITE_REG(0, VSBBase + VSControl); + + pAPriv->Port[1].StreamOn = FALSE; + } + + if (!pAPriv->Port[0].StreamOn && !pAPriv->Port[1].StreamOn) { + if (shutdown) + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2); + xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x00); + } + + if (shutdown) { + FreeBuffers(pPPriv); + FreeCookies(pPPriv); + + if (pAPriv->TimerUsers) { + pAPriv->TimerUsers &= ~PORTNUM(pPPriv); + if (!pAPriv->TimerUsers) + TimerCancel(pAPriv->Timer); + } + + if (VideoOn > VIDEO_OFF && pGlint->NoAccel) + Permedia2Sync(pAPriv->pScrn); + } +} + +static Bool +StartVideoStream(PortPrivPtr pPPriv, RegionPtr pRegion) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); + + if (pAPriv->VideoStd < 0) + return FALSE; + + pPPriv->StopDelay = -1; + + if (pAPriv->pm2p) { + if (pPPriv == &pAPriv->Port[0]) { + if (!RemakePutCookies(pPPriv, pRegion)) + return FALSE; + if (pPPriv->StreamOn) + return TRUE; + } else { + if (!RemakeGetCookies(pPPriv, pRegion)) + return FALSE; + if (pPPriv->StreamOn) { + BlackOut(pPPriv, pRegion); + return TRUE; + } + } + + xvipc.a = pPPriv->BuffersRequested; + xvipc.b = !pPPriv->Attribute[4]; + xvipc.c = 1 + (pPPriv->Attribute[4] & 2); + + if (!xvipcHandshake(pPPriv, OP_START, TRUE)) + return FALSE; + + if (pPPriv == &pAPriv->Port[1]) { + pPPriv->BufferBase[0] = xvipc.d; + BlackOut(pPPriv, pRegion); + } + + return pPPriv->StreamOn = TRUE; + } else { + CARD32 Base = (pPPriv == &pAPriv->Port[0]) ? VSABase : VSBBase; + + if (pPPriv->BuffersAllocated < pPPriv->BuffersRequested) { + int height = ((pAPriv->VideoStd == NTSC) ? 512 : 608) >> (!pPPriv->Attribute[4]); + + if (!AllocateBuffers(pPPriv, 704, height, 2, pPPriv->BuffersRequested, 0)) + return FALSE; + + pPPriv->fw = 704; + pPPriv->fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> + (!pPPriv->Attribute[4]); + } + + if (pPPriv == &pAPriv->Port[0]) { + if (!RemakePutCookies(pPPriv, pRegion)) + return FALSE; + } else { + if (!RemakeGetCookies(pPPriv, pRegion)) + return FALSE; + + BlackOut(pPPriv, pRegion); + } + + if (pPPriv->StreamOn) + return TRUE; + + GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress0); + if (pPPriv->pFBArea[1]) + GLINT_WRITE_REG(pPPriv->BufferBase[1] / 8, Base + VSVideoAddress1); + else + GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress1); + GLINT_WRITE_REG(pPPriv->BufferStride / 8, Base + VSVideoStride); + + GLINT_WRITE_REG(0, Base + VSCurrentLine); + + if (pAPriv->VideoStd == NTSC) { + GLINT_WRITE_REG(16, Base + VSVideoStartLine); + GLINT_WRITE_REG(16 + 240, Base + VSVideoEndLine); + GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData); + GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData); + } else { + GLINT_WRITE_REG(16, Base + VSVideoStartLine); + GLINT_WRITE_REG(16 + 288, Base + VSVideoEndLine); + GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData); + GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData); + } + + GLINT_WRITE_REG(2, Base + VSVideoAddressHost); + GLINT_WRITE_REG(0, Base + VSVideoAddressIndex); + + if (pPPriv == &pAPriv->Port[0]) { + int line, eeek = 0; + + xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D); + + do { + if (eeek++ > 1000000) break; + line = GLINT_READ_REG(VSABase + VSCurrentLine); + } while (line > 15); + + GLINT_WRITE_REG(VSA_Video | + (pPPriv->Attribute[4] ? + VSA_CombineFields : VSA_Discard_FieldTwo), + VSABase + VSControl); + if (ColorBars) + if (!pAPriv->Port[1].StreamOn) { + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83); + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]); + } + } else { + GLINT_WRITE_REG(VSB_Video | + (pPPriv->Attribute[4] ? VSB_CombineFields : 0) | + /* VSB_GammaCorrect | */ + (16 << 4) | /* 5:6:5 */ + (1 << 9) | /* 16 */ + VSB_RGBOrder, VSBBase + VSControl); + xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D); + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, Enc3A[pPPriv->Plug]); + xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]); + } + + pAPriv->TimerUsers |= 1 << PORTNUM(pPPriv); + TimerSet(pAPriv->Timer, 0, 80, TimerCallback, pAPriv); + + return pPPriv->StreamOn = TRUE; + } + + return FALSE; +} + + +/* + * Xv interface + */ + +static int +Permedia2PutVideo(ScrnInfoPtr pScrn, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int sw, sh; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "PutVideo %d,%d,%d,%d -> %d,%d,%d,%d\n", + vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); + + sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; + sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; + + if ((vid_x + vid_w) > sw || + (vid_y + vid_h) > sh) + return BadValue; + + pPPriv->VideoOn = VIDEO_OFF; + + pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw; + pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh; + pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw; + pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh; + + pPPriv->dx = drw_x; + pPPriv->dy = drw_y; + pPPriv->dw = drw_w; + pPPriv->dh = drw_h; + + pPPriv->FrameAcc = pAPriv->FramesPerSec; + + if (!StartVideoStream(pPPriv, clipBoxes)) + return XvBadAlloc; + + pPPriv->VideoOn = VIDEO_ON; + + return Success; +} + +static int +Permedia2PutStill(ScrnInfoPtr pScrn, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + GLINTPtr pGlint = GLINTPTR(pScrn); + int sw, sh, r = Success; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "PutStill %d,%d,%d,%d -> %d,%d,%d,%d\n", + vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); + + sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; + sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; + + if ((vid_x + vid_w) > sw || + (vid_y + vid_h) > sh) + return BadValue; + + pPPriv->VideoOn = VIDEO_OFF; + + pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw; + pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh; + pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw; + pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh; + + pPPriv->dx = drw_x; + pPPriv->dy = drw_y; + pPPriv->dw = drw_w; + pPPriv->dh = drw_h; + + pPPriv->FrameAcc = pAPriv->FramesPerSec; + + if (!StartVideoStream(pPPriv, clipBoxes)) + return XvBadAlloc; + + if (pAPriv->pm2p) { + /* Sleep, not busy wait, until the very next frame is ready. + Accept memory requests and other window's update events + in the meantime. */ + for (pPPriv->VideoOn = VIDEO_ONE_SHOT; pPPriv->VideoOn;) + if (!xvipcHandshake(pPPriv, OP_UPDATE, TRUE)) { + r = FALSE; + break; + } + } else { + usleep(80000); + + PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ? + pPPriv->BufferBase[0] : pPPriv->BufferBase[1 - + GLINT_READ_REG(VSABase + VSVideoAddressIndex)], FORMAT_YUYV, 1, 0); + } + + pPPriv->StopDelay = 125; + + return r; +} + +static int +Permedia2GetVideo(ScrnInfoPtr pScrn, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int sw, sh; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "GetVideo %d,%d,%d,%d <- %d,%d,%d,%d\n", + vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); + + sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; + sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; + + if ((vid_x + vid_w) > sw || + (vid_y + vid_h) > sh) { + return BadValue; + } + + pPPriv->VideoOn = VIDEO_OFF; + + pPPriv->vx = (vid_x * pPPriv->fw) / sw; + pPPriv->vy = (vid_y * pPPriv->fh) / sh; + pPPriv->vw = (vid_w * pPPriv->fw) / sw; + pPPriv->vh = (vid_h * pPPriv->fh) / sh; + + pPPriv->dx = drw_x; + pPPriv->dy = drw_y; + pPPriv->dw = drw_w; + pPPriv->dh = drw_h; + + pPPriv->FrameAcc = pAPriv->FramesPerSec; + + if (!StartVideoStream(pPPriv, clipBoxes)) { + return XvBadAlloc; + } + + GetYUV(pPPriv); + + pPPriv->VideoOn = VIDEO_ON; + + return Success; +} + +static int +Permedia2GetStill(ScrnInfoPtr pScrn, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int sw, sh; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "GetStill %d,%d,%d,%d <- %d,%d,%d,%d\n", + vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h)); + + sw = InputVideoEncodings[pAPriv->VideoStd * 3].width; + sh = InputVideoEncodings[pAPriv->VideoStd * 3].height; + + if ((vid_x + vid_w) > sw || + (vid_y + vid_h) > sh) + return BadValue; + + pPPriv->VideoOn = VIDEO_OFF; + + pPPriv->vx = (vid_x * pPPriv->fw) / sw; + pPPriv->vy = (vid_y * pPPriv->fh) / sh; + pPPriv->vw = (vid_w * pPPriv->fw) / sw; + pPPriv->vh = (vid_h * pPPriv->fh) / sh; + + pPPriv->dx = drw_x; + pPPriv->dy = drw_y; + pPPriv->dw = drw_w; + pPPriv->dh = drw_h; + + pPPriv->FrameAcc = pAPriv->FramesPerSec; + + if (!StartVideoStream(pPPriv, clipBoxes)) + return XvBadAlloc; + + GetYUV(pPPriv); + + return Success; +} + +static void +CopyYV12LE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch) +{ + int Y_size = width * height; + CARD8 *V = Y + Y_size; + CARD8 *U = V + (Y_size >> 2); + int pad = (pitch >> 2) - (width >> 1); + int x; + + width >>= 1; + + for (height >>= 1; height > 0; height--) { + for (x = 0; x < width; Y += 2, x++) + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); + dst += pad; + for (x = 0; x < width; Y += 2, x++) + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); + dst += pad; + U += width; + V += width; + } +} + +#if X_BYTE_ORDER == X_BIG_ENDIAN + +static void +CopyYV12BE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch) +{ + int Y_size = width * height; + CARD8 *V = Y + Y_size; + CARD8 *U = V + (Y_size >> 2); + int pad = (pitch >> 2) - (width >> 1); + int x; + + width >>= 1; + + for (height >>= 1; height > 0; height--) { + for (x = 0; x < width; Y += 2, x++) + *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); + dst += pad; + for (x = 0; x < width; Y += 2, x++) + *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); + dst += pad; + U += width; + V += width; + } +} + +#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ + +static void +CopyFlat(CARD8 *src, CARD8 *dst, int width, int height, int pitch) +{ + if (width == pitch) { + memcpy(dst, src, width * height); + return; + } + + while (height > 0) { + memcpy(dst, src, width); + dst += pitch; + src += width; + height--; + } +} + +static int +Permedia2PutImage(ScrnInfoPtr pScrn, + short src_x, short src_y, short drw_x, short drw_y, + short src_w, short src_h, short drw_w, short drw_h, + int id, unsigned char *buf, short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "PutImage %d,%d,%d,%d -> %d,%d,%d,%d id=0x%08x buf=%p w=%d h=%d sync=%d\n", + src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, + id, buf, width, height, sync)); + + if ((src_x + src_w) > width || + (src_y + src_h) > height) + return BadValue; + + pPPriv->vx = src_x << 10; + pPPriv->vy = src_y << 10; + pPPriv->vw = src_w << 10; + pPPriv->vh = src_h << 10; + + pPPriv->dx = drw_x; + pPPriv->dy = drw_y; + pPPriv->dw = drw_w; + pPPriv->dh = drw_h; + + if (!RemakePutCookies(pPPriv, clipBoxes)) + return XvBadAlloc; + + if (pPPriv->BuffersAllocated <= 0 || + id != pPPriv->Id || /* same bpp */ + width != pPPriv->fw || + height != pPPriv->fh) + { + for (i = 0; i < ENTRIES(ScalerImages); i++) + if (id == ScalerImages[i].id) + break; + + if (i >= ENTRIES(ScalerImages)) + return XvBadAlloc; +#if 0 + if (pPPriv->BuffersAllocated <= 0 || + pPPriv->Bpp != ScalerImages[i].bits_per_pixel || + width > pPPriv->fw || height > pPPriv->fw || + pPPriv->fw * pPPriv->fh > width * height * 2) +#else + if (1) +#endif + { + Permedia2Sync(pScrn); + + if (!AllocateBuffers(pPPriv, width, height, + (ScalerImages[i].bits_per_pixel + 7) >> 3, 1, 0)) { + pPPriv->Id = 0; + pPPriv->Bpp = 0; + pPPriv->fw = 0; + pPPriv->fh = 0; + + return XvBadAlloc; + } + + pPPriv->Id = id; + pPPriv->Bpp = ScalerImages[i].bits_per_pixel; + pPPriv->fw = width; + pPPriv->fh = height; + + RemoveableBuffers(pPPriv, TRUE); + } else + Permedia2Sync(pScrn); + } else + Permedia2Sync(pScrn); + + switch (id) { + case LE4CC('Y','V','1','2'): +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), + width, height, pPPriv->BufferStride); +#else + if (pGlint->FBDev) + CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), + width, height, pPPriv->BufferStride); + else + CopyYV12BE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]), + width, height, pPPriv->BufferStride); +#endif + PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUYV, 1, 0); + break; + + case LE4CC('Y','U','Y','2'): + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUYV, 1, 0); + break; + + case LE4CC('U','Y','V','Y'): + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_UYVY, 1, 0); + break; + + case LE4CC('Y','U','V','A'): + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 2, height, pPPriv->BufferStride); + PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUVA, 2, pPPriv->Attribute[7]); + break; + + case LE4CC('V','U','Y','A'): + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 2, height, pPPriv->BufferStride); + PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_VUYA, 2, pPPriv->Attribute[7]); + break; + + case 0x41: /* RGBA 8:8:8:8 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 2, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB8888, 2, pPPriv->Attribute[7]); + break; + + case 0x42: /* RGB 5:6:5 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB565, 1, 0); + break; + + case 0x43: /* RGB 1:5:5:5 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB5551, 1, pPPriv->Attribute[7]); + break; + + case 0x44: /* RGB 4:4:4:4 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB4444, 1, pPPriv->Attribute[7]); + break; + + case 0x45: /* RGB 1:2:3:2 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB2321, 0, pPPriv->Attribute[7]); + break; + + case 0x46: /* RGB 2:3:3 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_RGB332, 0, 0); + break; + + case 0x47: /* BGRA 8:8:8:8 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 2, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR8888, 2, pPPriv->Attribute[7]); + break; + + case 0x48: /* BGR 5:6:5 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR565, 1, 0); + break; + + case 0x49: /* BGR 1:5:5:5 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR5551, 1, pPPriv->Attribute[7]); + break; + + case 0x4A: /* BGR 4:4:4:4 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 1, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR4444, 1, pPPriv->Attribute[7]); + break; + + case 0x4B: /* BGR 1:2:3:2 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 0, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR2321, 0, pPPriv->Attribute[7]); + break; + + case 0x4C: /* BGR 2:3:3 */ + CopyFlat(buf, (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0], + width << 0, height, pPPriv->BufferStride); + PutRGB(pPPriv, pPPriv->BufferBase[0], FORMAT_BGR332, 0, 0); + break; + + default: + return XvBadAlloc; + } + + pPPriv->StopDelay = pAPriv->Delay; + + if (!pAPriv->TimerUsers) { + pAPriv->TimerUsers |= 1 << PORTNUM(pPPriv); + TimerSet(pAPriv->Timer, 0, 80, TimerCallback, pAPriv); + } + + if (sync) /* sched_yield? */ + Permedia2Sync(pScrn); + + return Success; +} + +static void +Permedia2StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + GLINTPtr pGlint = GLINTPTR(pScrn); + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "StopVideo port=%d, shutdown=%d\n", PORTNUM(pPPriv), shutdown)); + + if (shutdown) { + if (PORTNUM(pPPriv) < 2) { + StopVideoStream(pPPriv, TRUE); + RestoreVideoStd(pAPriv); + } else { + FreeBuffers(pPPriv); + FreeCookies(pPPriv); + if (pAPriv->TimerUsers) { + pAPriv->TimerUsers &= ~PORTNUM(pPPriv); + if (!pAPriv->TimerUsers) + TimerCancel(pAPriv->Timer); + } + } + } else { + pPPriv->VideoOn = VIDEO_OFF; + pPPriv->StopDelay = 750; /* appx. 30 sec */ + + if (pGlint->NoAccel) + Permedia2Sync(pScrn); + } +} + +static void +RestartVideo(PortPrivPtr pPPriv, int old_VideoOn) +{ + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int new_fh; + + if (pPPriv->VideoOn > VIDEO_OFF || + pAPriv->VideoStd < 0 /* invalid */) + return; + + new_fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> + (1 - (pPPriv->Attribute[4] & 1)); + + if (new_fh != pPPriv->fh) { + pPPriv->vy = (pPPriv->vy * new_fh) / pPPriv->fh; + pPPriv->vh = (pPPriv->vh * new_fh) / pPPriv->fh; + + pPPriv->fh = new_fh; + } + + if (old_VideoOn) { + if (StartVideoStream(pPPriv, NULL)) { + pPPriv->VideoOn = old_VideoOn; + + if (pPPriv == &pAPriv->Port[1]) + GetYUV(pPPriv); + } else { + DEBUG(xf86DrvMsgVerb(pAPriv->pScrn->scrnIndex, X_INFO, 4, + "RestartVideo port=%d suspend\n", PORTNUM(pPPriv))); + pPPriv->VideoOn = -old_VideoOn; /* suspend (not off) */ + } + } +} + +static int +Permedia2SetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + int old_VideoStd, old_Plug; + int VideoStd = -1, Plug = 0; + int r; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "SPA attr=%d val=%d port=%d\n", + attribute, value, PORTNUM(pPPriv))); + + if (attribute == xvFilter) { + pPPriv->Attribute[5] = !!value; + return Success; + } else if (attribute == xvAlpha) { + pPPriv->Attribute[7] = !!value; + return Success; + } + + if (PORTNUM(pPPriv) >= 2) + return BadMatch; + + if (attribute == xvInterlace) { + int old_value = pPPriv->Attribute[4]; + + value %= 3; + + if (value != old_value) { + int old_VideoOn = ABS(pPPriv->VideoOn); +#if 0 + if (old_VideoOn) + return XvBadAlloc; +#endif + StopVideoStream(pPPriv, FALSE); + FreeBuffers(pPPriv); + pPPriv->Attribute[4] = value; + RestartVideo(pPPriv, old_VideoOn); + + if (pPPriv->VideoOn < 0 /* suspended */) { + pPPriv->Attribute[4] = old_value; + RestartVideo(pPPriv, old_VideoOn); + return XvBadAlloc; + } + } + + return Success; + } + + if (pPPriv == &pAPriv->Port[0]) { + /* + * Input + */ + if (attribute == xvEncoding) { + if (value < 0 || value > ENTRIES(InputVideoEncodings)) + return XvBadEncoding; + + VideoStd = value / 3; + Plug = value % 3; + + /* Fall through */ + + } else if (attribute == xvBrightness) + return SetAttr(&pAPriv->Port[0], 0, value); + else if (attribute == xvContrast) + return SetAttr(&pAPriv->Port[0], 1, value); + else if (attribute == xvSaturation) + return SetAttr(&pAPriv->Port[0], 2, value); + else if (attribute == xvHue) + return SetAttr(&pAPriv->Port[0], 3, value); + } else { + /* + * Output + */ + if (attribute == xvEncoding) { + if (value < 0 || value > ENTRIES(OutputVideoEncodings)) + return XvBadEncoding; + + VideoStd = value / 2; + Plug = (value % 2) + 1; + + /* Fall through */ + + } else if (attribute == xvBkgColor) + return SetBkgCol(pPPriv, value); +#if 1 + else if (attribute == xvBrightness || + attribute == xvContrast || + attribute == xvSaturation || + attribute == xvHue) + return Success; +#endif + } + + if (attribute != xvEncoding) + return BadMatch; + + old_VideoStd = pAPriv->VideoStd; + old_Plug = pPPriv->Plug; + +#if 0 + if (pAPriv->Port[0].VideoOn || + pAPriv->Port[1].VideoOn) + return XvBadAlloc; +#endif + + if (Plug != old_Plug) + if ((r = SetPlug(pPPriv, Plug)) != Success) + return r; + + if (VideoStd != old_VideoStd) { + int old_VideoOn0 = ABS(pAPriv->Port[0].VideoOn); + int old_VideoOn1 = ABS(pAPriv->Port[1].VideoOn); + + StopVideoStream(&pAPriv->Port[0], FALSE); + StopVideoStream(&pAPriv->Port[1], FALSE); + + if (VideoStd == NTSC || pAPriv->VideoStd == NTSC) { + FreeBuffers(&pAPriv->Port[0]); + FreeBuffers(&pAPriv->Port[1]); + } + + if (SetVideoStd(pPPriv, VideoStd) == Success) { + RestartVideo(&pAPriv->Port[0], old_VideoOn0); + RestartVideo(&pAPriv->Port[1], old_VideoOn1); + } + + if (pAPriv->Port[0].VideoOn < 0 || + pAPriv->Port[1].VideoOn < 0 || + VideoStd != pAPriv->VideoStd) { + if (SetVideoStd(pPPriv, old_VideoStd) == Success) { + RestartVideo(&pAPriv->Port[0], old_VideoOn0); + RestartVideo(&pAPriv->Port[1], old_VideoOn1); + } + + if (Plug != old_Plug) + SetPlug(pPPriv, old_Plug); + + return XvBadAlloc; + } + } + + return Success; +} + +static void +RestoreVideoStd(AdaptorPrivPtr pAPriv) +{ + if (pAPriv->Port[0].VideoOn && !pAPriv->Port[1].VideoOn && + pAPriv->Port[0].VideoStdReq != pAPriv->VideoStd) + Permedia2SetPortAttribute(pAPriv->pScrn, xvEncoding, + pAPriv->Port[0].VideoStdReq * 3 + pAPriv->Port[0].Plug, + (pointer) &pAPriv->Port[0]); + else + if (pAPriv->Port[1].VideoOn && !pAPriv->Port[0].VideoOn && + pAPriv->Port[1].VideoStdReq != pAPriv->VideoStd) + Permedia2SetPortAttribute(pAPriv->pScrn, xvEncoding, + pAPriv->Port[2].VideoStdReq * 2 + pAPriv->Port[1].Plug - 1, + (pointer) &pAPriv->Port[1]); +} + +static int +Permedia2GetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 *value, pointer data) +{ + PortPrivPtr pPPriv = (PortPrivPtr) data; + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + + if (PORTNUM(pPPriv) >= 2 && + attribute != xvFilter && + attribute != xvAlpha) + return BadMatch; + + if (attribute == xvEncoding) { + if (pAPriv->VideoStd < 0) + return XvBadAlloc; + else + if (pPPriv == &pAPriv->Port[0]) + *value = pAPriv->VideoStd * 3 + pPPriv->Plug; + else + *value = pAPriv->VideoStd * 2 + pPPriv->Plug - 1; + } else if (attribute == xvBrightness) + *value = pPPriv->Attribute[0]; + else if (attribute == xvContrast) + *value = pPPriv->Attribute[1]; + else if (attribute == xvSaturation) + *value = pPPriv->Attribute[2]; + else if (attribute == xvHue) + *value = pPPriv->Attribute[3]; + else if (attribute == xvInterlace) + *value = pPPriv->Attribute[4]; + else if (attribute == xvFilter) + *value = pPPriv->Attribute[5]; + else if (attribute == xvBkgColor) + *value = pPPriv->Attribute[6]; + else if (attribute == xvAlpha) + *value = pPPriv->Attribute[7]; + else + return BadMatch; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "GPA attr=%d val=%d port=%d\n", + attribute, *value, PORTNUM(pPPriv))); + + return Success; +} + +static void +Permedia2QueryBestSize(ScrnInfoPtr pScrn, Bool motion, + short vid_w, short vid_h, short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, pointer data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + +static int +Permedia2QueryImageAttributes(ScrnInfoPtr pScrn, + int id, unsigned short *width, unsigned short *height, + int *pitches, int *offsets) +{ + int i, pitch; + + *width = CLAMP(*width, 1, 2047); + *height = CLAMP(*height, 1, 2047); + + if (offsets) + offsets[0] = 0; + + switch (id) { + case LE4CC('Y','V','1','2'): /* Planar YVU 4:2:0 (emulated) */ + *width = CLAMP((*width + 1) & ~1, 2, 2046); + *height = CLAMP((*height + 1) & ~1, 2, 2046); + + pitch = *width; /* luma component */ + + if (offsets) { + offsets[1] = pitch * *height; + offsets[2] = offsets[1] + (offsets[1] >> 2); + } + + if (pitches) { + pitches[0] = pitch; + pitches[1] = pitches[2] = pitch >> 1; + } + + return pitch * *height * 3 / 2; + + case LE4CC('Y','U','Y','2'): /* Packed YUYV 4:2:2 */ + case LE4CC('U','Y','V','Y'): /* Packed UYVY 4:2:2 */ + *width = CLAMP((*width + 1) & ~1, 2, 2046); + + pitch = *width * 2; + + if (pitches) + pitches[0] = pitch; + + return pitch * *height; + + default: + for (i = 0; i < ENTRIES(ScalerImages); i++) + if (ScalerImages[i].id == id) + break; + + if (i >= ENTRIES(ScalerImages)) + break; + + pitch = *width * (ScalerImages[i].bits_per_pixel >> 3); + + if (pitches) + pitches[0] = pitch; + + return pitch * *height; + } + + return 0; +} + +static void +RestoreVideo(AdaptorPrivPtr pAPriv) +{ + GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); + + GLINT_WRITE_REG(pAPriv->dFifoControl, PMFifoControl); + GLINT_WRITE_REG(0, VSABase + VSControl); + GLINT_WRITE_REG(0, VSBBase + VSControl); + usleep(160000); + GLINT_MASK_WRITE_REG(VS_UnitMode_ROM, ~VS_UnitMode_Mask, VSConfiguration); +} + +static void +InitializeVideo(AdaptorPrivPtr pAPriv) +{ + GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn); + int i; + + GLINT_WRITE_REG(0, VSABase + VSControl); + GLINT_WRITE_REG(0, VSBBase + VSControl); + +#if 0 + GLINT_MASK_WRITE_REG(0, ~(VSAIntFlag | VSBIntFlag), IntEnable); + GLINT_WRITE_REG(VSAIntFlag | VSBIntFlag, IntFlags); /* Reset */ +#endif + + for (i = 0x0018; i <= 0x00B0; i += 8) { + GLINT_WRITE_REG(0, VSABase + i); + GLINT_WRITE_REG(0, VSBBase + i); + } + + GLINT_WRITE_REG((0 << 8) | (132 << 0), VSABase + VSFifoControl); + GLINT_WRITE_REG((0 << 8) | (132 << 0), VSBBase + VSFifoControl); + + GLINT_MASK_WRITE_REG( + VS_UnitMode_AB8 | + VS_GPBusMode_A | + /* VS_HRefPolarityA | */ + VS_VRefPolarityA | + VS_VActivePolarityA | + /* VS_UseFieldA | */ + VS_FieldPolarityA | + /* VS_FieldEdgeA | */ + /* VS_VActiveVBIA | */ + VS_InterlaceA | + VS_ReverseDataA | + + /* VS_HRefPolarityB | */ + VS_VRefPolarityB | + VS_VActivePolarityB | + /* VS_UseFieldB | */ + VS_FieldPolarityB | + /* VS_FieldEdgeB | */ + /* VS_VActiveVBIB | */ + VS_InterlaceB | + /* VS_ColorSpaceB_RGB | */ + /* VS_ReverseDataB | */ + /* VS_DoubleEdgeB | */ + 0, ~0x1FFFFE0F, VSConfiguration); + + pAPriv->dFifoControl = GLINT_READ_REG(PMFifoControl); + GLINT_WRITE_REG((12 << 8) | 8, PMFifoControl); +} + +static Bool +xvipcHandshake(PortPrivPtr pPPriv, int op, Bool block) +{ + int r; + int brake = 150; + + xvipc.magic = XVIPC_MAGIC; + xvipc.op = op; + xvipc.block = block; + + if (pPPriv) { + AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; + + xvipc.pm2p = pAPriv->pm2p; + xvipc.pAPriv = pAPriv; + xvipc.port = PORTNUM(pPPriv); + } else { + xvipc.pm2p = (void *) -1; + xvipc.pAPriv = NULL; + xvipc.port = -1; + } + + for (;;) { + if (brake-- <= 0) + return FALSE; /* I brake for bugs. */ + + DEBUG(xf86MsgVerb(X_INFO, 4, + "PM2 XVIPC send op=%d bl=%d po=%d a=%d b=%d c=%d\n", + xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c)); + + r = ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc); + + DEBUG(xf86MsgVerb(X_INFO, 4, + "PM2 XVIPC recv op=%d bl=%d po=%d a=%d b=%d c=%d err=%d/%d\n", + xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c, r, errno)); + + switch (xvipc.op) { + case OP_ALLOC: + { + AdaptorPrivPtr pAPriv = xvipc.pAPriv; + ScrnInfoPtr pScrn = pAPriv->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + FBAreaPtr pFBArea = NULL; + LFBAreaPtr pLFBArea; + + xvipc.a = -1; + + pLFBArea = xalloc(sizeof(LFBAreaRec)); + + if (pLFBArea) { + pLFBArea->pFBArea = pFBArea = + xf86AllocateLinearOffscreenArea(pScrn->pScreen, + xvipc.b >> BPPSHIFT(pGlint), 2, NULL, NULL, NULL); + + if (pFBArea) { + /* xvipc.a = pFBArea->linear; */ + pLFBArea->Linear = xvipc.a = + ((pFBArea->box.y1 * pScrn->displayWidth) + + pFBArea->box.x1) << BPPSHIFT(pGlint); + } else + xfree(pLFBArea); + } + + /* Report results */ + + if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) != 0) + if (pFBArea) { + xf86FreeOffscreenArea(pFBArea); + xfree(pLFBArea); + pFBArea = NULL; + } + + if (pFBArea) { + pLFBArea->Next = pAPriv->LFBList; + pAPriv->LFBList = pLFBArea; + } + + DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC alloc addr=%d=0x%08x pFB=%p\n", + xvipc.a, xvipc.a, pFBArea)); + + goto event; + } + + case OP_FREE: + { + AdaptorPrivPtr pAPriv = xvipc.pAPriv; + LFBAreaPtr pLFBArea, *ppLFBArea; + + for (ppLFBArea = &pAPriv->LFBList; (pLFBArea = *ppLFBArea); + ppLFBArea = &pLFBArea->Next) + if (pLFBArea->Linear == xvipc.a) + break; + + if (!pLFBArea) + xvipc.a = -1; + + DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC free addr=%d=0x%08x pFB=%p\n", + xvipc.a, xvipc.a, pLFBArea ? pLFBArea->pFBArea : NULL)); + + if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) == 0 && pLFBArea) { + xf86FreeOffscreenArea(pLFBArea->pFBArea); + *ppLFBArea = pLFBArea->Next; + xfree(pLFBArea); + } + + goto event; + } + + case OP_UPDATE: + { + AdaptorPrivPtr pAPriv = xvipc.pAPriv; + PortPrivPtr pPPriv; + + pPPriv = &pAPriv->Port[0]; + + if (pPPriv->VideoOn > VIDEO_OFF && xvipc.a > 0) { + pPPriv->FrameAcc += pPPriv->FramesPerSec; + if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { + pPPriv->FrameAcc -= pAPriv->FramesPerSec; + + /* Asynchronous resizing caused by kernel app */ + + if (xvipc.c != pPPriv->fw || + xvipc.d != pPPriv->fh) { + pPPriv->vx = (pPPriv->vx * xvipc.c) / pPPriv->fw; + pPPriv->vw = (pPPriv->vw * xvipc.c) / pPPriv->fw; + pPPriv->vy = (pPPriv->vy * xvipc.d) / pPPriv->fh; + pPPriv->vh = (pPPriv->vh * xvipc.d) / pPPriv->fh; + + pPPriv->fw = xvipc.c; + pPPriv->fh = xvipc.d; + pPPriv->BufferPProd = xvipc.e; + + RemakePutCookies(pPPriv, NULL); + } + + PutYUV(pPPriv, xvipc.a, FORMAT_YUYV, 1, 0); + + if (pPPriv->VideoOn == VIDEO_ONE_SHOT) + pPPriv->VideoOn = VIDEO_OFF; + } + } else + if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { + StopVideoStream(pPPriv, TRUE); + RestoreVideoStd(pAPriv); + } + + pPPriv = &pAPriv->Port[1]; + + if (pPPriv->VideoOn > VIDEO_OFF && xvipc.b > 0) { + pPPriv->FrameAcc += pPPriv->FramesPerSec; + if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) { + pPPriv->FrameAcc -= pAPriv->FramesPerSec; + + pPPriv->BufferBase[0] = xvipc.b; + + /* Output is always exclusive, no async resizing */ + + GetYUV(pPPriv); + + if (pPPriv->VideoOn == VIDEO_ONE_SHOT) + pPPriv->VideoOn = VIDEO_OFF; + } + } else + if (pPPriv->StopDelay >= 0 && !(pPPriv->StopDelay--)) { + StopVideoStream(pPPriv, TRUE); + RestoreVideoStd(pAPriv); + } + + /* Fall through */ + } + + default: + event: + if (xvipc.op == op) + return r == 0; + + xvipc.op = OP_EVENT; + xvipc.block = block; + } + } + + return TRUE; +} + +static void +Permedia2ReadInput(int fd, pointer unused) +{ + xvipcHandshake(NULL, OP_EVENT, FALSE); +} + +static Bool +xvipcOpen(char *name, ScrnInfoPtr pScrn) +{ + const char *osname; + + if (xvipc_fd >= 0) + return TRUE; + + xf86GetOS(&osname, NULL, NULL, NULL); + + if (!osname || strcmp(osname, "linux")) + return FALSE; + + for (;;) { + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, + "XVIPC probing device %s\n", name)); + + if ((xvipc_fd = open(name, O_RDWR /* | O_TRUNC */, 0)) < 0) + break; + + xvipc.magic = XVIPC_MAGIC; + xvipc.pm2p = (void *) -1; + xvipc.pAPriv = NULL; + xvipc.op = OP_CONNECT; + xvipc.a = 0; + xvipc.b = 0; + xvipc.c = 0; + xvipc.d = 0; + + if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0 || xvipc.pm2p) + break; + + if (xvipc.c != XVIPC_VERSION) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Your Permedia 2 kernel driver %d.%d uses XVIPC protocol " + "V.%d while this Xv driver expects V.%d. Please update.\n", + xvipc.a, xvipc.b, xvipc.c, XVIPC_VERSION); + break; + } + + xf86AddInputHandler(xvipc_fd, Permedia2ReadInput, NULL); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv driver opened %s\n", name); + + return TRUE; + } + + if (xvipc_fd >= 0) + close(xvipc_fd); + + xvipc_fd = -1; + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cannot find Permedia 2 kernel driver.\n"); + + return FALSE; +} + +static void +DeleteAdaptorPriv(AdaptorPrivPtr pAPriv) +{ + int i; + + if (pAPriv->VideoIO) { + StopVideoStream(&pAPriv->Port[0], TRUE); + StopVideoStream(&pAPriv->Port[1], TRUE); + } + + for (i = 0; i < 6; i++) { + FreeBuffers(&pAPriv->Port[i]); + FreeCookies(&pAPriv->Port[i]); + } + + TimerFree(pAPriv->Timer); + + if (pAPriv->VideoIO) { + if (pAPriv->pm2p) + xvipcHandshake(&pAPriv->Port[0], OP_DISCONNECT, TRUE); + else { + xf86DestroyI2CDevRec(&pAPriv->Port[0].I2CDev, FALSE); + xf86DestroyI2CDevRec(&pAPriv->Port[1].I2CDev, FALSE); + + RestoreVideo(pAPriv); + } + } + + xfree(pAPriv); +} + +static AdaptorPrivPtr +NewAdaptorPriv(ScrnInfoPtr pScrn, Bool VideoIO) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) xcalloc(1, sizeof(AdaptorPrivRec)); + int i; + + if (!pAPriv) + return NULL; + + pAPriv->pScrn = pScrn; + + for (i = 0; i < PORTS; i++) + pAPriv->Port[i].pAdaptor = pAPriv; + + switch (pScrn->depth) { + case 8: + pAPriv->dDitherMode = + (0 << 10) | /* BGR */ + (1 << 1) | /* Dither */ + ((5 & 0x10) << 12) | + ((5 & 0x0F) << 2) | /* 3:3:2f */ + UNIT_ENABLE; + pAPriv->dAlphaBlendMode = + (0 << 13) | + ((5 & 0x10) << 12) | + ((5 & 0x0F) << 8) | + (84 << 1) | /* Blend (decal) RGB */ + UNIT_ENABLE; + pAPriv->dTextureDataFormat = + (1 << 4) | /* No alpha */ + ((14 & 0x10) << 2) | + ((14 & 0x0F) << 0); /* CI8 */ + break; + + case 15: + pAPriv->dDitherMode = + (1 << 10) | /* RGB */ + ((1 & 0x10) << 12) | + ((1 & 0x0F) << 2) | /* 5:5:5:1f */ + UNIT_ENABLE; + pAPriv->dAlphaBlendMode = + (1 << 13) | + ((1 & 0x10) << 12) | + ((1 & 0x0F) << 8) | + (84 << 1) | + UNIT_ENABLE; + pAPriv->dTextureDataFormat = + (1 << 5) | /* RGB */ + (1 << 4) | + ((1 & 0x10) << 2) | + ((1 & 0x0F) << 0); + break; + + case 16: + pAPriv->dDitherMode = + (1 << 10) | /* RGB */ + ((16 & 0x10) << 12) | + ((16 & 0x0F) << 2) | /* 5:6:5f */ + UNIT_ENABLE; + pAPriv->dAlphaBlendMode = + (1 << 13) | + ((16 & 0x10) << 12) | + ((16 & 0x0F) << 8) | + (84 << 1) | + UNIT_ENABLE; + pAPriv->dTextureDataFormat = + (1 << 5) | + (1 << 4) | + ((16 & 0x10) << 2) | + ((16 & 0x0F) << 0); + break; + + case 24: + pAPriv->dDitherMode = + (1 << 10) | /* RGB */ + ((0 & 0x10) << 12) | + ((0 & 0x0F) << 2) | /* 8:8:8:8 */ + UNIT_ENABLE; + pAPriv->dAlphaBlendMode = + (1 << 13) | + ((0 & 0x10) << 12) | + ((0 & 0x0F) << 8) | + (84 << 1) | + UNIT_ENABLE; + pAPriv->dTextureDataFormat = + (1 << 5) | + (1 << 4) | + ((0 & 0x10) << 2) | + ((0 & 0x0F) << 0); + break; + + default: + xfree(pAPriv); + return NULL; + } + + pAPriv->VideoIO = VideoIO; + + if (VideoIO) { + if (xvipc_fd >= 0) { + /* Initial handshake, take over control of this head */ + + xvipc.magic = XVIPC_MAGIC; + xvipc.pm2p = (void *) -1; /* Kernel head ID */ + xvipc.pAPriv = pAPriv; /* Server head ID */ + xvipc.op = OP_CONNECT; + + xvipc.a = pGlint->PciInfo->bus; + xvipc.b = pGlint->PciInfo->device; + xvipc.c = pGlint->PciInfo->func; + + xvipc.d = pScrn->videoRam << 10; /* XF86Config overrides probing */ + + if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0) { + if (errno == EBUSY) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Another application already opened the Permedia 2 " + "kernel driver for this board. To enable " + "shared access please start the server first.\n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to initialize kernel backbone " + "due to error %d: %s.\n", errno, strerror(errno)); + goto failed; + } + + pAPriv->pm2p = xvipc.pm2p; + } else { + InitializeVideo(pAPriv); + + if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7111_SLAVE_ADDRESS)) + goto failed; + + pAPriv->Port[0].I2CDev.DevName = "Decoder SAA 7111A"; + pAPriv->Port[0].I2CDev.SlaveAddr = SAA7111_SLAVE_ADDRESS; + pAPriv->Port[0].I2CDev.pI2CBus = pGlint->VSBus; + + if (!xf86I2CDevInit(&pAPriv->Port[0].I2CDev)) + goto failed; + + if (!xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, DecInitVec, ENTRIES(DecInitVec) / 2)) + goto failed; + + if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7125_SLAVE_ADDRESS)) + goto failed; + + pAPriv->Port[1].I2CDev.DevName = "Encoder SAA 7125"; + pAPriv->Port[1].I2CDev.SlaveAddr = SAA7125_SLAVE_ADDRESS; + pAPriv->Port[1].I2CDev.pI2CBus = pGlint->VSBus; + + if (!xf86I2CDevInit(&pAPriv->Port[1].I2CDev)) + goto failed; + + if (!xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, EncInitVec, ENTRIES(EncInitVec) / 2)) + goto failed; + } + + if (SetVideoStd(&pAPriv->Port[0], PAL) != Success || + SetPlug(&pAPriv->Port[0], 0) != Success || /* composite */ + SetPlug(&pAPriv->Port[1], 1) != Success) /* composite-adaptor */ + goto failed; + + pAPriv->Port[1].VideoStdReq = pAPriv->Port[0].VideoStdReq; + + pAPriv->Port[0].BuffersRequested = 2; + pAPriv->Port[1].BuffersRequested = 1; + + for (i = 0; i < 2; i++) { + pAPriv->Port[i].fw = 704; + pAPriv->Port[i].fh = 576; + pAPriv->Port[i].FramesPerSec = 30; + pAPriv->Port[i].BufferPProd = partprodPermedia[704 >> 5]; + } + + SetAttr(&pAPriv->Port[0], 0, 0); /* Brightness (-1000..+1000) */ + SetAttr(&pAPriv->Port[0], 1, 0); /* Contrast (-3000..+1000) */ + SetAttr(&pAPriv->Port[0], 2, 0); /* Color saturation (-3000..+1000) */ + SetAttr(&pAPriv->Port[0], 3, 0); /* Hue (-1000..+1000) */ + + pAPriv->Port[0].Attribute[4] = 1; /* Interlaced (0 = not, 1 = yes, + 2 = double scan 50/60 Hz) */ + pAPriv->Port[0].Attribute[5] = 0; /* Bilinear Filter (Bool) */ + + pAPriv->Port[1].Attribute[4] = 1; /* Interlaced (Bool) */ + pAPriv->Port[1].Attribute[5] = 0; /* Bilinear Filter (Bool) */ + + SetBkgCol(&pAPriv->Port[1], 0x000000); /* BkgColor 0x00RRGGBB */ + } /* VideoIO */ + + if (!(pAPriv->Timer = TimerSet(NULL, 0, 0, TimerCallback, pAPriv))) + goto failed; + + for (i = 0; i < PORTS; i++) + pAPriv->Port[i].StopDelay = -1; + + /* Frontend scaler */ + + for (i = 2; i < 6; i++) { + pAPriv->Port[i].fw = 0; + pAPriv->Port[i].fh = 0; + pAPriv->Port[i].BuffersRequested = 1; + pAPriv->Delay = 125; + pAPriv->Instant = 1000 / 25; + + if (!VideoIO || pAPriv->pm2p) { + pAPriv->Delay = 5; + pAPriv->Instant = 1000; + } + + pAPriv->Port[i].Attribute[5] = 0; /* Bilinear Filter (Bool) */ + pAPriv->Port[i].Attribute[7] = 0; /* Alpha Enable (Bool) */ + } + + return pAPriv; + +failed: + + DeleteAdaptorPriv(pAPriv); + + return NULL; +} + + +/* + * Glint interface + */ + +void +Permedia2VideoEnterVT(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + AdaptorPrivPtr pAPriv; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv enter VT\n")); + + for (pAPriv = AdaptorPrivList; pAPriv != NULL; pAPriv = pAPriv->Next) + if (pAPriv->pScrn == pScrn) { + if (pAPriv->VideoIO) { + if (pAPriv->pm2p) + xvipcHandshake(&pAPriv->Port[0], OP_ENTER, TRUE); + else { + InitializeVideo(pAPriv); + + xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, EncInitVec, ENTRIES(EncInitVec) / 2); + } + + SetVideoStd(&pAPriv->Port[0], pAPriv->VideoStd); + SetPlug(&pAPriv->Port[0], pAPriv->Port[0].Plug); + SetPlug(&pAPriv->Port[1], pAPriv->Port[1].Plug); + } + + if (pGlint->NoAccel) + Permedia2InitializeEngine(pScrn); + + break; + } +} + +void +Permedia2VideoLeaveVT(ScrnInfoPtr pScrn) +{ + AdaptorPrivPtr pAPriv; + + for (pAPriv = AdaptorPrivList; pAPriv != NULL; pAPriv = pAPriv->Next) + if (pAPriv->pScrn == pScrn) { + if (pAPriv->VideoIO) { + StopVideoStream(&pAPriv->Port[0], TRUE); + StopVideoStream(&pAPriv->Port[1], TRUE); + + if (pAPriv->pm2p) + xvipcHandshake(&pAPriv->Port[0], OP_LEAVE, TRUE); + else + RestoreVideo(pAPriv); + } + break; + } + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Elvis left the building\n")); +} + +void +Permedia2VideoUninit(ScrnInfoPtr pScrn) +{ + AdaptorPrivPtr pAPriv, *ppAPriv; + + for (ppAPriv = &AdaptorPrivList; (pAPriv = *ppAPriv); ppAPriv = &(pAPriv->Next)) + if (pAPriv->pScrn == pScrn) { + *ppAPriv = pAPriv->Next; + DeleteAdaptorPriv(pAPriv); + break; + } + + if (xvipc_fd >= 0) { + close(xvipc_fd); + xvipc_fd = -1; + } + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv cleanup\n")); +} + +void +Permedia2VideoInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + AdaptorPrivPtr pAPriv; + pointer options[3]; + DevUnion Private[PORTS]; + XF86VideoAdaptorRec VAR[ADAPTORS]; + XF86VideoAdaptorPtr VARPtrs[ADAPTORS]; + Bool VideoIO = TRUE; + int i; + + switch (pGlint->Chipset) { + case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: + break; + + default: + return; + } + + options[0] = NULL; /* VideoAdaptor "input" subsection options */ + options[1] = NULL; /* VideoAdaptor "output" subsection options */ + options[2] = NULL; /* VideoAdaptor options */ + + for (i = 0;; i++) { + char *adaptor; /* receives VideoAdaptor section identifier */ + + if (!options[0]) + options[0] = xf86FindXvOptions(pScreen->myNum, i, "input", &adaptor, options[2] ? NULL : &options[2]); + + if (!options[1]) + options[1] = xf86FindXvOptions(pScreen->myNum, i, "output", &adaptor, options[2] ? NULL : &options[2]); + + if (!adaptor) { + if (!i) /* VideoAdaptor reference enables Xv vio driver */ + VideoIO = FALSE; + break; + } else if (options[0] && options[1]) + break; + } + + if (VideoIO) + switch (pciReadLong(pGlint->PciTag, PCI_SUBSYSTEM_ID_REG)) { + case PCI_SUBSYSTEM_ID_WINNER_2000_P2A: + case PCI_SUBSYSTEM_ID_WINNER_2000_P2C: + case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A: + case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C: + break; + + default: + xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 1, "No Xv vio support for this board\n"); + VideoIO = FALSE; + } + + if (pGlint->NoAccel && !VideoIO) + return; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Initializing Xv driver rev. 4\n"); + + if (VideoIO) { + for (i = 0; i <= 2; i++) { + xf86ProcessOptions(pScrn->scrnIndex, options[i], + (i == 0) ? InputOptions : + (i == 1) ? OutputOptions : + AdaptorOptions); + + xf86ShowUnusedOptions(pScrn->scrnIndex, options[i]); + } + + if (xf86IsOptionSet(AdaptorOptions, OPTION_DEVICE)) { + if (!xvipcOpen(xf86GetOptValString(AdaptorOptions, OPTION_DEVICE), pScrn)) + VideoIO = FALSE; + } + } + + if (!(pAPriv = NewAdaptorPriv(pScrn, VideoIO))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv driver initialization failed\n"); + return; + } + + if (VideoIO) { + int n; + + if (xf86GetOptValInteger(InputOptions, OPTION_BUFFERS, &n)) + pAPriv->Port[0].BuffersRequested = CLAMP(n, 1, 2); + if (xf86GetOptValInteger(InputOptions, OPTION_FPS, &n)) + pAPriv->Port[0].FramesPerSec = CLAMP(n, 1, 30); + + if (xf86GetOptValInteger(OutputOptions, OPTION_BUFFERS, &n)) + pAPriv->Port[1].BuffersRequested = 1; + if (xf86GetOptValInteger(OutputOptions, OPTION_FPS, &n)) + pAPriv->Port[1].FramesPerSec = CLAMP(n, 1, 30); + } + + if (pGlint->NoAccel) { + BoxRec AvailFBArea; + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Xv driver overrides NoAccel option\n"); + + Permedia2InitializeEngine(pScrn); + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pGlint->FbMapSize / + (pScrn->displayWidth * pScrn->bitsPerPixel / 8); + + xf86InitFBManager(pScreen, &AvailFBArea); + } + +#if defined(XFree86LOADER) && 0 + if (xf86LoaderCheckSymbol("xf86InitLinearFBManagerRegion")) { + int last = pGlint->FbMapSize / (pScrn->bitsPerPixel / 8) - 1; + BoxRec AvailFBArea; + RegionPtr Region; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = pScrn->virtualY; + AvailFBArea.x2 = last % pScrn->displayWidth + 1; + AvailFBArea.y2 = last / pScrn->displayWidth + 1; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, + "Using linear FB %d,%d-%d,%d pitch %d (%dk)\n", + AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2, + pScrn->displayWidth, (((AvailFBArea.y2 - AvailFBArea.y1) + * pScrn->displayWidth) << BPPSHIFT(pGlint)) / 1024)); + + Region = xf86LinearFBRegion(pScreen, &AvailFBArea, pScrn->displayWidth); + xf86InitLinearFBManagerRegion(pScreen, Region); + REGION_DESTROY(pScreen, Region); + } +#endif + + memset(VAR, 0, sizeof(VAR)); + + for (i = 0; i < PORTS; i++) + Private[i].ptr = (pointer) &pAPriv->Port[i]; + + for (i = 0; i < ADAPTORS; i++) { + VARPtrs[i] = &VAR[i]; + switch (i) { + case 0: + VAR[i].name = "Permedia 2 Video Input"; + VAR[i].type = XvInputMask | XvWindowMask | XvVideoMask | XvStillMask; + VAR[i].nPorts = 1; + VAR[i].pPortPrivates = &Private[0]; + VAR[i].nAttributes = ENTRIES(InputVideoAttributes); + VAR[i].pAttributes = InputVideoAttributes; + VAR[i].nEncodings = ENTRIES(InputVideoEncodings); + VAR[i].pEncodings = InputVideoEncodings; + VAR[i].nFormats = ENTRIES(InputVideoFormats); + VAR[i].pFormats = InputVideoFormats; + break; + + case 1: + VAR[i].name = "Permedia 2 Video Output"; + VAR[i].type = XvOutputMask | XvWindowMask | XvVideoMask | XvStillMask; + VAR[i].nPorts = 1; + VAR[i].pPortPrivates = &Private[1]; + VAR[i].nAttributes = ENTRIES(OutputVideoAttributes); + VAR[i].pAttributes = OutputVideoAttributes; + VAR[i].nEncodings = ENTRIES(OutputVideoEncodings); + VAR[i].pEncodings = OutputVideoEncodings; + VAR[i].nFormats = ENTRIES(OutputVideoFormats); + VAR[i].pFormats = OutputVideoFormats; + break; + + case 2: + VAR[i].name = "Permedia 2 Frontend Scaler"; + VAR[i].type = XvInputMask | XvWindowMask | XvImageMask; + VAR[i].nPorts = 3; + VAR[i].pPortPrivates = &Private[2]; + VAR[i].nAttributes = ENTRIES(ScalerAttributes); + VAR[i].pAttributes = ScalerAttributes; + VAR[i].nEncodings = ENTRIES(ScalerEncodings); + VAR[i].pEncodings = ScalerEncodings; + VAR[i].nFormats = ENTRIES(ScalerVideoFormats); + VAR[i].pFormats = ScalerVideoFormats; + VAR[i].nImages = ENTRIES(ScalerImages); + VAR[i].pImages = ScalerImages; + break; + } + + VAR[i].PutVideo = Permedia2PutVideo; + VAR[i].PutStill = Permedia2PutStill; + VAR[i].GetVideo = Permedia2GetVideo; + VAR[i].GetStill = Permedia2GetStill; + VAR[i].StopVideo = Permedia2StopVideo; + VAR[i].SetPortAttribute = Permedia2SetPortAttribute; + VAR[i].GetPortAttribute = Permedia2GetPortAttribute; + VAR[i].QueryBestSize = Permedia2QueryBestSize; + VAR[i].PutImage = Permedia2PutImage; + VAR[i].QueryImageAttributes = Permedia2QueryImageAttributes; + } + + if (VideoIO ? xf86XVScreenInit(pScreen, &VARPtrs[0], 3) : + xf86XVScreenInit(pScreen, &VARPtrs[2], 1)) { + char *s; + + xvEncoding = MAKE_ATOM(XV_ENCODING); + xvHue = MAKE_ATOM(XV_HUE); + xvSaturation = MAKE_ATOM(XV_SATURATION); + xvBrightness = MAKE_ATOM(XV_BRIGHTNESS); + xvContrast = MAKE_ATOM(XV_CONTRAST); + xvInterlace = MAKE_ATOM(XV_INTERLACE); + xvFilter = MAKE_ATOM(XV_FILTER); + xvBkgColor = MAKE_ATOM(XV_BKGCOLOR); + xvAlpha = MAKE_ATOM(XV_ALPHA); + + pAPriv->Next = AdaptorPrivList; + AdaptorPrivList = pAPriv; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv frontend scaler enabled\n"); + + if (VideoIO) { + if ((s = xf86GetOptValString(InputOptions, OPTION_ENCODING))) + for (i = 0; i < ENTRIES(InputVideoEncodings); i++) + if (!strncmp(s, InputVideoEncodings[i].name, strlen(s))) { + Permedia2SetPortAttribute(pScrn, xvEncoding, i, (pointer) &pAPriv->Port[0]); + break; + } + + if ((s = xf86GetOptValString(OutputOptions, OPTION_ENCODING))) + for (i = 0; i < ENTRIES(OutputVideoEncodings); i++) + if (!strncmp(s, OutputVideoEncodings[i].name, strlen(s))) { + Permedia2SetPortAttribute(pScrn, xvEncoding, i, (pointer) &pAPriv->Port[1]); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv vio driver %senabled\n", + pAPriv->pm2p ? "with kernel backbone " : ""); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n"); + DeleteAdaptorPriv(pAPriv); + } +} + +#endif /* XvExtension */ diff --git a/src/pm2ramdac.c b/src/pm2ramdac.c new file mode 100644 index 0000000..dddfcaa --- /dev/null +++ b/src/pm2ramdac.c @@ -0,0 +1,165 @@ +/* + * Copyright 1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Permedia2OutIndReg() and Permedia2InIndReg() are used to access + * the indirect Permedia2 RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c,v 1.11 2000/12/22 10:39:24 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "glint_regs.h" +#include "glint.h" + +void +Permedia2OutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char tmp = 0x00; + + GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg); + + if (mask != 0x00) + tmp = GLINT_READ_REG (PM2DACIndexData) & mask; + + GLINT_SLOW_WRITE_REG (tmp | data, PM2DACIndexData); +} + +unsigned char +Permedia2InIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + + GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg); + ret = GLINT_READ_REG (PM2DACIndexData); + + return (ret); +} + +void +Permedia2WriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(index, PM2DACWriteAddress); +} + +void +Permedia2WriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(data, PM2DACData); +} + +void +Permedia2ReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask); + GLINT_SLOW_WRITE_REG(index, PM2DACReadAddress); +} + +unsigned char +Permedia2ReadData (ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTDACDelay(5); + return(GLINT_READ_REG(PM2DACData)); +} + +void Permedia2LoadPalette( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i, index, shift = 0, j, repeat = 1; + + if (pScrn->depth == 15) { + repeat = 8; + shift = 3; + } + + for(i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < repeat; j++) { + Permedia2WriteAddress(pScrn, (index << shift)+j); + Permedia2WriteData(pScrn, colors[index].red); + Permedia2WriteData(pScrn, colors[index].green); + Permedia2WriteData(pScrn, colors[index].blue); + } + /* for video i/o */ + GLINT_SLOW_WRITE_REG(index, TexelLUTIndex); + GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | + ((colors[index].green & 0xFF) << 8) | + ((colors[index].blue & 0xFF) << 16), + TexelLUTData); + } +} + +/* special one for 565 mode */ +void Permedia2LoadPalette16( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i, index, j; + + for(i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 4; j++) { + Permedia2WriteAddress(pScrn, (index << 2)+j); + Permedia2WriteData(pScrn, colors[index >> 1].red); + Permedia2WriteData(pScrn, colors[index].green); + Permedia2WriteData(pScrn, colors[index >> 1].blue); + } + GLINT_SLOW_WRITE_REG(index, TexelLUTIndex); + GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | + ((colors[index].green & 0xFF) << 8) | + ((colors[index].blue & 0xFF) << 16), + TexelLUTData); + + if(index <= 31) { + for (j = 0; j < 4; j++) { + Permedia2WriteAddress(pScrn, (index << 3)+j); + Permedia2WriteData(pScrn, colors[index].red); + Permedia2WriteData(pScrn, colors[(index << 1) + 1].green); + Permedia2WriteData(pScrn, colors[index].blue); + } + } + } +} diff --git a/src/pm2v_dac.c b/src/pm2v_dac.c new file mode 100644 index 0000000..0fd10ca --- /dev/null +++ b/src/pm2v_dac.c @@ -0,0 +1,567 @@ +/* + * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Helmut Fahrion, <hf@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c,v 1.29 2002/05/07 23:15:59 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "glint_regs.h" +#include "glint.h" + +static unsigned long +PM2VDAC_CalculateClock +( + unsigned long reqclock, /* In kHz units */ + unsigned long refclock, /* In kHz units */ + unsigned char *prescale, /* ClkPreScale */ + unsigned char *feedback, /* ClkFeedBackScale */ + unsigned char *postscale /* ClkPostScale */ + ) +{ + int f, pre, post; + unsigned long freq; + long freqerr = 1000; + unsigned long actualclock = 0; + unsigned char divide[5] = { 1, 2, 4, 8, 16 }; + + for (f=1;f<256;f++) { + for (pre=1;pre<256;pre++) { + for (post=0;post<2;post++) { + freq = ((refclock * f) / (pre * (1 << divide[post]))); + if ((reqclock > freq - freqerr)&&(reqclock < freq + freqerr)){ + freqerr = (reqclock > freq) ? + reqclock - freq : freq - reqclock; + *feedback = f; + *prescale = pre; + *postscale = post; + actualclock = freq; + } + } + } + } + + return(actualclock); +} + +static void +Permedia2VPreInitSecondary(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* disable MCLK */ + Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 0); + + /* boot new mclk values */ + Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPreScale, 0x00, 0x09); + Permedia2vOutIndReg(pScrn, PM2VDACRDMClkFeedbackScale, 0x00, 0x58); + Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPostScale, 0x00, 0x01); + + /* re-enable MCLK */ + Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 1); + + /* spin until locked MCLK */ + while ( (Permedia2vInIndReg(pScrn, PM2VDACRDMClkControl) & 0x2) == 0); + + /* Now re-boot the SGRAM's */ + GLINT_SLOW_WRITE_REG(0xe6002021,PMMemConfig); + GLINT_SLOW_WRITE_REG(0x00000020,PMBootAddress); +} + +void +Permedia2VPreInit(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (IS_JPRO) { + /* Appian Jeronimo Pro 4x8mb (pm2v version) */ + /* BIOS doesn't initialize the secondary heads, so we need to */ + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Appian Jeronimo Pro 4x8mb board detected and initialized.\n"); + + Permedia2VPreInitSecondary(pScrn); + } + +#if defined(__alpha__) + /* + * On Alpha, we have to init secondary PM2V cards, since + * int10 cannot be run on the OEMed cards with VGA disable + * jumpers. + */ + if (!xf86IsPrimaryPci(pGlint->PciInfo)) { + if ( IS_QPM2V ) { + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PM2V secondary: initializing\n"); + Permedia2VPreInitSecondary(pScrn); + } + } +#endif /* __alpha__ */ +} + +Bool +Permedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTRegPtr pReg = &pGlint->ModeReg[0]; + CARD32 temp1, temp2, temp3, temp4; + + temp1 = 0; + temp2 = 0; +#if X_BYTE_ORDER == X_BIG_ENDIAN + switch (pGlint->HwBpp) { + case 8: + case 24: + temp1 = 0x00; + temp2 = 0x00; + break; + + case 15: + case 16: + temp1 = 0x02; + temp2 = 0x02; + break; + + case 32: + temp1 = 0x01; + temp2 = 0x01; + break; + default: + break; + }; +#endif /* BIG_ENDIAN */ + + pReg->glintRegs[Aperture0 >> 3] = temp1; + pReg->glintRegs[Aperture1 >> 3] = temp2; + + pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; + pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; + + pReg->glintRegs[DFIFODis >> 3] = 0; + pReg->glintRegs[FIFODis >> 3] = 1; + + if (pGlint->UseBlockWrite) + pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21; + + temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; + temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; + temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); + pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); + pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); + pReg->glintRegs[PMHbEnd >> 3] = + Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay); + pReg->glintRegs[PMScreenStride >> 3] = + Shiftbpp(pScrn,pScrn->displayWidth>>1); + + pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; + pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; + pReg->glintRegs[PMVsStart >> 3] = temp2; + pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; + + /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick + both sync lines to active low here and if needed invert them + using the RAMDAC's RDSyncControl below. */ + pReg->glintRegs[PMVideoControl >> 3] = + (1 << 5) | (1 << 3) | 1; + + /* We stick the RAMDAC into 64bit mode */ + /* And reduce the horizontal timings and clock by half */ + pReg->glintRegs[PMVideoControl >> 3] |= 1<<16; + pReg->glintRegs[PMHTotal >> 3] >>= 1; + pReg->glintRegs[PMHsEnd >> 3] >>= 1; + pReg->glintRegs[PMHsStart >> 3] >>= 1; + pReg->glintRegs[PMHbEnd >> 3] >>= 1; + + pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); + pReg->glintRegs[PMScreenBase >> 3] = 0; + pReg->glintRegs[PMHTotal >> 3] -= 1; + pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */ + pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */ + + pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD; + pReg->DacRegs[PM2VDACRDDACControl] = 0x00; + + { + /* Get the programmable clock values */ + unsigned char m,n,p; + unsigned long clockused; + + clockused = PM2VDAC_CalculateClock(mode->Clock/2,pGlint->RefClock, + &m,&n,&p); + pReg->DacRegs[PM2VDACRDDClk0PreScale] = m; + pReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = n; + pReg->DacRegs[PM2VDACRDDClk0PostScale] = p; + } + + pReg->glintRegs[PM2VDACRDIndexControl >> 3] = 0x00; + + if (pScrn->rgbBits == 8) + pReg->DacRegs[PM2VDACRDMiscControl] = 0x01; /* 8bit DAC */ + else + pReg->DacRegs[PM2VDACRDMiscControl] = 0x00; /* 6bit DAC */ + + pReg->DacRegs[PM2VDACRDSyncControl] = 0x00; + if (mode->Flags & V_PHSYNC) + pReg->DacRegs[PM2VDACRDSyncControl] |= 0x01; /* invert hsync */ + if (mode->Flags & V_PVSYNC) + pReg->DacRegs[PM2VDACRDSyncControl] |= 0x08; /* invert vsync */ + + switch (pScrn->bitsPerPixel) + { + case 8: + pReg->DacRegs[PM2VDACRDPixelSize] = 0x00; + pReg->DacRegs[PM2VDACRDColorFormat] = 0x2E; + break; + case 16: + pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; + pReg->DacRegs[PM2VDACRDPixelSize] = 0x01; + if (pScrn->depth == 15) + pReg->DacRegs[PM2VDACRDColorFormat] = 0x61; + else + pReg->DacRegs[PM2VDACRDColorFormat] = 0x70; + break; + case 24: + pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; + pReg->DacRegs[PM2VDACRDPixelSize] = 0x04; + pReg->DacRegs[PM2VDACRDColorFormat] = 0x60; + break; + case 32: + pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; + pReg->DacRegs[PM2VDACRDPixelSize] = 0x02; + pReg->DacRegs[PM2VDACRDColorFormat] = 0x20; + if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { + pReg->DacRegs[PM2VDACRDMiscControl] |= 0x18; + pReg->DacRegs[PM2VDACRDOverlayKey] = pScrn->colorKey; + } + break; + } + + return(TRUE); +} + +void +Permedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information */ + memcpy((CARD8*)pGlint->VGAdata,(CARD8*)pGlint->FbBase, 65536); + + glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); + glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); + glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); + glintReg->glintRegs[PMFramebufferWriteMask >> 3] = + GLINT_READ_REG(PMFramebufferWriteMask); + glintReg->glintRegs[PMBypassWriteMask >> 3] = + GLINT_READ_REG(PMBypassWriteMask); + glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); + glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); + /* We only muck about with PMMemConfig, if user wants to */ + if (pGlint->UseBlockWrite) + glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig); + glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); + glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); + glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd); + glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); + glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); + glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); + glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); + glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); + glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); + glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); + glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); + glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); + glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); + + for (i=0;i<768;i++) { + Permedia2ReadAddress(pScrn, i); + glintReg->cmap[i] = Permedia2ReadData(pScrn); + } + + glintReg->glintRegs[PM2VDACRDIndexControl >> 3] = + GLINT_READ_REG(PM2VDACRDIndexControl); + glintReg->DacRegs[PM2VDACRDOverlayKey] = + Permedia2vInIndReg(pScrn, PM2VDACRDOverlayKey); + glintReg->DacRegs[PM2VDACRDSyncControl] = + Permedia2vInIndReg(pScrn, PM2VDACRDSyncControl); + glintReg->DacRegs[PM2VDACRDMiscControl] = + Permedia2vInIndReg(pScrn, PM2VDACRDMiscControl); + glintReg->DacRegs[PM2VDACRDDACControl] = + Permedia2vInIndReg(pScrn, PM2VDACRDDACControl); + glintReg->DacRegs[PM2VDACRDPixelSize] = + Permedia2vInIndReg(pScrn, PM2VDACRDPixelSize); + glintReg->DacRegs[PM2VDACRDColorFormat] = + Permedia2vInIndReg(pScrn, PM2VDACRDColorFormat); + + glintReg->DacRegs[PM2VDACRDDClk0PreScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PreScale); + glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0FeedbackScale); + glintReg->DacRegs[PM2VDACRDDClk0PostScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PostScale); +} + +void +Permedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 temp; + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information */ + if (pGlint->STATE) + memcpy((CARD8*)pGlint->FbBase,(CARD8*)pGlint->VGAdata, 65536); + + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3], + PMFramebufferWriteMask); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3], + PMBypassWriteMask); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis); + /* We only muck about with PMMemConfig, if user wants to */ + if (pGlint->UseBlockWrite) + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3], + PMVideoControl); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3], + PMScreenStride); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart); + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd); + + GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PM2VDACRDIndexControl >> 3], + PM2VDACRDIndexControl); + Permedia2vOutIndReg(pScrn, PM2VDACRDOverlayKey, 0x00, + glintReg->DacRegs[PM2VDACRDOverlayKey]); + Permedia2vOutIndReg(pScrn, PM2VDACRDSyncControl, 0x00, + glintReg->DacRegs[PM2VDACRDSyncControl]); + Permedia2vOutIndReg(pScrn, PM2VDACRDMiscControl, 0x00, + glintReg->DacRegs[PM2VDACRDMiscControl]); + Permedia2vOutIndReg(pScrn, PM2VDACRDDACControl, 0x00, + glintReg->DacRegs[PM2VDACRDDACControl]); + Permedia2vOutIndReg(pScrn, PM2VDACRDPixelSize, 0x00, + glintReg->DacRegs[PM2VDACRDPixelSize]); + Permedia2vOutIndReg(pScrn, PM2VDACRDColorFormat, 0x00, + glintReg->DacRegs[PM2VDACRDColorFormat]); + + for (i=0;i<768;i++) { + Permedia2WriteAddress(pScrn, i); + Permedia2WriteData(pScrn, glintReg->cmap[i]); + } + + temp = Permedia2vInIndReg(pScrn, PM2VDACIndexClockControl) & 0xFC; + Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PreScale, 0x00, + glintReg->DacRegs[PM2VDACRDDClk0PreScale]); + Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0FeedbackScale, 0x00, + glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale]); + Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PostScale, 0x00, + glintReg->DacRegs[PM2VDACRDDClk0PostScale]); + Permedia2vOutIndReg(pScrn, PM2VDACIndexClockControl, 0x00, temp|0x03); +} + +static void +Permedia2vShowCursor(ScrnInfoPtr pScrn) +{ + /* Enable cursor - X11 mode */ + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x11); +} + +static void Permedia2vLoadCursorCallback(ScrnInfoPtr pScrn); + +static void +Permedia2vHideCursor(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* Disable cursor - X11 mode */ + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x10); + + /* + * For some reason, we need to clear the image as well as disable + * the cursor on PM2V, but not on PM3. The problem is noticeable + * only when running multi-head, as you can see the cursor get + * "left behind" on the screen it is leaving... + */ + if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) { + memset(pGlint->HardwareCursorPattern, 0, 1024); + pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback; + } +} + +static void +Permedia2vLoadCursorCallback( + ScrnInfoPtr pScrn +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + for (i=0; i<1024; i++) + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPattern+i, 0x00, + pGlint->HardwareCursorPattern[i]); + + pGlint->LoadCursorCallback = NULL; +} + +static void +Permedia2vLoadCursorImage( + ScrnInfoPtr pScrn, + unsigned char *src +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + for (i=0; i<1024; i++) + pGlint->HardwareCursorPattern[i] = *(src++); + + pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback; +} + +static void +Permedia2vSetCursorPosition( + ScrnInfoPtr pScrn, + int x, int y +) +{ + x += 64; + y += 64; + /* Output position - "only" 11 bits of location documented */ + + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotX, 0x00, 0x3f); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotY, 0x00, 0x3f); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXLow, 0x00, x & 0xFF); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXHigh, 0x00, (x>>8) & 0x0F); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYLow, 0x00, y & 0xFF); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYHigh, 0x00, (y>>8) & 0x0F); + Permedia2vOutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00); +} + +static void +Permedia2vCursorColorCallback( + ScrnInfoPtr pScrn +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int fg = pGlint->FGCursor; + int bg = pGlint->BGCursor; + + if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && + (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) { + /* PM3 uses last 2 indexes into hardware cursor palette fg first...*/ + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+39, 0x00, (fg>>16)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+40, 0x00, (fg>>8)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+41, 0x00, fg & 0xff); + + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+42, 0x00, (bg>>16)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+43, 0x00, (bg>>8)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+44, 0x00, bg & 0xff); + } else { + /* PM2v uses first 2 indexes into hardware cursor palette bg first...*/ + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+0, 0x00, (bg>>16)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+1, 0x00, (bg>>8)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+2, 0x00, bg & 0xff); + + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+3, 0x00, (fg>>16)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+4, 0x00, (fg>>8)&0xff); + Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+5, 0x00, fg & 0xff); + } + pGlint->CursorColorCallback = NULL; +} + +static void +Permedia2vSetCursorColors( + ScrnInfoPtr pScrn, + int bg, int fg +) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->FGCursor = fg; + pGlint->BGCursor = bg; + + pGlint->CursorColorCallback = Permedia2vCursorColorCallback; +} + +static Bool +Permedia2vUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) +{ + return TRUE; +} + +Bool +Permedia2vHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pGlint->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | +#if X_BYTE_ORDER == X_BIG_ENDIAN + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | +#endif + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; + infoPtr->SetCursorColors = Permedia2vSetCursorColors; + infoPtr->SetCursorPosition = Permedia2vSetCursorPosition; + infoPtr->LoadCursorImage = Permedia2vLoadCursorImage; + infoPtr->HideCursor = Permedia2vHideCursor; + infoPtr->ShowCursor = Permedia2vShowCursor; + infoPtr->UseHWCursor = Permedia2vUseHWCursor; + + return(xf86InitCursor(pScreen, infoPtr)); +} diff --git a/src/pm2vramdac.c b/src/pm2vramdac.c new file mode 100644 index 0000000..ae5b1d0 --- /dev/null +++ b/src/pm2vramdac.c @@ -0,0 +1,64 @@ +/* + * Copyright 1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * Permedia2vOutIndReg() and Permedia2vInIndReg() are used to access + * the indirect Permedia2v RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c,v 1.6 2001/01/31 16:15:00 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "glint_regs.h" +#include "glint.h" + +void +Permedia2vOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char tmp = 0x00; + + GLINT_SET_INDEX(reg); + + if (mask != 0x00) + tmp = GLINT_READ_REG (PM2VDACIndexData) & mask; + + GLINT_WRITE_REG (tmp | data, PM2VDACIndexData); +} + +unsigned char +Permedia2vInIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char ret; + + GLINT_SET_INDEX(reg); + ret = GLINT_READ_REG (PM2VDACIndexData); + + return (ret); +} diff --git a/src/pm3_accel.c b/src/pm3_accel.c new file mode 100644 index 0000000..9599590 --- /dev/null +++ b/src/pm3_accel.c @@ -0,0 +1,1223 @@ +/* + * Copyright 2000-2001 by Sven Luther <luther@dpt-info.u-strasbg.fr>. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sven Luther not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sven Luther makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * SVEN LUTHER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SVEN LUTHER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> + * Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * this work is sponsored by Appian Graphics. + * + * Permedia 3 accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.31 2003/01/06 00:04:54 alanh Exp $ */ + +#include "Xarch.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "fb.h" + +#include "glint_regs.h" +#include "pm3_regs.h" +#include "glint.h" + +#include "xaalocal.h" /* For replacements */ + +#define DEBUG 0 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("pm3_accel: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("pm3_accel: " str " done\n") +# define TRACE(str) ErrorF("pm3_accel trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +# define TRACE(str) +#endif + +#define PM3_WRITEMASK \ + (pGlint->PM3_UsingSGRAM ? PM3FBHardwareWriteMask : PM3FBSoftwareWriteMask ) +#define PM3_OTHERWRITEMASK \ + (pGlint->PM3_UsingSGRAM ? PM3FBSoftwareWriteMask : PM3FBHardwareWriteMask ) + +#ifndef XF86DRI +#define PM3_PLANEMASK(planemask) \ +{ \ + if (planemask != pGlint->planemask) { \ + pGlint->planemask = planemask; \ + REPLICATE(planemask); \ + GLINT_WRITE_REG(planemask, PM3_WRITEMASK); \ + } \ +} +#else +#define PM3_PLANEMASK(planemask) \ + { \ + pGlint->planemask = planemask; \ + REPLICATE(planemask); \ + GLINT_WRITE_REG(planemask, PM3_WRITEMASK); \ + } +#endif + +/* Clipping */ +static void Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void Permedia3DisableClipping(ScrnInfoPtr pScrn); +/* ScreenToScreenCopy */ +static void Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +/* SolidFill */ +static void Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +/* 8x8 Mono Pattern Fills */ +static void Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int x_offset, int y_offset, int x, int y, + int w, int h); +static void Permedia3SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void Permedia3SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void Permedia3SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +static void Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int trans_color, + int bpp, int depth); +static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft); +static void Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); +static void Permedia3RestoreAccelState(ScrnInfoPtr pScrn); +static void Permedia3WritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int rop, + unsigned int planemask, int transparency_color, + int bpp, int depth); +static void Permedia3WriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int skipleft, + int fg, int bg, int rop,unsigned int planemask); + +void +Permedia3InitializeEngine(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int colorformat = 0; + + /* Initialize the Accelerator Engine to defaults */ + TRACE_ENTER("Permedia3InitializeEngine"); + + if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { + GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); + } + if (pGlint->MultiAperture) { + ErrorF("pm3_accel: SVEN : multiAperture set\n"); + /* Only write the following register to the first PM3 */ + GLINT_SLOW_WRITE_REG(1, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership); + + /* Only write the following register to the second PM3 */ + GLINT_SLOW_WRITE_REG(2, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership); + + /* Make sure the rest of the register writes go to both PM3's */ + GLINT_SLOW_WRITE_REG(3, BroadcastMask); + } + + /* Disable LocalBuffer. Fixes stripes problems when + * doing screen-to-screen copies */ + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadEnables); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBSourceReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBWriteMode); + + /* Host out PreInit */ + /* Set filter mode to enable sync tag & data output */ + GLINT_SLOW_WRITE_REG(0x400, FilterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3DeltaMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3GIDMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCoordMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode0); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode1); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LUTMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureFilterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCompositeMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureApplicationMode); + GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode1); + GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode1); + GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode0); + GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode0); + + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ChromaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); + /* Not done in P3Lib ??? */ + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendColorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendAlphaMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3Window); + + GLINT_SLOW_WRITE_REG(0, PM3Config2D); + + GLINT_SLOW_WRITE_REG(0xffffffff, PM3SpanColorMask); + + GLINT_SLOW_WRITE_REG(0, PM3XBias); + GLINT_SLOW_WRITE_REG(0, PM3YBias); + + GLINT_SLOW_WRITE_REG(0, PM3DeltaControl); + + GLINT_SLOW_WRITE_REG(0xffffffff, BitMaskPattern); + + /* ScissorStippleUnit Initialization (is it needed ?) */ + pGlint->ClippingOn = FALSE; + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + /* We never use Screen Scissor ... + GLINT_SLOW_WRITE_REG( + (pScrn->virtualX&0xffff)|((pScrn->virtualY&0xffff)<<16), + ScreenSize); + GLINT_SLOW_WRITE_REG( + (0&0xffff)|((0&0xffff)<<16), + WindowOrigin); + */ + + /* StencilDepthUnit Initialization */ + GLINT_SLOW_WRITE_REG(0, PM3Window); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(0, StencilData); + + /* FBReadUnit Initialization */ + TRACE("Permedia3InitializeEngine : only syncs upto now"); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadEnables_E(0xff) | + PM3FBDestReadEnables_R(0xff) | + PM3FBDestReadEnables_ReferenceAlpha(0xff), + PM3FBDestReadEnables); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr0); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset0); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth0); + /* + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr1); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset1); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth1); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr2); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset2); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth2); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr3); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset3); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth3); + */ + GLINT_SLOW_WRITE_REG( + PM3FBDestReadMode_ReadEnable | + /* Not needed, since FBDestRead is the same as FBWrite. + PM3FBDestReadMode_Blocking | + */ + PM3FBDestReadMode_Enable0, + PM3FBDestReadMode); + TRACE("Permedia3InitializeEngine : DestRead"); + GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferAddr); + GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferOffset); + GLINT_SLOW_WRITE_REG( + PM3FBSourceReadBufferWidth_Width(pScrn->displayWidth), + PM3FBSourceReadBufferWidth); + GLINT_SLOW_WRITE_REG( + PM3FBSourceReadMode_Blocking | + PM3FBSourceReadMode_ReadEnable, + PM3FBSourceReadMode); + TRACE("Permedia3InitializeEngine : SourceRead"); + switch (pScrn->bitsPerPixel) { + case 8: + pGlint->PM3_PixelSize = 2; +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap = 3<<15; /* Swap host data */ +#endif + break; + case 16: + pGlint->PM3_PixelSize = 1; +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap = 2<<15; /* Swap host data */ +#endif + break; + case 32: + pGlint->PM3_PixelSize = 0; + break; + } + GLINT_SLOW_WRITE_REG(pGlint->PM3_PixelSize, PixelSize); +#if X_BYTE_ORDER == X_BIG_ENDIAN + GLINT_SLOW_WRITE_REG(1 | pGlint->RasterizerSwap, RasterizerMode); +#endif + TRACE("Permedia3InitializeEngine : PixelSize"); + + /* LogicalOpUnit Initialization */ + GLINT_SLOW_WRITE_REG(0xffffffff, PM3_OTHERWRITEMASK); + + /* FBWriteUnit Initialization */ + GLINT_SLOW_WRITE_REG( + PM3FBWriteMode_WriteEnable| + PM3FBWriteMode_OpaqueSpan| + PM3FBWriteMode_Enable0, + PM3FBWriteMode); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr0); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset0); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth0); + /* + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr1); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset1); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth1); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr2); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset2); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth2); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr3); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset3); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth3); + */ + TRACE("Permedia3InitializeEngine : FBWrite"); + /* SizeOfframebuffer */ + GLINT_SLOW_WRITE_REG( + pScrn->displayWidth * + (8 * pGlint->FbMapSize / (pScrn->bitsPerPixel * pScrn->displayWidth) + >4095?4095: 8 * pGlint->FbMapSize / + (pScrn->bitsPerPixel * pScrn->displayWidth)), + PM3SizeOfFramebuffer); + GLINT_SLOW_WRITE_REG(0xffffffff, PM3_WRITEMASK); + TRACE("Permedia3InitializeEngine : FBHardwareWriteMask & SizeOfFramebuffer"); + /* Color Format */ + switch (pScrn->depth) { + case 8: + colorformat = 4; + break; + case 15: + colorformat = 2; + break; + case 16: + colorformat = 3; + break; + case 24: + case 32: + colorformat = 0; + break; + } + GLINT_SLOW_WRITE_REG(UNIT_DISABLE| + ((colorformat&0xf)<<2)|(1<<10), + DitherMode); + + /* Other stuff */ + pGlint->startxdom = 0; + pGlint->startxsub = 0; + pGlint->starty = 0; + pGlint->count = 0; + pGlint->dy = 1<<16; + pGlint->dxdom = 0; + pGlint->x = 0; + pGlint->y = 0; + pGlint->h = 0; + pGlint->w = 0; + pGlint->ROP = 0xFF; + GLINT_SLOW_WRITE_REG(0, dXDom); + GLINT_SLOW_WRITE_REG(0, dXSub); + GLINT_SLOW_WRITE_REG(1<<16, dY); + GLINT_SLOW_WRITE_REG(0, StartXDom); + GLINT_SLOW_WRITE_REG(0, StartXSub); + GLINT_SLOW_WRITE_REG(0, StartY); + GLINT_SLOW_WRITE_REG(0, GLINTCount); + if (*pGlint->AccelInfoRec->Sync) + (*pGlint->AccelInfoRec->Sync)(pScrn); + TRACE_EXIT("Permedia3InitializeEngine"); +} + +Bool +Permedia3AccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + /* Generic accel engine flags */ + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + /* Synchronization of the accel engine */ + if (pGlint->MultiAperture) + infoPtr->Sync = DualPermedia3Sync; + else + infoPtr->Sync = Permedia3Sync; + + Permedia3InitializeEngine(pScrn); + + /* Clipping Setup */ + infoPtr->ClippingFlags = 0; + infoPtr->SetClippingRectangle = Permedia3SetClippingRectangle; + infoPtr->DisableClipping = Permedia3DisableClipping; + + /* ScreenToScreenCopy */ + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + infoPtr->SetupForScreenToScreenCopy = + Permedia3SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + Permedia3SubsequentScreenToScreenCopy; + + /* SolidFill */ + infoPtr->SolidFillFlags = 0; + infoPtr->SetupForSolidFill = Permedia3SetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = Permedia3SubsequentFillRectSolid; + + /* 8x8 Mono Pattern Fills */ + infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_SCREEN_ORIGIN | + BIT_ORDER_IN_BYTE_LSBFIRST; + infoPtr->SetupForMono8x8PatternFill = + Permedia3SetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + Permedia3SubsequentMono8x8PatternFillRect; + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X | + BIT_ORDER_IN_BYTE_LSBFIRST | + CPU_TRANSFER_PAD_DWORD; + + infoPtr->NumScanlineColorExpandBuffers = 1; + pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4) + + (pScrn->virtualX + * pScrn->bitsPerPixel / 8)); + infoPtr->ScanlineColorExpandBuffers = + pGlint->XAAScanlineColorExpandBuffers; + pGlint->XAAScanlineColorExpandBuffers[0] = + pGlint->IOBase + OutputFIFO + 4; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + Permedia3SetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + Permedia3SubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + Permedia3SubsequentColorExpandScanline; + + infoPtr->ScanlineImageWriteFlags = NO_GXCOPY | + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X | + BIT_ORDER_IN_BYTE_LSBFIRST | + CPU_TRANSFER_PAD_DWORD; + infoPtr->NumScanlineImageWriteBuffers = 1; + infoPtr->ScanlineImageWriteBuffers = + pGlint->XAAScanlineColorExpandBuffers; + infoPtr->SetupForScanlineImageWrite = + Permedia3SetupForScanlineImageWrite; + infoPtr->SubsequentScanlineImageWriteRect = + Permedia3SubsequentScanlineImageWriteRect; + infoPtr->SubsequentImageWriteScanline = + Permedia3SubsequentImageWriteScanline; + + infoPtr->WriteBitmap = Permedia3WriteBitmap; + infoPtr->WriteBitmapFlags = 0; + + infoPtr->WritePixmap = Permedia3WritePixmap; + infoPtr->WritePixmapFlags = 0; + + { + Bool shared_accel = FALSE; + int i; + + for(i = 0; i < pScrn->numEntities; i++) { + if(xf86IsEntityShared(pScrn->entityList[i])) + shared_accel = TRUE; + } + if(shared_accel == TRUE) + infoPtr->RestoreAccelState = Permedia3RestoreAccelState; + } + + Permedia3EnableOffscreen(pScreen); + + return(XAAInit(pScreen, infoPtr)); +} + +void +Permedia3EnableOffscreen (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + BoxRec AvailFBArea; + + /* Available Framebuffer Area for XAA. */ + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + /* X coords are short's so we have to do this to make sure we dont wrap*/ + AvailFBArea.y2 = ((pGlint->FbMapSize > 16384*1024) ? 16384*1024 : + pGlint->FbMapSize) / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + /* Permedia3 has a maximum 4096x4096 framebuffer */ + if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095; + + xf86InitFBManager(pScreen, &AvailFBArea); +} +#define CHECKCLIPPING \ +{ \ + if (pGlint->ClippingOn) { \ + pGlint->ClippingOn = FALSE; \ + GLINT_WAIT(1); \ + GLINT_WRITE_REG(0, ScissorMode); \ + } \ +} + +void +Permedia3Sync(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(2); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); +} + +void +DualPermedia3Sync( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(3); + GLINT_WRITE_REG(3, BroadcastMask); /* hack! this shouldn't need to be reloaded */ + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + + /* Read 1st PM3 until Sync Tag shows */ + ACCESSCHIP1(); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); + + ACCESSCHIP2(); + /* Read 2nd PM3 until Sync Tag shows */ + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); + + ACCESSCHIP1(); +} + +static void +Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WAIT(3); + GLINT_WRITE_REG(((y1&0x0fff)<<16)|(x1&0x0fff), ScissorMinXY); + GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG(1, ScissorMode); + pGlint->ClippingOn = TRUE; +} +static void +Permedia3DisableClipping(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CHECKCLIPPING; +} + +/* ScreenToScreenCopy definition */ +static void +Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SetupForScreenToScreenCopy"); + + pGlint->PM3_Render2D = + PM3Render2D_SpanOperation | + PM3Render2D_Operation_Normal; + + pGlint->ClippingOn = TRUE; + + pGlint->PM3_Config2D = + PM3Config2D_UserScissorEnable | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + + if (xdir == 1) pGlint->PM3_Render2D |= PM3Render2D_XPositive; + if (ydir == 1) pGlint->PM3_Render2D |= PM3Render2D_YPositive; + + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXnoop)&&(rop!=GXinvert)) { + pGlint->PM3_Render2D |= PM3Render2D_FBSourceReadEnable; + pGlint->PM3_Config2D |= PM3Config2D_Blocking; + } + + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + + GLINT_WAIT(2); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + + TRACE_EXIT("Permedia3SetupForScreenToScreenCopy"); +} +static void +Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + /* Spans needs to be 32 bit aligned. */ + int x_align = x1 & 0x1f; + TRACE_ENTER("Permedia3SubsequentScreenToScreenCopy"); + GLINT_WAIT(5); + GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMinXY); + GLINT_WRITE_REG((((y2+h)&0x0fff)<<16)|((x2+w)&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x2-x_align) | + PM3RectanglePosition_YOffset(y2), + PM3RectanglePosition); + GLINT_WRITE_REG( + PM3FBSourceReadBufferOffset_XOffset(x1-x2)| + PM3FBSourceReadBufferOffset_YOffset(y1-y2), + PM3FBSourceReadBufferOffset); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w+x_align)| + PM3Render2D_Height(h), + PM3Render2D); + TRACE_EXIT("Permedia3SubsequentScreenToScreenCopy"); +} + +/* Solid Fills */ +static void +Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SetupForFillRectSolid"); + /* Prepare Common Render2D & Config2D data */ + pGlint->PM3_Render2D = + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_Normal; + pGlint->PM3_Config2D = + PM3Config2D_UseConstantSource | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + GLINT_WAIT(3); + REPLICATE(color); + /* We can't do block fills properly at 32bpp, so we can stick the chip + * into 16bpp and double the width and xcoord, but it seems that at + * extremely high resolutions (above 1600) it doesn't fill. + * so, we fall back to the slower span filling method. + */ + if ((rop == GXcopy) && (pScrn->bitsPerPixel == 32) && + (pScrn->displayWidth <= 1600)) { + pGlint->AccelInfoRec->SubsequentSolidFillRect = + Permedia3SubsequentFillRectSolid32bpp; + if (pGlint->PM3_UsingSGRAM) { + GLINT_WRITE_REG(color, PM3FBBlockColor); + } else { + pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; + GLINT_WRITE_REG(color, PM3ForegroundColor); + } + } else { + pGlint->AccelInfoRec->SubsequentSolidFillRect = + Permedia3SubsequentFillRectSolid; + /* Can't do block fills at 8bpp either */ + if ((rop == GXcopy) && (pScrn->bitsPerPixel == 16)) { + if (pGlint->PM3_UsingSGRAM) { + GLINT_WRITE_REG(color, PM3FBBlockColor); + } else { + pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; + GLINT_WRITE_REG(color, PM3ForegroundColor); + } + } else { + pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; + GLINT_WRITE_REG(color, PM3ForegroundColor); + } + } + PM3_PLANEMASK(planemask); + if (((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + || ((planemask != 0xffffffff) && !(pGlint->PM3_UsingSGRAM))) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + TRACE_EXIT("Permedia3SetupForFillRectSolid"); +} + +static void +Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SubsequentFillRectSolid"); + + GLINT_WAIT(2); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + + TRACE_EXIT("Permedia3SubsequentFillRectSolid"); +} + +static void +Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SubsequentFillRectSolid32bpp"); + + GLINT_WAIT(6); + + /* Put the chip into 16bpp mode */ + GLINT_WRITE_REG(1, PixelSize); + /* Now double the displayWidth */ + GLINT_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth<<1), + PM3FBWriteBufferWidth0); + + /* and double the x,w coords */ + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x<<1) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w<<1) | PM3Render2D_Height(h), + PM3Render2D); + + /* Now fixup */ + GLINT_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth0); + GLINT_WRITE_REG(0, PixelSize); + TRACE_EXIT("Permedia3SubsequentFillRectSolid32bpp"); +} + +/* 8x8 Mono Pattern Fills */ +static void +Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SetupForMono8x8PatternFill"); + REPLICATE(fg); + pGlint->PM3_Render2D = + PM3Render2D_AreaStippleEnable | + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_Normal; + pGlint->PM3_Config2D = + PM3Config2D_UseConstantSource | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + pGlint->PM3_AreaStippleMode = 1; +/* Mirror stipple pattern horizontally */ +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->PM3_AreaStippleMode |= (1<<18); +#endif + pGlint->PM3_AreaStippleMode |= (2<<1); + pGlint->PM3_AreaStippleMode |= (2<<4); + if (bg != -1) { + REPLICATE(bg); + pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; + pGlint->PM3_AreaStippleMode |= 1<<20; + GLINT_WAIT(12); + GLINT_WRITE_REG(bg, BackgroundColor); + } + else GLINT_WAIT(11); + GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0); + GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4); + GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); + GLINT_WRITE_REG(fg, PM3ForegroundColor); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + TRACE_EXIT("Permedia3SetupForMono8x8PatternFill"); +} +static void +Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int x_offset, int y_offset, + int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SubsequentMono8x8PatternFillRect"); + GLINT_WAIT(3); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG( + (x_offset&0x7)<<7 | (y_offset&0x7)<<12 | + pGlint->PM3_AreaStippleMode, + AreaStippleMode); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + TRACE_EXIT("Permedia3SubsequentMono8x8PatternFillRect"); +} + +static void +Permedia3SetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + REPLICATE(fg); + pGlint->PM3_Render2D = + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_SyncOnBitMask; + pGlint->PM3_Config2D = + PM3Config2D_UserScissorEnable | + PM3Config2D_UseConstantSource | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + if (bg != -1) { + REPLICATE(bg); + pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; + GLINT_WAIT(4); + GLINT_WRITE_REG(bg, BackgroundColor); + } + else GLINT_WAIT(3); + GLINT_WRITE_REG(fg, PM3ForegroundColor); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); +} + +static void +Permedia3SubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + TRACE_ENTER("Permedia2SubsequentScanlineCPUToScreenColorExpandFill"); + + pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ + + pGlint->cpucount = h; + + GLINT_WAIT(5); + GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); + GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + +#if defined(__alpha__) + if (0) /* force Alpha to use indirect always */ +#else + if ((pGlint->dwords*h) < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than 120 dword colour expansion */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; + pGlint->ScanlineDirect = 1; + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); + GLINT_WAIT(pGlint->dwords*h); + } else { + /* Use indirect for anything else */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; + pGlint->ScanlineDirect = 0; + } + + pGlint->cpucount--; +} + +static void +Permedia3SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; + int dwords = pGlint->dwords; + + if (!pGlint->ScanlineDirect) { + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + dwords -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, dwords); + } + } +} + +/* Images Writes */ +static void Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int trans_color, int bpp, int depth) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SetupForScanlineImageWrite"); + pGlint->PM3_Render2D = + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_SyncOnHostData; + pGlint->PM3_Config2D = + PM3Config2D_UserScissorEnable | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + GLINT_WAIT(2); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + TRACE_EXIT("Permedia3SetupForScanlineImageWrite"); +} + +static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SubsequentScanlineImageWrite"); + pGlint->dwords = (((w * pScrn->bitsPerPixel) + 3) >> 2); /* per scanline */ + + pGlint->cpucount = h; + GLINT_WAIT(5); + GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); + GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + +#if defined(__alpha__) + if (0) /* force Alpha to use indirect always */ +#else + if (pGlint->dwords < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than 120 dword colour expansion */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; + pGlint->ScanlineDirect = 1; + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | (0x15<<4) | 0x05, + OutputFIFO); + GLINT_WAIT(pGlint->dwords); + } else { + /* Use indirect for anything else */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; + pGlint->ScanlineDirect = 0; + } + + pGlint->cpucount--; + TRACE_EXIT("Permedia3SubsequentScanlineImageWrite"); +} + +static void +Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dwords = pGlint->dwords; + + if (pGlint->ScanlineDirect) { + if (pGlint->cpucount--) + GLINT_WAIT(dwords); + return; + } else { + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno], + pGlint->FIFOSize - 1); + dwords -= pGlint->FIFOSize - 1; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno], + dwords); + } + } +} + +static void +Permedia3RestoreAccelState(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { + GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); + } + Permedia3Sync(pScrn); +} + +static void +Permedia3WritePixmap( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int trans, + int bpp, int depth +) +{ + int dwords; + int count; + int skipleft = (long)src & 0x03L; + int Bpp = bpp >> 3; + CARD32 *srcp; + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3WritePixmap"); + + if (skipleft) { + /* Skipleft is either + * - 0, 1, 2 or 3 in 8 bpp + * - 0 or 1 in 16 bpp + * - 0 in 32 bpp + */ + skipleft /= Bpp; + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + + pGlint->PM3_Render2D = + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_SyncOnHostData; + pGlint->PM3_Config2D = + PM3Config2D_UserScissorEnable | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + GLINT_WAIT(6); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); + GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + /* width of the stuff to copy in 32 bit words */ + dwords = ((w * Bpp) + 3) >> 2; + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + + Permedia3DisableClipping(pScrn); + Permedia3Sync(pScrn); +} + +static void +Permedia3WriteBitmap(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, int skipleft, + int fg, int bg, int rop, + unsigned int planemask +) +{ + int dwords; + GLINTPtr pGlint = GLINTPTR(pScrn); + int count; + CARD32 *srcp; + TRACE_ENTER("Permedia3WriteBitmap"); + + w += skipleft; + x -= skipleft; + dwords = (w + 31) >>5; + + REPLICATE(fg); + pGlint->PM3_Render2D = + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_SyncOnBitMask; + pGlint->PM3_Config2D = + PM3Config2D_UserScissorEnable | + PM3Config2D_UseConstantSource | + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(rop) | + PM3Config2D_FBWriteEnable; + if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) + pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; + if (bg != -1) { + REPLICATE(bg); + pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; + GLINT_WAIT(8); + GLINT_WRITE_REG(bg, BackgroundColor); + } + else GLINT_WAIT(7); + GLINT_WRITE_REG(fg, PM3ForegroundColor); + PM3_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); + GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); + GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG(pGlint->PM3_Render2D | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | + 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + count -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(count) { + GLINT_WAIT(count + 1); + GLINT_WRITE_REG(((count - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + + Permedia3DisableClipping(pScrn); + Permedia3Sync(pScrn); +} diff --git a/src/pm3_dac.c b/src/pm3_dac.c new file mode 100644 index 0000000..f848094 --- /dev/null +++ b/src/pm3_dac.c @@ -0,0 +1,842 @@ +/* + * Copyright 2000,2001 by Sven Luther <luther@dpt-info.u-strasbg.fr>. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sven Luther not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sven Luther makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * SVEN LUTHER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SVEN LUTHER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> + * Thomas Witzel, <twitzel@nmr.mgh.harvard.edu> + * Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * this work is sponsored by Appian Graphics. + * + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c,v 1.33 2002/07/19 15:33:45 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86int10.h" + +#include "glint_regs.h" +#include "pm3_regs.h" +#include "glint.h" + +#define DEBUG 0 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("glint: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("glint: " str " done\n") +# define TRACE(str) ErrorF("glint trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +# define TRACE(str) +#endif + +int +Permedia3MemorySizeDetect(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR (pScrn); + CARD32 size = 0, temp, temp1, temp2, i; + + /* We can map 64MB, as that's the size of the Permedia3 aperture + * regardless of memory configuration */ + pGlint->FbMapSize = 64*1024*1024; + + /* Mark as VIDMEM_MMIO to avoid write-combining while detecting memory */ + pGlint->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pGlint->PciTag, pGlint->FbAddress, pGlint->FbMapSize); + + if (pGlint->FbBase == NULL) + return 0; + + temp = GLINT_READ_REG(PM3MemBypassWriteMask); + GLINT_SLOW_WRITE_REG(0xffffffff, PM3MemBypassWriteMask); + + /* The Permedia3 splits up memory, and even replicates it. Grrr. + * So that each 32MB appears at offset 0, and offset 32, unless + * there's really 64MB attached to the chip. + * So, 16MB appears at offset 0, nothing between 16-32, then it re-appears + * at offset 32. + * This below is to detect the cases of memory combinations + */ + + /* Test first 32MB */ + for(i=0;i<32;i++) { + /* write test pattern */ + MMIO_OUT32(pGlint->FbBase, i*1024*1024, i*0x00345678); + mem_barrier(); + temp1 = MMIO_IN32(pGlint->FbBase, i*1024*1024); + /* Let's check for wrapover, write will fail at 16MB boundary */ + if (temp1 == (i*0x00345678)) + size = i; + else + break; + } + + /* Ok, we're satisfied we've got 32MB, let's test the second lot */ + if ((size + 1) == i) { + for(i=0;i<32;i++) { + /* Clear first 32MB */ + MMIO_OUT32(pGlint->FbBase, i*1024*1024, 0); + mem_barrier(); + } + for(i=32;i<64;i++) { + /* write test pattern */ + MMIO_OUT32(pGlint->FbBase, i*1024*1024, i*0x00345678); + mem_barrier(); + temp1 = MMIO_IN32(pGlint->FbBase, i*1024*1024); + temp2 = MMIO_IN32(pGlint->FbBase, (i-32)*1024*1024); + /* Let's check for wrapover */ + if ( (temp1 == (i*0x00345678)) && (temp2 == 0) ) + size = i; + else + break; + } + } + + GLINT_SLOW_WRITE_REG(temp, PM3MemBypassWriteMask); + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->FbBase, + pGlint->FbMapSize); + + pGlint->FbBase = NULL; + pGlint->FbMapSize = 0; + + return ( (size+1) * 1024 ); +} + +static unsigned long +PM3DAC_CalculateClock +( + unsigned long ReqClock, /* In kHz units */ + unsigned long RefClock, /* In kHz units */ + unsigned char *prescale, /* ClkPreScale */ + unsigned char *feedback, /* ClkFeedBackScale */ + unsigned char *postscale /* ClkPostScale */ + ) +{ + unsigned long fMinVCO = 2000000; /* min fVCO is 200MHz (in 100Hz units) */ + unsigned long fMaxVCO = 6220000; /* max fVCO is 622MHz (in 100Hz units) */ + unsigned long fMinINTREF = 10000;/* min fINTREF is 1MHz (in 100Hz units) */ + unsigned long fMaxINTREF = 20000;/* max fINTREF is 2MHz (in 100Hz units) */ + unsigned long M, N, P; /* M=feedback, N=prescale, P=postscale */ + unsigned long fINTREF; + unsigned long fVCO; + unsigned long ActualClock; + long Error; + unsigned long LowestError = 1000000; + unsigned int bFoundFreq = FALSE; + int cInnerLoopIterations = 0; + int LoopCount; + unsigned long ClosestClock = 0; + + ReqClock*=10; /* convert into 100Hz units */ + RefClock*=10; /* convert into 100Hz units */ + + for(P = 0; P <= 5; ++P) + { + unsigned long fVCOLowest, fVCOHighest; + + /* it is pointless going through the main loop if all values of + N produce an fVCO outside the acceptable range */ + N = 1; + M = (N * (1UL << P) * ReqClock) / (2 * RefClock); + fVCOLowest = (2 * RefClock * M) / N; + N = 255; + M = (N * (1UL << P) * ReqClock) / (2 * RefClock); + fVCOHighest = (2 * RefClock * M) / N; + + if(fVCOHighest < fMinVCO || fVCOLowest > fMaxVCO) + { + continue; + } + + for(N = 1; N <= 255; ++N, ++cInnerLoopIterations) + { + fINTREF = RefClock / N; + if(fINTREF < fMinINTREF || fINTREF > fMaxINTREF) + { + if(fINTREF > fMaxINTREF) + { + /* hopefully we will get into range as the prescale + value increases */ + continue; + } + else + { + /* already below minimum and it will only get worse: + move to the next postscale value */ + break; + } + } + + M = (N * (1UL << P) * ReqClock) / (2 * RefClock); + if(M > 255) + { + /* M, N & P registers are only 8 bits wide */ + break; + } + + /* we can expect rounding errors in calculating M, which + will always be rounded down. So we will checkout our + calculated value of M along with (M+1) */ + for(LoopCount = (M == 255) ? 1 : 2; --LoopCount >= 0; ++M) + { + fVCO = (2 * RefClock * M) / N; + if(fVCO >= fMinVCO && fVCO <= fMaxVCO) + { + ActualClock = fVCO / (1UL << P); + Error = ActualClock - ReqClock; + if(Error < 0) + Error = -Error; + if(Error < LowestError) + { + bFoundFreq = TRUE; + LowestError = Error; + ClosestClock = ActualClock; + *prescale = N; + *feedback = M; + *postscale = P; + if(Error == 0) + goto Done; + } + } + } + } + } + +Done: + + if(bFoundFreq) + ActualClock = ClosestClock; + else + ActualClock = 0; + +#if 0 + ErrorF("PM3DAC_CalculateClock: Got prescale=%d, feedback=%d, postscale=%d, WantedClock = %d00 ActualClock = %d00 (Error %d00)\n", + *prescale, *feedback, *postscale, ReqClock, ActualClock, LowestError); +#endif + + return(ActualClock); +} + +static unsigned long +PM4DAC_CalculateClock +( + unsigned long req_clock, /* In kHz units */ + unsigned long ref_clock, /* In kHz units */ + unsigned char *param_m, /* ClkPreScale */ + unsigned char *param_n, /* ClkFeedBackScale */ + unsigned char *param_p /* ClkPostScale */ + ) +{ +#define INITIALFREQERR 10000 + + long fMinVCO = 200000; /* min fVCO is 200MHz (in 10000Hz units) */ + long fMaxVCO = 400000; /* max fVCO is 400MHz (in 10000Hz units) */ + unsigned long int M, N, P; + unsigned long int fVCO; + unsigned long int ActualClock; + int Error; + int LowestError = INITIALFREQERR; + short bFoundFreq = FALSE; + int cInnerLoopIterations = 0; + int LoopCount; + + /* + * Actual Equations: + * fVCO = (ref_clock * M)/(N+1) + * PIXELCLOCK = fVCO/(1<<p) + * 200 <= fVCO <= 400 + * 24 <= N <= 80 + * 1 <= M <= 15 + * 0 <= P <= 3 + * 1Mhz < ref_clock/(N+1) <= 2Mhz - not used + * For refclk == 14.318 we have the tighter equations: + * 32 <= N <= 80 + * 3 <= M <= 12 + * Notes: + * The spec says that the PLLs will only do 260Mhz, but I have assumed 300Mhz 'cos + * 260Mhz is a crap limit. + */ + +#define P4RD_PLL_MIN_P 0 +#define P4RD_PLL_MAX_P 3 +#define P4RD_PLL_MIN_M 1 +#define P4RD_PLL_MAX_M 12 +#define P4RD_PLL_MIN_N 24 +#define P4RD_PLL_MAX_N 80 + + for(P = P4RD_PLL_MIN_P; P <= P4RD_PLL_MAX_P; ++P) { + unsigned long int fVCOLowest, fVCOHighest; + + /* it's pointless going through the main loop if all values of + * N produce an fVCO outside the acceptable range */ + + M = P4RD_PLL_MIN_M; + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + fVCOLowest = (ref_clock * N) / (M + 1); + + M = P4RD_PLL_MAX_M; + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + fVCOHighest = (ref_clock * N) / (M + 1); + + if(fVCOHighest < fMinVCO || fVCOLowest > fMaxVCO) + continue; + + for(M = P4RD_PLL_MIN_M; M <= P4RD_PLL_MAX_M; ++M, ++cInnerLoopIterations) + { + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + if(N > P4RD_PLL_MAX_N || N < P4RD_PLL_MIN_N) + continue; + + /* we can expect rounding errors in calculating M, which will always be rounded down. */ + /* So we'll checkout our calculated value of M along with (M+1) */ + + for(LoopCount = (N == P4RD_PLL_MAX_N) ? 1 : 2; --LoopCount >= 0; ++N) + { + fVCO = (ref_clock * N) / (M + 1); + + if( (fVCO >= fMinVCO) && (fVCO <= fMaxVCO) ) + { + ActualClock = (fVCO / (1 << P)); + + Error = ActualClock - req_clock; + + if(Error < 0) + Error = -Error; + + /* It is desirable that we use the lowest value of M if the*/ + /* frequencies are the same.*/ + if(Error < LowestError || (Error == LowestError && M < *param_m)) + { + bFoundFreq = TRUE; + LowestError = Error; + *param_m = M; + *param_n = N; + *param_p = P; + if(Error == 0) + goto Done; + } + } + } + } + } + +Done: + if(bFoundFreq) + ActualClock = (ref_clock * (*param_n)) / (((*param_m) + 1) * (1 << (*param_p))); + else + ActualClock = 0; + + return(ActualClock); +} + +void +Permedia3PreInit(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 LocalMemCaps; + + TRACE_ENTER("Permedia3PreInit"); + + if (IS_J2000) { + unsigned char m,n,p; + unsigned long clockused; + + if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) + GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture); + + /* Memory timings for the Appian J2000 board. + * This is needed for the second head which is left un-initialized + * by the bios, thus freezing the machine. */ + GLINT_SLOW_WRITE_REG(0x02e311B8, PM3LocalMemCaps); + GLINT_SLOW_WRITE_REG(0x07424905, PM3LocalMemTimings); + GLINT_SLOW_WRITE_REG(0x0c000003, PM3LocalMemControl); + GLINT_SLOW_WRITE_REG(0x00000061, PM3LocalMemRefresh); + GLINT_SLOW_WRITE_REG(0x00000000, PM3LocalMemPowerDown); + + /* Let's program the K, M and S Clocks to the same values as the bios + * does for first head : + * - KClk and MClk are 105Mhz. + * - S Clock is set to PClk. + * Note 1 : pGlint->RefClock is not set yet, so use 14318 instead. + * Note 2 : KClk gets internally halved, so we need to double it. + */ + clockused = PM3DAC_CalculateClock(2*105000, 14318, &m,&n,&p); + Permedia2vOutIndReg(pScrn, PM3RD_KClkPreScale, 0x00, m); + Permedia2vOutIndReg(pScrn, PM3RD_KClkFeedbackScale, 0x00, n); + Permedia2vOutIndReg(pScrn, PM3RD_KClkPostScale, 0x00, p); + Permedia2vOutIndReg(pScrn, PM3RD_KClkControl, 0x00, + PM3RD_KClkControl_STATE_RUN | + PM3RD_KClkControl_SOURCE_PLL | + PM3RD_KClkControl_ENABLE); + Permedia2vOutIndReg(pScrn, PM3RD_MClkControl, 0x00, + PM3RD_MClkControl_STATE_RUN | + PM3RD_MClkControl_SOURCE_KCLK | + PM3RD_MClkControl_ENABLE); + Permedia2vOutIndReg(pScrn, PM3RD_SClkControl, 0x00, + PM3RD_SClkControl_STATE_RUN | + PM3RD_SClkControl_SOURCE_PCLK | + PM3RD_SClkControl_ENABLE); + } + +#if defined(__alpha__) + /* + * On Alpha, we have to "int10" secondary VX1 cards early; + * otherwise, some information taken from registers, like + * memory size, is incorrect. + */ + if (!xf86IsPrimaryPci(pGlint->PciInfo)) { + if ( IS_QVX1 ) { + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VX1 secondary enabling VGA before int10\n"); + + /* Enable VGA on the current card. */ + pciWriteByte( pGlint->PciTag, 0xf8, 0 ); + pciWriteByte( pGlint->PciTag, 0xf4, 0 ); + pciWriteByte( pGlint->PciTag, 0xfc, 0 ); + + /* The card we are on should be VGA-enabled now, so run int10. */ + if (xf86LoadSubModule(pScrn, "int10")) { + xf86Int10InfoPtr pInt; + + xf86LoaderReqSymLists(GLINTint10Symbols, NULL); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); + pInt = xf86InitInt10(pGlint->pEnt->index); + xf86FreeInt10(pInt); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VX1 secondary disabling VGA after int10\n"); + + /* Finally, disable VGA on the current card. */ + pciWriteByte( pGlint->PciTag, 0xf8, 0x70 ); + pciWriteByte( pGlint->PciTag, 0xf4, 0x01 ); + pciWriteByte( pGlint->PciTag, 0xfc, 0x00 ); + } + } +#endif /* __alpha__ */ + + /* If we have SDRAM instead of SGRAM, we have to do some things + differently in the FillRectSolid code. */ + LocalMemCaps = GLINT_READ_REG(PM3LocalMemCaps); + pGlint->PM3_UsingSGRAM = !(LocalMemCaps & PM3LocalMemCaps_NoWriteMask); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s memory\n", + pGlint->PM3_UsingSGRAM ? "SGRAM" : "SDRAM"); + + TRACE_EXIT("Permedia3PreInit"); +} + +Bool +Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 temp1, temp2, temp3, temp4; + + if ((pGlint->numMultiDevices == 2) || (IS_J2000)) { + STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn); + } + + if (pGlint->MultiAperture) { + STOREREG(GMultGLINTAperture, pGlint->realWidth); + STOREREG(GMultGLINT1, + pGlint->MultiPciInfo[0]->memBase[2] & 0xFF800000); + STOREREG(GMultGLINT2, + pGlint->MultiPciInfo[1]->memBase[2] & 0xFF800000); + } + + STOREREG(PM3MemBypassWriteMask, 0xffffffff); + STOREREG(Aperture0, 0x00000000); + STOREREG(Aperture1, 0x00000000); + + if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) + STOREREG(DFIFODis, 0x00000001); + + STOREREG(FIFODis, 0x00000007); + + temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; + temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; + temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + STOREREG(PMHTotal, Shiftbpp(pScrn, mode->CrtcHTotal - 1)); + STOREREG(PMHsEnd, Shiftbpp(pScrn, temp1 + temp3)); + STOREREG(PMHsStart, Shiftbpp(pScrn, temp1)); + STOREREG(PMHbEnd, Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); + STOREREG(PMHgEnd, Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); + STOREREG(PMScreenStride, Shiftbpp(pScrn, pScrn->displayWidth)); + + STOREREG(PMVTotal, mode->CrtcVTotal - 1); + STOREREG(PMVsEnd, temp2 + temp4 - 1); + STOREREG(PMVsStart, temp2 - 1); + STOREREG(PMVbEnd, mode->CrtcVTotal - mode->CrtcVDisplay); + + switch (pScrn->bitsPerPixel) + { + case 8: + STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_8BIT); + STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_8BIT); + STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (0 << 19)); + break; + case 16: +#if X_BYTE_ORDER != X_BIG_ENDIAN + STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT); + STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT); +#else + STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT | + PM3ByApertureMode_BYTESWAP_BADC); + STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT | + PM3ByApertureMode_BYTESWAP_BADC); +#endif + STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (1 << 19)); + break; + case 32: +#if X_BYTE_ORDER != X_BIG_ENDIAN + STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT); + STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT); +#else + STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT | + PM3ByApertureMode_BYTESWAP_DCBA); + STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT | + PM3ByApertureMode_BYTESWAP_DCBA); +#endif + STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (2 << 19)); + break; + } + + STOREREG(VClkCtl, GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); + STOREREG(PMScreenBase, 0x00000000); + STOREREG(ChipConfig, GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD); + + { + /* Get the programmable clock values */ + unsigned char m,n,p; + unsigned long clockused; + + /* Let's program the dot clock */ + switch (pGlint->Chipset) { + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + case PCI_VENDOR_3DLABS_CHIP_R4: + clockused = PM4DAC_CalculateClock(mode->Clock, + pGlint->RefClock, &m,&n,&p); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + clockused = PM3DAC_CalculateClock(mode->Clock, + pGlint->RefClock, &m,&n,&p); + break; + case PCI_VENDOR_3DLABS_CHIP_GAMMA: + switch (pGlint->MultiChip) { + case PCI_CHIP_PERMEDIA3: + clockused = PM3DAC_CalculateClock(mode->Clock, + pGlint->RefClock, &m,&n,&p); + break; + case PCI_CHIP_R4: + clockused = PM4DAC_CalculateClock(mode->Clock, + pGlint->RefClock, &m,&n,&p); + break; + } + break; + } + STOREDAC(PM3RD_DClk0PreScale, m); + STOREDAC(PM3RD_DClk0FeedbackScale, n); + STOREDAC(PM3RD_DClk0PostScale, p); + } + + temp1 = 0; + temp2 = 0; + temp3 = 0; + + if (pGlint->UseFlatPanel) { + temp2 |= PM3RD_DACControl_BLANK_PEDESTAL_ENABLE; + temp3 |= PM3RD_MiscControl_VSB_OUTPUT_ENABLE; + STOREREG(VSConfiguration, 0x06); + STOREREG(VSBBase, 1<<14); + } + + if (mode->Flags & V_PHSYNC) temp1 |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH; + if (mode->Flags & V_PVSYNC) temp1 |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH; + + STOREREG(PM2VDACRDIndexControl, 0x00); + STOREDAC(PM2VDACRDSyncControl, temp1); + STOREDAC(PM2VDACRDDACControl, temp2); + + if (pScrn->rgbBits == 8) + temp3 |= 0x01; /* 8bit DAC */ + + switch (pScrn->bitsPerPixel) + { + case 8: + STOREDAC(PM2VDACRDPixelSize, 0x00); + STOREDAC(PM2VDACRDColorFormat, 0x2E); + break; + case 16: + temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; + STOREDAC(PM2VDACRDPixelSize, 0x01); + if (pScrn->depth == 15) { + STOREDAC(PM2VDACRDColorFormat, 0x61); + } else { + STOREDAC(PM2VDACRDColorFormat, 0x70); + } + break; + case 24: + temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; + STOREDAC(PM2VDACRDPixelSize, 0x04); + STOREDAC(PM2VDACRDColorFormat, 0x20); + break; + case 32: + temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; + if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { + temp3 |= 0x18; + STOREDAC(PM2VDACRDOverlayKey, pScrn->colorKey); + } + STOREDAC(PM2VDACRDPixelSize, 0x02); + STOREDAC(PM2VDACRDColorFormat, 0x20); + break; + } + STOREDAC(PM2VDACRDMiscControl, temp3); + + STOREREG(PM3FifoControl, 0x905); /* Lower the default fifo threshold */ + + return(TRUE); +} + +void +Permedia3Save(ScrnInfoPtr pScrn, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536); + + if ((pGlint->numMultiDevices == 2) || (IS_J2000)) { + SAVEREG(GCSRAperture); + } + + if (pGlint->MultiAperture) { + SAVEREG(GMultGLINTAperture); + SAVEREG(GMultGLINT1); + SAVEREG(GMultGLINT2); + } + + /* Permedia 3 memory Timings */ + SAVEREG(PM3MemBypassWriteMask); + SAVEREG(PM3ByAperture1Mode); + SAVEREG(PM3ByAperture2Mode); + SAVEREG(ChipConfig); + SAVEREG(Aperture0); + SAVEREG(Aperture1); + SAVEREG(PM3FifoControl); + + if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) + SAVEREG(DFIFODis); + SAVEREG(FIFODis); + SAVEREG(PMHTotal); + SAVEREG(PMHbEnd); + SAVEREG(PMHgEnd); + SAVEREG(PMScreenStride); + SAVEREG(PMHsStart); + SAVEREG(PMHsEnd); + SAVEREG(PMVTotal); + SAVEREG(PMVbEnd); + SAVEREG(PMVsStart); + SAVEREG(PMVsEnd); + SAVEREG(PMScreenBase); + SAVEREG(PMVideoControl); + SAVEREG(VClkCtl); + if (pGlint->UseFlatPanel) { + SAVEREG(VSConfiguration); + SAVEREG(VSBBase); + } + + for (i=0;i<768;i++) { + Permedia2ReadAddress(pScrn, i); + pReg->cmap[i] = Permedia2ReadData(pScrn); + } + + SAVEREG(PM2VDACRDIndexControl); + P2VIN(PM2VDACRDOverlayKey); + P2VIN(PM2VDACRDSyncControl); + P2VIN(PM2VDACRDMiscControl); + P2VIN(PM2VDACRDDACControl); + P2VIN(PM2VDACRDPixelSize); + P2VIN(PM2VDACRDColorFormat); + P2VIN(PM2VDACRDDClk0PreScale); + P2VIN(PM2VDACRDDClk0FeedbackScale); + P2VIN(PM2VDACRDDClk0PostScale); +} + +void +Permedia3Restore(ScrnInfoPtr pScrn, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 temp; + int i; + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + if (pGlint->STATE) + xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536); + + if ((pGlint->numMultiDevices == 2) || (IS_J2000)) { + RESTOREREG(GCSRAperture); + } + + if (pGlint->MultiAperture) { + RESTOREREG(GMultGLINTAperture); + RESTOREREG(GMultGLINT1); + RESTOREREG(GMultGLINT2); + } + + /* Permedia 3 memory Timings */ + RESTOREREG(PM3MemBypassWriteMask); + RESTOREREG(PM3ByAperture1Mode); + RESTOREREG(PM3ByAperture2Mode); + RESTOREREG(ChipConfig); + RESTOREREG(Aperture0); + RESTOREREG(Aperture1); + RESTOREREG(PM3FifoControl); + if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) + RESTOREREG(DFIFODis); + RESTOREREG(FIFODis); + RESTOREREG(PMVideoControl); + RESTOREREG(PMHbEnd); + RESTOREREG(PMHgEnd); + RESTOREREG(PMScreenBase); + RESTOREREG(VClkCtl); + RESTOREREG(PMScreenStride); + RESTOREREG(PMHTotal); + RESTOREREG(PMHsStart); + RESTOREREG(PMHsEnd); + RESTOREREG(PMVTotal); + RESTOREREG(PMVbEnd); + RESTOREREG(PMVsStart); + RESTOREREG(PMVsEnd); + + if (pGlint->UseFlatPanel) { + RESTOREREG(VSConfiguration); + RESTOREREG(VSBBase); + } + + RESTOREREG(PM2VDACRDIndexControl); + P2VOUT(PM2VDACRDOverlayKey); + P2VOUT(PM2VDACRDSyncControl); + P2VOUT(PM2VDACRDMiscControl); + P2VOUT(PM2VDACRDDACControl); + P2VOUT(PM2VDACRDPixelSize); + P2VOUT(PM2VDACRDColorFormat); + + for (i=0;i<768;i++) { + Permedia2WriteAddress(pScrn, i); + Permedia2WriteData(pScrn, pReg->cmap[i]); + } + + temp = Permedia2vInIndReg(pScrn, PM2VDACIndexClockControl) & 0xFC; + P2VOUT(PM2VDACRDDClk0PreScale); + P2VOUT(PM2VDACRDDClk0FeedbackScale); + P2VOUT(PM2VDACRDDClk0PostScale); + Permedia2vOutIndReg(pScrn, PM2VDACIndexClockControl, 0x00, temp|0x03); +} + +void Permedia3LoadPalette( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ +#if 0 + GLINTPtr pGlint = GLINTPTR(pScrn); +#endif + int i, index, shift = 0, j, repeat = 1; + + if (pScrn->depth == 15) { + repeat = 8; + shift = 3; + } + + for(i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < repeat; j++) { + Permedia2WriteAddress(pScrn, (index << shift)+j); + Permedia2WriteData(pScrn, colors[index].red); + Permedia2WriteData(pScrn, colors[index].green); + Permedia2WriteData(pScrn, colors[index].blue); + } +#if 0 + GLINT_SLOW_WRITE_REG(index, PM3LUTIndex); + GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | + ((colors[index].green & 0xFF) << 8) | + ((colors[index].blue & 0xFF) << 16), + PM3LUTData); +#endif + } +} + +/* special one for 565 mode */ +void Permedia3LoadPalette16( + ScrnInfoPtr pScrn, + int numColors, + int *indices, + LOCO *colors, + VisualPtr pVisual +){ +#if 0 + GLINTPtr pGlint = GLINTPTR(pScrn); +#endif + int i, index, j; + + for(i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 4; j++) { + Permedia2WriteAddress(pScrn, (index << 2)+j); + Permedia2WriteData(pScrn, colors[index >> 1].red); + Permedia2WriteData(pScrn, colors[index].green); + Permedia2WriteData(pScrn, colors[index >> 1].blue); + } +#if 0 + GLINT_SLOW_WRITE_REG(index, PM3LUTIndex); + GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | + ((colors[index].green & 0xFF) << 8) | + ((colors[index].blue & 0xFF) << 16), + PM3LUTData); +#endif + + if(index <= 31) { + for (j = 0; j < 4; j++) { + Permedia2WriteAddress(pScrn, (index << 3)+j); + Permedia2WriteData(pScrn, colors[index].red); + Permedia2WriteData(pScrn, colors[(index << 1) + 1].green); + Permedia2WriteData(pScrn, colors[index].blue); + } + } + } +} diff --git a/src/pm3_regs.h b/src/pm3_regs.h new file mode 100644 index 0000000..be9fc51 --- /dev/null +++ b/src/pm3_regs.h @@ -0,0 +1,1111 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.10 2003/01/12 03:55:47 tsi Exp $ */ + +/* + * glint register file + * + * Copyright by Sven Luther + * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> + * Thomas Witzel, <twitzel@nmr.mgh.harvard.edu> + * + * this work is sponsored by Appian Graphics. + * + */ + +#ifndef _PM3_REG_H_ +#define _PM3_REG_H_ + +/********************************************** +* GLINT Permedia3 Control Status registers * +***********************************************/ +/* Control Status Registers */ +#define PM3ResetStatus 0x0000 +#define PM3IntEnable 0x0008 +#define PM3IntFlags 0x0010 +#define PM3InFIFOSpace 0x0018 +#define PM3OutFIFOWords 0x0020 +#define PM3DMAAddress 0x0028 +#define PM3DMACount 0x0030 +#define PM3ErrorFlags 0x0038 +#define PM3VClkCtl 0x0040 +#define PM3TestRegister 0x0048 +#define PM3Aperture0 0x0050 +#define PM3Aperture1 0x0058 +#define PM3DMAControl 0x0060 +#define PM3FIFODis 0x0068 +#define PM3ChipConfig 0x0070 +#define PM3AGPControl 0x0078 + +#define PM3GPOutDMAAddress 0x0080 +#define PM3PCIFeedbackCount 0x0088 +#define PM3PCIAbortStatus 0x0090 +#define PM3PCIAbortAddress 0x0098 + +#define PM3PCIPLLStatus 0x00f0 + +#define PM3HostTextureAddress 0x0100 +#define PM3TextureDownloadControl 0x0108 +#define PM3TextureOperation 0x0110 +#define PM3LogicalTexturePage 0x0118 +#define PM3TexDMAAddress 0x0120 +#define PM3TexFIFOSpace 0x0128 + +/********************************************** +* GLINT Permedia3 Region 0 Bypass Controls * +***********************************************/ +#define PM3ByAperture1Mode 0x0300 +# define PM3ByApertureMode_BYTESWAP_ABCD (0<<0) +# define PM3ByApertureMode_BYTESWAP_BADC (1<<0) +# define PM3ByApertureMode_BYTESWAP_CDAB (2<<0) +# define PM3ByApertureMode_BYTESWAP_DCBA (3<<0) +# define PM3ByApertureMode_PATCH_DISABLE (0<<2) +# define PM3ByApertureMode_PATCH_ENABLE (1<<2) +# define PM3ByApertureMode_FORMAT_RAW (0<<3) +# define PM3ByApertureMode_FORMAT_YUYV (1<<3) +# define PM3ByApertureMode_FORMAT_UYVY (2<<3) +# define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5) +# define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5) +# define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7) +# define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9) +# define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16) +# define PM3ByApertureMode_FRAMEBUFFER (0<<21) +# define PM3ByApertureMode_LOCALBUFFER (1<<21) +# define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22) + +#define PM3ByAperture2Mode 0x0328 + +/********************************************** +* GLINT Permedia3 Memory Control (0x1000) * +***********************************************/ +#define PM3MemCounter 0x1000 +#define PM3MemBypassWriteMask 0x1008 +#define PM3MemScratch 0x1010 +#define PM3LocalMemCaps 0x1018 +# define PM3LocalMemCaps_NoWriteMask (1<<28) +#define PM3LocalMemTimings 0x1020 +#define PM3LocalMemControl 0x1028 +#define PM3LocalMemRefresh 0x1030 +#define PM3LocalMemPowerDown 0x1038 +#define PM3RemoteMemControl 0x1100 + +/********************************************** +* GLINT Permedia3 Video Control (0x3000) * +***********************************************/ + +#define PM3ScreenBase 0x3000 +#define PM3ScreenStride 0x3008 +#define PM3HTotal 0x3010 +#define PM3HgEnd 0x3018 +#define PM3HbEnd 0x3020 +#define PM3HsStart 0x3028 +#define PM3HsEnd 0x3030 +#define PM3VTotal 0x3038 +#define PM3VbEnd 0x3040 +#define PM3VsStart 0x3048 +#define PM3VsEnd 0x3050 +#define PM3VideoControl 0x3058 +# define PM3VideoControl_DISABLE (0<<0) +# define PM3VideoControl_ENABLE (1<<0) +# define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1) +# define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1) +# define PM3VideoControl_LINE_DOUBLE_OFF (0<<2) +# define PM3VideoControl_LINE_DOUBLE_ON (1<<2) +# define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3) +# define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3) +# define PM3VideoControl_HSYNC_FORCE_LOW (2<<3) +# define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3) +# define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5) +# define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5) +# define PM3VideoControl_VSYNC_FORCE_LOW (2<<5) +# define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5) +# define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7) +# define PM3VideoControl_BYTE_DOUBLE_ON (1<<7) +# define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9) +# define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9) +# define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9) +# define PM3VideoControl_STEREO_DISABLE (0<<11) +# define PM3VideoControl_STEREO_ENABLE (1<<11) +# define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12) +# define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12) +# define PM3VideoControl_VIDEO_EXT_LOW (0<<14) +# define PM3VideoControl_VIDEO_EXT_HIGH (1<<14) +# define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16) +# define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16) +# define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16) +# define PM3VideoControl_PATCH_DISABLE (0<<18) +# define PM3VideoControl_PATCH_ENABLE (1<<18) +# define PM3VideoControl_PIXELSIZE_8BIT (0<<19) +# define PM3VideoControl_PIXELSIZE_16BIT (1<<19) +# define PM3VideoControl_PIXELSIZE_32BIT (2<<19) +# define PM3VideoControl_DISPLAY_DISABLE (0<<21) +# define PM3VideoControl_DISPLAY_ENABLE (1<<21) +# define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22) +# define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28) +#define PM3InterruptLine 0x3060 +#define PM3DisplayData 0x3068 +#define PM3VerticalLineCount 0x3070 +#define PM3FifoControl 0x3078 +#define PM3ScreenBaseRight 0x3080 +#define PM3MiscControl 0x3088 + +#define PM3VideoOverlayUpdate 0x3100 +# define PM3VideoOverlayUpdate_DISABLE (0<<0) +# define PM3VideoOverlayUpdate_ENABLE (1<<0) +#define PM3VideoOverlayMode 0x3108 +# define PM3VideoOverlayMode_DISABLE (0<<0) +# define PM3VideoOverlayMode_ENABLE (1<<0) +# define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1) +# define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1) +# define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1) +# define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4) +# define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4) +# define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5) +# define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5) +# define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5) +# define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5)) +# define PM3VideoOverlayMode_COLORORDER_BGR (0<<12) +# define PM3VideoOverlayMode_COLORORDER_RGB (1<<12) +# define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13) +# define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13) +# define PM3VideoOverlayMode_FILTER_MASK (3<<14) +# define PM3VideoOverlayMode_FILTER_OFF (0<<14) +# define PM3VideoOverlayMode_FILTER_FULL (1<<14) +# define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14) +# define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16) +# define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16) +# define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18) +# define PM3VideoOverlayMode_PATCHMODE_ON (1<<18) +# define PM3VideoOverlayMode_FLIP_VIDEO (0<<20) +# define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20) +# define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20) +# define PM3VideoOverlayMode_MIRROR_MASK (3<<23) +# define PM3VideoOverlayMode_MIRRORX_OFF (0<<23) +# define PM3VideoOverlayMode_MIRRORX_ON (1<<23) +# define PM3VideoOverlayMode_MIRRORY_OFF (0<<24) +# define PM3VideoOverlayMode_MIRRORY_ON (1<<24) +#define PM3VideoOverlayFifoControl 0x3110 +#define PM3VideoOverlayIndex 0x3118 +#define PM3VideoOverlayBase 0x3120 +#define PM3VideoOverlayBase0 0x3120 +#define PM3VideoOverlayBase1 0x3128 +#define PM3VideoOverlayBase2 0x3130 +#define PM3VideoOverlayStride 0x3138 +# define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0) +#define PM3VideoOverlayWidth 0x3140 +# define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0) +#define PM3VideoOverlayHeight 0x3148 +# define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0) +#define PM3VideoOverlayOrigin 0x3150 +# define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0) +# define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16) +#define PM3VideoOverlayShrinkXDelta 0x3158 +# define PM3VideoOverlayShrinkXDelta_NONE (1<<16) +# define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \ + ((((s)<<16)/(d))&0x0ffffff0) +#define PM3VideoOverlayZoomXDelta 0x3160 +# define PM3VideoOverlayZoomXDelta_NONE (1<<16) +# define PM3VideoOverlayZoomXDelta_DELTA(s,d) \ + ((((s)<<16)/(d))&0x0001fff0) +#define PM3VideoOverlayYDelta 0x3168 +# define PM3VideoOverlayYDelta_NONE (1<<16) +# define PM3VideoOverlayYDelta_DELTA(s,d) \ + ((((s)<<16)/(d))&0x0ffffff0) +#define PM3VideoOverlayFieldOffset 0x3170 +#define PM3VideoOverlayStatus 0x3178 + +/********************************************** +* GLINT Permedia3 RAMDAC Registers (0x4000) * +***********************************************/ +/* Direct Registers */ +#define PM3RD_PaletteWriteAddress 0x4000 +#define PM3RD_PaletteData 0x4008 +#define PM3RD_PixelMask 0x4010 +#define PM3RD_PaletteReadAddress 0x4018 + +#define PM3RD_IndexLow 0x4020 +#define PM3RD_IndexHigh 0x4028 +#define PM3RD_IndexedData 0x4030 +#define PM3RD_IndexControl 0x4038 +# define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0) +# define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0) + +/* Indirect Registers */ +#define PM3RD_MiscControl 0x000 +# define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0) +# define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0) +# define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1) +# define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1) +# define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2) +# define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2) +# define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3) +# define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3) +# define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4) +# define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4) +# define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5) +# define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5) +# define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6) +# define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6) +# define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7) +# define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7) +#define PM3RD_SyncControl 0x001 +# define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0) +# define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0) +# define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0) +# define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0) +# define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0) +# define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3) +# define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3) +# define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3) +# define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3) +# define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3) +# define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6) +# define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6) +# define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7) +# define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7) +#define PM3RD_DACControl 0x002 +# define PM3RD_DACControl_DAC_POWER_ON (0<<0) +# define PM3RD_DACControl_DAC_POWER_OFF (1<<0) +# define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3) +# define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3) +# define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4) +# define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4) +# define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5) +# define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5) +# define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6) +# define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6) +# define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7) +# define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7) +#define PM3RD_PixelSize 0x003 +# define PM3RD_PixelSize_24_BIT_PIXELS (4<<0) +# define PM3RD_PixelSize_32_BIT_PIXELS (2<<0) +# define PM3RD_PixelSize_16_BIT_PIXELS (1<<0) +# define PM3RD_PixelSize_8_BIT_PIXELS (0<<0) +#define PM3RD_ColorFormat 0x004 +# define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6) +# define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6) +# define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5) +# define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5) +# define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0) +# define PM3RD_ColorFormat_8888_COLOR (0<<0) +# define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0) +# define PM3RD_ColorFormat_4444_COLOR (2<<0) +# define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0) +# define PM3RD_ColorFormat_332_BACK_COLOR (6<<0) +# define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0) +# define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0) +# define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0) +# define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0) +# define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0) +# define PM3RD_ColorFormat_CI8_COLOR (14<<0) +# define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0) +# define PM3RD_ColorFormat_565_BACK_COLOR (17<<0) +#define PM3RD_CursorMode 0x005 +# define PM3RD_CursorMode_CURSOR_DISABLE (0<<0) +# define PM3RD_CursorMode_CURSOR_ENABLE (1<<0) +# define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2) +# define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2) +# define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2) +# define PM3RD_CursorMode_TYPE_MS (0<<4) +# define PM3RD_CursorMode_TYPE_X (1<<4) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6) +#define PM3RD_CursorControl 0x006 +# define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0) +# define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0) +# define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1) +# define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1) +# define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2) +# define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2) + +#define PM3RD_CursorXLow 0x007 +#define PM3RD_CursorXHigh 0x008 +#define PM3RD_CursorYLow 0x009 +#define PM3RD_CursorYHigh 0x00a +#define PM3RD_CursorHotSpotX 0x00b +#define PM3RD_CursorHotSpotY 0x00c +#define PM3RD_OverlayKey 0x00d +#define PM3RD_Pan 0x00e +# define PM3RD_Pan_DISABLE (0<<0) +# define PM3RD_Pan_ENABLE (1<<0) +# define PM3RD_Pan_GATE_DISABLE (0<<1) +# define PM3RD_Pan_GATE_ENABLE (1<<1) +#define PM3RD_Sense 0x00f + +#define PM3RD_CheckControl 0x018 +# define PM3RD_CheckControl_PIXEL_DISABLED (0<<0) +# define PM3RD_CheckControl_PIXEL_ENABLED (1<<0) +# define PM3RD_CheckControl_LUT_DISABLED (0<<1) +# define PM3RD_CheckControl_LUT_ENABLED (1<<1) +#define PM3RD_CheckPixelRed 0x019 +#define PM3RD_CheckPixelGreen 0x01a +#define PM3RD_CheckPixelBlue 0x01b +#define PM3RD_CheckLUTRed 0x01c +#define PM3RD_CheckLUTGreen 0x01d +#define PM3RD_CheckLUTBlue 0x01e +#define PM3RD_Scratch 0x01f + +#define PM3RD_VideoOverlayControl 0x020 +# define PM3RD_VideoOverlayControl_DISABLE (0<<0) +# define PM3RD_VideoOverlayControl_ENABLE (1<<0) +# define PM3RD_VideoOverlayControl_MODE_MASK (3<<1) +# define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1) +# define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1) +# define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1) +# define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1) +# define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3) +# define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3) +# define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4) +# define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4) +# define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5) +# define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5) +#define PM3RD_VideoOverlayXStartLow 0x021 +#define PM3RD_VideoOverlayXStartHigh 0x022 +#define PM3RD_VideoOverlayYStartLow 0x023 +#define PM3RD_VideoOverlayYStartHigh 0x024 +#define PM3RD_VideoOverlayXEndLow 0x025 +#define PM3RD_VideoOverlayXEndHigh 0x026 +#define PM3RD_VideoOverlayYEndLow 0x027 +#define PM3RD_VideoOverlayYEndHigh 0x028 +#define PM3RD_VideoOverlayKeyR 0x029 +#define PM3RD_VideoOverlayKeyG 0x02a +#define PM3RD_VideoOverlayKeyB 0x02b +#define PM3RD_VideoOverlayBlend 0x02c +# define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6) + +#define PM3RD_DClkSetup1 0x1f0 +#define PM3RD_DClkSetup2 0x1f1 +#define PM3RD_KClkSetup1 0x1f2 +#define PM3RD_KClkSetup2 0x1f3 + +#define PM3RD_DClkControl 0x200 +# define PM3RD_DClkControl_SOURCE_PLL (0<<4) +# define PM3RD_DClkControl_SOURCE_VSA (1<<4) +# define PM3RD_DClkControl_SOURCE_VSB (2<<4) +# define PM3RD_DClkControl_SOURCE_EXT (3<<4) +# define PM3RD_DClkControl_STATE_RUN (2<<2) +# define PM3RD_DClkControl_STATE_HIGH (1<<2) +# define PM3RD_DClkControl_STATE_LOW (0<<2) +# define PM3RD_DClkControl_LOCKED (1<<1) +# define PM3RD_DClkControl_NOT_LOCKED (0<<1) +# define PM3RD_DClkControl_ENABLE (1<<0) +# define PM3RD_DClkControl_DISABLE (0<<0) +#define PM3RD_DClk0PreScale 0x201 +#define PM3RD_DClk0FeedbackScale 0x202 +#define PM3RD_DClk0PostScale 0x203 +#define PM3RD_DClk1PreScale 0x204 +#define PM3RD_DClk1FeedbackScale 0x205 +#define PM3RD_DClk1PostScale 0x206 +#define PM3RD_DClk2PreScale 0x207 +#define PM3RD_DClk2FeedbackScale 0x208 +#define PM3RD_DClk2PostScale 0x209 +#define PM3RD_DClk3PreScale 0x20a +#define PM3RD_DClk3FeedbackScale 0x20b +#define PM3RD_DClk3PostScale 0x20c +#define PM3RD_KClkControl 0x20d +# define PM3RD_KClkControl_DISABLE (0<<0) +# define PM3RD_KClkControl_ENABLE (1<<0) +# define PM3RD_KClkControl_NOT_LOCKED (0<<1) +# define PM3RD_KClkControl_LOCKED (1<<1) +# define PM3RD_KClkControl_STATE_LOW (0<<2) +# define PM3RD_KClkControl_STATE_HIGH (1<<2) +# define PM3RD_KClkControl_STATE_RUN (2<<2) +# define PM3RD_KClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_KClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_KClkControl_SOURCE_PLL (2<<4) +#define PM3RD_KClkPreScale 0x20e +#define PM3RD_KClkFeedbackScale 0x20f +#define PM3RD_KClkPostScale 0x210 +#define PM3RD_MClkControl 0x211 +# define PM3RD_MClkControl_DISABLE (0<<0) +# define PM3RD_MClkControl_ENABLE (1<<0) +# define PM3RD_MClkControl_NOT_LOCKED (0<<1) +# define PM3RD_MClkControl_LOCKED (1<<1) +# define PM3RD_MClkControl_STATE_LOW (0<<2) +# define PM3RD_MClkControl_STATE_HIGH (1<<2) +# define PM3RD_MClkControl_STATE_RUN (2<<2) +# define PM3RD_MClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_MClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4) +# define PM3RD_MClkControl_SOURCE_EXT (4<<4) +# define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4) +# define PM3RD_MClkControl_SOURCE_KCLK (6<<4) +#define PM3RD_MClkPreScale 0x212 +#define PM3RD_MClkFeedbackScale 0x213 +#define PM3RD_MClkPostScale 0x214 +#define PM3RD_SClkControl 0x215 +# define PM3RD_SClkControl_DISABLE (0<<0) +# define PM3RD_SClkControl_ENABLE (1<<0) +# define PM3RD_SClkControl_NOT_LOCKED (0<<1) +# define PM3RD_SClkControl_LOCKED (1<<1) +# define PM3RD_SClkControl_STATE_LOW (0<<2) +# define PM3RD_SClkControl_STATE_HIGH (1<<2) +# define PM3RD_SClkControl_STATE_RUN (2<<2) +# define PM3RD_SClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_SClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4) +# define PM3RD_SClkControl_SOURCE_EXT (4<<4) +# define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4) +# define PM3RD_SClkControl_SOURCE_KCLK (6<<4) +#define PM3RD_SClkPreScale 0x216 +#define PM3RD_SClkFeedbackScale 0x217 +#define PM3RD_SClkPostScale 0x218 + +#define PM3RD_CursorPalette(p) (0x303+(p)) +#define PM3RD_CursorPattern(p) (0x400+(p)) +/****************************************************** +* GLINT Permedia3 Video Streaming Registers (0x5000) * +*******************************************************/ + +#define PM3VSConfiguration 0x5800 + +/********************************************** +* GLINT Permedia3 Core Registers (0x8000+) * +***********************************************/ +#define PM3AALineWidth 0x94c0 +#define PM3AAPointsize 0x94a0 +#define PM3AlphaBlendAlphaMode 0xafa8 +#define PM3AlphaBlendAlphaModeAnd 0xad30 +#define PM3AlphaBlendAlphaModeOr 0xad38 +#define PM3AlphaBlendColorMode 0xafa0 +#define PM3AlphaBlendColorModeAnd 0xacb0 +#define PM3AlphaBlendColorModeOr 0xacb8 +#define PM3AlphaDestColor 0xaf88 +#define PM3AlphaSourceColor 0xaf80 +#define PM3AlphaTestMode 0x8800 +#define PM3AlphaTestModeAnd 0xabf0 +#define PM3AlphaTestModeOr 0xabf8 +#define PM3AntialiasMode 0x8808 +#define PM3AntialiasModeAnd 0xac00 +#define PM3AntialiasModeOr 0xac08 +/* ... */ +#define PM3BackgroundColor 0xb0c8 +/* ... */ +#define PM3ColorDDAMode 0x87e0 +#define PM3ColorDDAModeAnd 0xabe0 +#define PM3ColorDDAModeOr 0xabe8 +#define PM3CommandInterrupt 0xa990 +#define PM3ConstantColorDDA 0xafb0 +# define PM3ConstantColorDDA_R(r) ((r)&0xff) +# define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8) +# define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16) +# define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24) +#define PM3ContextData 0x8dd0 +#define PM3ContextDump 0x8dc0 +#define PM3ContextRestore 0x8dc8 +#define PM3Continue 0x8058 +#define PM3ContinueNewDom 0x8048 +#define PM3ContinueNewLine 0x8040 +#define PM3ContinueNewSub 0x8050 +#define PM3Count 0x8030 +/* ... */ +#define PM3DeltaControl 0x9350 +#define PM3DeltaControlAnd 0xab20 +#define PM3DeltaControlOr 0xab28 +#define PM3DeltaMode 0x9300 +#define PM3DeltaModeAnd 0xaad0 +#define PM3DeltaModeOr 0xaad8 +/* ... */ +#define PM3DitherMode 0x8818 +#define PM3DitherModeAnd 0xacd0 +#define PM3DitherModeOr 0xacd8 +/* ... */ +#define PM3dXDom 0x8008 +#define PM3dXSub 0x8018 +#define PM3dY 0x8028 +/* ... */ +#define PM3FBBlockColor 0x8ac8 +#define PM3FBBlockColor0 0xb060 +#define PM3FBBlockColor1 0xb068 +#define PM3FBBlockColor2 0xb070 +#define PM3FBBlockColor3 0xb078 +#define PM3FBBlockColorBack 0xb0a0 +#define PM3FBBlockColorBack0 0xb080 +#define PM3FBBlockColorBack1 0xb088 +#define PM3FBBlockColorBack2 0xb090 +#define PM3FBBlockColorBack3 0xb098 +#define PM3FBColor 0x8a98 +#define PM3FBDestReadBufferAddr0 0xae80 +#define PM3FBDestReadBufferAddr1 0xae88 +#define PM3FBDestReadBufferAddr2 0xae90 +#define PM3FBDestReadBufferAddr3 0xae98 +#define PM3FBDestReadBufferOffset0 0xaea0 +#define PM3FBDestReadBufferOffset1 0xaea8 +#define PM3FBDestReadBufferOffset2 0xaeb0 +#define PM3FBDestReadBufferOffset3 0xaeb8 +# define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +#define PM3FBDestReadBufferWidth0 0xaec0 +#define PM3FBDestReadBufferWidth1 0xaec8 +#define PM3FBDestReadBufferWidth2 0xaed0 +#define PM3FBDestReadBufferWidth3 0xaed8 +# define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff) + +#define PM3FBDestReadEnables 0xaee8 +#define PM3FBDestReadEnablesAnd 0xad20 +#define PM3FBDestReadEnablesOr 0xad28 +# define PM3FBDestReadEnables_E(e) ((e)&0xff) +# define PM3FBDestReadEnables_E0 1<<0 +# define PM3FBDestReadEnables_E1 1<<1 +# define PM3FBDestReadEnables_E2 1<<2 +# define PM3FBDestReadEnables_E3 1<<3 +# define PM3FBDestReadEnables_E4 1<<4 +# define PM3FBDestReadEnables_E5 1<<5 +# define PM3FBDestReadEnables_E6 1<<6 +# define PM3FBDestReadEnables_E7 1<<7 +# define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) +# define PM3FBDestReadEnables_R0 1<<8 +# define PM3FBDestReadEnables_R1 1<<9 +# define PM3FBDestReadEnables_R2 1<<10 +# define PM3FBDestReadEnables_R3 1<<11 +# define PM3FBDestReadEnables_R4 1<<12 +# define PM3FBDestReadEnables_R5 1<<13 +# define PM3FBDestReadEnables_R6 1<<14 +# define PM3FBDestReadEnables_R7 1<<15 +# define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) + +#define PM3FBDestReadMode 0xaee0 +#define PM3FBDestReadModeAnd 0xac90 +#define PM3FBDestReadModeOr 0xac98 +# define PM3FBDestReadMode_ReadDisable 0<<0 +# define PM3FBDestReadMode_ReadEnable 1<<0 +# define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2 +# define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7 +# define PM3FBDestReadMode_Enable0 1<<8 +# define PM3FBDestReadMode_Enable1 1<<9 +# define PM3FBDestReadMode_Enable2 1<<10 +# define PM3FBDestReadMode_Enable3 1<<11 +# define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12 +# define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14 +# define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16 +# define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18 +# define PM3FBDestReadMode_Origin0 1<<20 +# define PM3FBDestReadMode_Origin1 1<<21 +# define PM3FBDestReadMode_Origin2 1<<22 +# define PM3FBDestReadMode_Origin3 1<<23 +# define PM3FBDestReadMode_Blocking 1<<24 +# define PM3FBDestReadMode_UseReadEnabled 1<<26 +# define PM3FBDestReadMode_AlphaFiltering 1<<27 + +#define PM3FBHardwareWriteMask 0x8ac0 +#define PM3FBSoftwareWriteMask 0x8820 +#define PM3FBData 0x8aa0 +#define PM3FBSourceData 0x8aa8 +#define PM3FBSourceReadBufferAddr 0xaf08 +#define PM3FBSourceReadBufferOffset 0xaf10 +# define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +#define PM3FBSourceReadBufferWidth 0xaf18 +# define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff) +#define PM3FBSourceReadMode 0xaf00 +#define PM3FBSourceReadModeAnd 0xaca0 +#define PM3FBSourceReadModeOr 0xaca8 +# define PM3FBSourceReadMode_ReadDisable (0<<0) +# define PM3FBSourceReadMode_ReadEnable (1<<0) +# define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2 +# define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7 +# define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8 +# define PM3FBSourceReadMode_Origin 1<<10 +# define PM3FBSourceReadMode_Blocking 1<<11 +# define PM3FBSourceReadMode_UserTexelCoord 1<<13 +# define PM3FBSourceReadMode_WrapXEnable 1<<14 +# define PM3FBSourceReadMode_WrapYEnable 1<<15 +# define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16 +# define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20 +# define PM3FBSourceReadMode_ExternalSourceData 1<<24 +#define PM3FBWriteBufferAddr0 0xb000 +#define PM3FBWriteBufferAddr1 0xb008 +#define PM3FBWriteBufferAddr2 0xb010 +#define PM3FBWriteBufferAddr3 0xb018 + +#define PM3FBWriteBufferOffset0 0xb020 +#define PM3FBWriteBufferOffset1 0xb028 +#define PM3FBWriteBufferOffset2 0xb030 +#define PM3FBWriteBufferOffset3 0xb038 +# define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16) + +#define PM3FBWriteBufferWidth0 0xb040 +#define PM3FBWriteBufferWidth1 0xb048 +#define PM3FBWriteBufferWidth2 0xb050 +#define PM3FBWriteBufferWidth3 0xb058 +# define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff) + +#define PM3FBWriteMode 0x8ab8 +#define PM3FBWriteModeAnd 0xacf0 +#define PM3FBWriteModeOr 0xacf8 +# define PM3FBWriteMode_WriteDisable 0<<0 +# define PM3FBWriteMode_WriteEnable 1<<0 +# define PM3FBWriteMode_Replicate 1<<4 +# define PM3FBWriteMode_OpaqueSpan 1<<5 +# define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6) +# define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9) +# define PM3FBWriteMode_Enable0 1<<12 +# define PM3FBWriteMode_Enable1 1<<13 +# define PM3FBWriteMode_Enable2 1<<14 +# define PM3FBWriteMode_Enable3 1<<15 +# define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16) +# define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18) +# define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20) +# define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22) +# define PM3FBWriteMode_Origin0 1<<24 +# define PM3FBWriteMode_Origin1 1<<25 +# define PM3FBWriteMode_Origin2 1<<26 +# define PM3FBWriteMode_Origin3 1<<27 +#define PM3ForegroundColor 0xb0c0 +/* ... */ +#define PM3GIDMode 0xb538 +#define PM3GIDModeAnd 0xb5b0 +#define PM3GIDModeOr 0xb5b8 +/* ... */ +#define PM3LBDestReadBufferAddr 0xb510 +#define PM3LBDestReadBufferOffset 0xb518 +#define PM3LBDestReadEnables 0xb508 +#define PM3LBDestReadEnablesAnd 0xb590 +#define PM3LBDestReadEnablesOr 0xb598 +#define PM3LBDestReadMode 0xb500 +#define PM3LBDestReadModeAnd 0xb580 +#define PM3LBDestReadModeOr 0xb588 +# define PM3LBDestReadMode_Disable 0<<0 +# define PM3LBDestReadMode_Enable 1<<0 +# define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) +# define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) +# define PM3LBDestReadMode_Layout 1<<8 +# define PM3LBDestReadMode_Origin 1<<9 +# define PM3LBDestReadMode_UserReadEnables 1<<10 +# define PM3LBDestReadMode_Packed16 1<<11 +# define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) +#define PM3LBReadFormat 0x8888 +# define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) +# define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2) +# define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6) +# define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11) +# define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15) +# define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20) +# define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23) +#define PM3LBSourceReadBufferAddr 0xb528 +#define PM3LBSourceReadBufferOffset 0xb530 +#define PM3LBSourceReadMode 0xb520 +#define PM3LBSourceReadModeAnd 0xb5a0 +#define PM3LBSourceReadModeOr 0xb5a8 +# define PM3LBSourceReadMode_Enable 1<<0 +# define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) +# define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) +# define PM3LBSourceReadMode_Layout 1<<8 +# define PM3LBSourceReadMode_Origin 1<<9 +# define PM3LBSourceReadMode_Packed16 1<<10 +# define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) +#define PM3LBStencil 0x88a8 +#define PM3LBWriteBufferAddr 0xb540 +#define PM3LBWriteBufferOffset 0xb548 +#define PM3LBWriteFormat 0x88c8 +# define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0) +# define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2) +# define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6) +# define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20) +# define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23) +#define PM3LBWriteMode 0x88c0 +#define PM3LBWriteModeAnd 0xac80 +#define PM3LBWriteModeOr 0xac88 +# define PM3LBWriteMode_WriteDisable 0<<0 +# define PM3LBWriteMode_WriteEnable 1<<0 +# define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) +# define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) +# define PM3LBWriteMode_Layout 1<<9 +# define PM3LBWriteMode_Origin 1<<10 +# define PM3LBWriteMode_Packed16 1<<11 +# define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) +/* ... */ +#define PM3LineStippleMode 0x81a8 +#define PM3LineStippleModeAnd 0xabc0 +#define PM3LineStippleModeOr 0xabc8 +#define PM3LoadLineStippleCounters 0x81b0 +/* ... */ +#define PM3LogicalOpMode 0x8828 +#define PM3LogicalOpModeAnd 0xace0 +#define PM3LogicalOpModeOr 0xace8 +# define PM3LogicalOpMode_Disable (0<<0) +# define PM3LogicalOpMode_Enable (1<<0) +# define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1) +# define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5) +# define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5) +# define PM3LogicalOpMode_Background_Disable (0<<6) +# define PM3LogicalOpMode_Background_Enable (1<<6) +# define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7) +# define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) +# define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) + +/* ... */ +#define PM3LUT 0x8e80 +/* ... */ +#define PM3LUT 0x8e80 +#define PM3LUTAddress 0x84d0 +#define PM3LUTData 0x84c8 +#define PM3LUTIndex 0x84c0 +#define PM3LUTMode 0xb378 +#define PM3LUTModeAnd 0xad70 +#define PM3LUTModeOr 0xad78 +#define PM3LUTTransfer 0x84d8 +/* ... */ +#define PM3PixelSize 0x80c0 +# define PM3PixelSize_GLOBAL_32BIT (0<<0) +# define PM3PixelSize_GLOBAL_16BIT (1<<0) +# define PM3PixelSize_GLOBAL_8BIT (2<<0) +# define PM3PixelSize_RASTERIZER_32BIT (0<<2) +# define PM3PixelSize_RASTERIZER_16BIT (1<<2) +# define PM3PixelSize_RASTERIZER_8BIT (2<<2) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4) +# define PM3PixelSize_TEXTURE_32BIT (0<<6) +# define PM3PixelSize_TEXTURE_16BIT (1<<6) +# define PM3PixelSize_TEXTURE_8BIT (2<<6) +# define PM3PixelSize_LUT_32BIT (0<<8) +# define PM3PixelSize_LUT_16BIT (1<<8) +# define PM3PixelSize_LUT_8BIT (2<<8) +# define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10) +# define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10) +# define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10) +# define PM3PixelSize_LOGICAL_OP_32BIT (0<<12) +# define PM3PixelSize_LOGICAL_OP_16BIT (1<<12) +# define PM3PixelSize_LOGICAL_OP_8BIT (2<<12) +# define PM3PixelSize_LOCALBUFFER_32BIT (0<<14) +# define PM3PixelSize_LOCALBUFFER_16BIT (1<<14) +# define PM3PixelSize_LOCALBUFFER_8BIT (2<<14) +# define PM3PixelSize_SETUP_32BIT (0<<16) +# define PM3PixelSize_SETUP_16BIT (1<<16) +# define PM3PixelSize_SETUP_8BIT (2<<16) +# define PM3PixelSize_GLOBAL (0<<31) +# define PM3PixelSize_INDIVIDUAL (1<<31) +/* ... */ +#define PM3Render 0x8038 +# define PM3Render_AreaStipple_Disable (0<<0) +# define PM3Render_AreaStipple_Enable (1<<0) +# define PM3Render_LineStipple_Disable (0<<1) +# define PM3Render_LineStipple_Enable (1<<1) +# define PM3Render_ResetLine_Disable (0<<2) +# define PM3Render_ResetLine_Enable (1<<2) +# define PM3Render_FastFill_Disable (0<<3) +# define PM3Render_FastFill_Enable (1<<3) +# define PM3Render_Primitive_Line (0<<6) +# define PM3Render_Primitive_Trapezoid (1<<6) +# define PM3Render_Primitive_Point (2<<6) +# define PM3Render_Antialias_Disable (0<<8) +# define PM3Render_Antialias_Enable (1<<8) +# define PM3Render_Antialias_SubPixelRes_4x4 (0<<9) +# define PM3Render_Antialias_SubPixelRes_8x8 (1<<9) +# define PM3Render_UsePointTable_Disable (0<<10) +# define PM3Render_UsePointTable_Enable (1<<10) +# define PM3Render_SyncOnbitMask_Disable (0<<11) +# define PM3Render_SyncOnBitMask_Enable (1<<11) +# define PM3Render_SyncOnHostData_Disable (0<<12) +# define PM3Render_SyncOnHostData_Enable (1<<12) +# define PM3Render_Texture_Disable (0<<13) +# define PM3Render_Texture_Enable (1<<13) +# define PM3Render_Fog_Disable (0<<14) +# define PM3Render_Fog_Enable (1<<14) +# define PM3Render_Coverage_Disable (0<<15) +# define PM3Render_Coverage_Enable (1<<15) +# define PM3Render_SubPixelCorrection_Disable (0<<16) +# define PM3Render_SubPixelCorrection_Enable (1<<16) +# define PM3Render_SpanOperation_Disable (0<<18) +# define PM3Render_SpanOperation_Enable (1<<18) +# define PM3Render_FBSourceRead_Disable (0<<27) +# define PM3Render_FBSourceRead_Enable (1<<27) +#define PM3RasterizerMode 0x80a0 +#define PM3RasterizerModeAnd 0xaba0 +#define PM3RasterizerModeOr 0xabb8 +#define PM3RectangleHeight 0x94e0 +#define PM3Render 0x8038 +#define PM3RepeatLine 0x9328 +#define PM3ResetPickResult 0x8c20 +#define PM3RLEMask 0x8c48 +#define PM3RouterMode 0x8840 +#define PM3RStart 0x8780 +#define PM3S1Start 0x8400 +#define PM3aveLineStippleCounters 0x81c0 +#define PM3ScissorMaxXY 0x8190 +#define PM3ScissorMinXY 0x8188 +#define PM3ScissorMode 0x8180 +#define PM3ScissorModeAnd 0xabb0 +#define PM3ScissorModeOr 0xabb8 +#define PM3ScreenSize 0x8198 +#define PM3Security 0x8908 +#define PM3SetLogicalTexturePage 0xb360 +#define PM3SizeOfFramebuffer 0xb0a8 +#define PM3SStart 0x8388 +#define PM3StartXDom 0x8000 +#define PM3StartXSub 0x8010 +#define PM3StartY 0x8020 +/* ... */ +#define PM3SpanColorMask 0x8168 +/* ... */ +#define PM3TextureApplicationMode 0x8680 +#define PM3TextureApplicationModeAnd 0xac50 +#define PM3TextureApplicationModeOr 0xac58 +#define PM3TextureBaseAddr 0x8500 +#define PM3TextureCacheControl 0x8490 +#define PM3TextureChromaLower0 0x84f0 +#define PM3TextureChromaLower1 0x8608 +#define PM3TextureChromaUpper0 0x84e8 +#define PM3TextureChromaUpper1 0x8600 +#define PM3TextureCompositeAlphaMode0 0xb310 +#define PM3TextureCompositeAlphaMode0And 0xb390 +#define PM3TextureCompositeAlphaMode0Or 0xb398 +#define PM3TextureCompositeAlphaMode1 0xb320 +#define PM3TextureCompositeAlphaMode1And 0xb3b0 +#define PM3TextureCompositeAlphaMode1Or 0xb3b8 +#define PM3TextureCompositeColorMode0 0xb308 +#define PM3TextureCompositeColorMode0And 0xb380 +#define PM3TextureCompositeColorMode0Or 0xb388 +#define PM3TextureCompositeColorMode1 0xb318 +#define PM3TextureCompositeColorMode1And 0xb3a0 +#define PM3TextureCompositeColorMode1Or 0xb3a8 +#define PM3TextureCompositeFactor0 0xb328 +#define PM3TextureCompositeFactor1 0xb330 +#define PM3TextureCompositeMode 0xb300 +#define PM3TextureCoordMode 0x8380 +#define PM3TextureCoordModeAnd 0xac20 +#define PM3TextureCoordModeOr 0xac28 +#define PM3TextureData 0x88e8 +/* +#define PM3TextureDownloadControl 0x0108 +*/ +#define PM3TextureDownloadOffset 0x88f0 +#define PM3TextureEnvColor 0x8688 +#define PM3TextureFilterMode 0x84e0 +#define PM3TextureFilterModeAnd 0xad50 +#define PM3TextureFilterModeOr 0xad58 +#define PM3TextureIndexMode0 0xb338 +#define PM3TextureIndexMode0And 0xb3c0 +#define PM3TextureIndexMode0Or 0xb3c8 +#define PM3TextureIndexMode1 0xb340 +#define PM3TextureIndexMode1And 0xb3d0 +#define PM3TextureIndexMode1Or 0xb3d8 +#define PM3TextureLODBiasS 0x8450 +#define PM3TextureLODBiasT 0x8458 +/* ... */ +#define PM3TextureMapSize 0xb428 +#define PM3TextureMapWidth0 0x8580 +#define PM3TextureMapWidth1 0x8588 +# define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0) +# define PM3TextureMapWidth_BorderLayout (1<<12) +# define PM3TextureMapWidth_Layout_Linear (0<<13) +# define PM3TextureMapWidth_Layout_Patch64 (1<<13) +# define PM3TextureMapWidth_Layout_Patch32_2 (2<<13) +# define PM3TextureMapWidth_Layout_Patch2 (3<<13) +# define PM3TextureMapWidth_HostTexture (1<<15) +#define PM3TextureReadMode0 0xb400 +#define PM3TextureReadMode0And 0xac30 +#define PM3TextureReadMode0Or 0xac38 +#define PM3TextureReadMode1 0xb408 +#define PM3TextureReadMode1And 0xad40 +#define PM3TextureReadMode1Or 0xad48 +/* ... */ +#define PM3WaitForCompletion 0x80b8 +#define PM3Window 0x8980 +# define PM3Window_ForceLBUpdate 1<<3 +# define PM3Window_LBUpdateSource 1<<4 +# define PM3Window_FrameCount(c) (((c)&0xff)<<9 +# define PM3Window_StencilFCP 1<<17 +# define PM3Window_DepthFCP 1<<18 +# define PM3Window_OverrideWriteFiltering 1<<19 +#define PM3WindowAnd 0xab80 +#define PM3WindowOr 0xab88 +#define PM3WindowOrigin 0x81c8 +#define PM3XBias 0x9480 +#define PM3YBias 0x9488 +#define PM3YLimits 0x80a8 +#define PM3UVMode 0x8f00 +#define PM3ZFogBias 0x86b8 +#define PM3ZStart 0xadd8 +#define PM3ZStartL 0x89b8 +#define PM3ZStartU 0x89b0 + + +/********************************************** +* GLINT Permedia3 2D setup Unit * +***********************************************/ +#define PM3Config2D 0xb618 +# define PM3Config2D_OpaqueSpan 1<<0 +# define PM3Config2D_MultiRXBlit 1<<1 +# define PM3Config2D_UserScissorEnable 1<<2 +# define PM3Config2D_FBDestReadEnable 1<<3 +# define PM3Config2D_AlphaBlendEnable 1<<4 +# define PM3Config2D_DitherEnable 1<<5 +# define PM3Config2D_ForegroundROPEnable 1<<6 +# define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) +# define PM3Config2D_BackgroundROPEnable 1<<11 +# define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) +# define PM3Config2D_UseConstantSource 1<<16 +# define PM3Config2D_FBWriteEnable 1<<17 +# define PM3Config2D_Blocking 1<<18 +# define PM3Config2D_ExternalSourceData 1<<19 +# define PM3Config2D_LUTModeEnable 1<<20 +#define PM3DownloadGlyphwidth 0xb658 +# define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) +#define PM3DownloadTarget 0xb650 +# define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff) +#define PM3GlyphData 0xb660 +#define PM3GlyphPosition 0xb608 +# define PM3GlyphPosition_XOffset(x) ((x)&0xffff) +# define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16) +#define PM3Packed4Pixels 0xb668 +#define PM3Packed8Pixels 0xb630 +#define PM3Packed16Pixels 0xb638 +#define PM3RectanglePosition 0xb600 +# define PM3RectanglePosition_XOffset(x) ((x)&0xffff) +# define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) +#define PM3Render2D 0xb640 +# define PM3Render2D_Width(w) ((w)&0x0fff) +# define PM3Render2D_Operation_Normal 0<<12 +# define PM3Render2D_Operation_SyncOnHostData 1<<12 +# define PM3Render2D_Operation_SyncOnBitMask 2<<12 +# define PM3Render2D_Operation_PatchOrderRendering 3<<12 +# define PM3Render2D_FBSourceReadEnable 1<<14 +# define PM3Render2D_SpanOperation 1<<15 +# define PM3Render2D_Height(h) (((h)&0x0fff)<<16) +# define PM3Render2D_XPositive 1<<28 +# define PM3Render2D_YPositive 1<<29 +# define PM3Render2D_AreaStippleEnable 1<<30 +# define PM3Render2D_TextureEnable 1<<31 +#define PM3Render2DGlyph 0xb648 +# define PM3Render2DGlyph_Width(w) ((w)&0x7f) +# define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) +# define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14) +# define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23) +#define PM3RenderPatchOffset 0xb610 +# define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff) +# define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16) +#define PM3RLCount 0xb678 +# define PM3RLCount_Count(c) ((c)&0x0fff) +#define PM3RLData 0xb670 + +/********************************************** +* GLINT Permedia3 Alias Register * +***********************************************/ +#define PM3FillBackgroundColor 0x8330 +#define PM3FillConfig2D0 0x8338 +#define PM3FillConfig2D1 0x8360 +# define PM3FillConfig2D_OpaqueSpan 1<<0 +# define PM3FillConfig2D_MultiRXBlit 1<<1 +# define PM3FillConfig2D_UserScissorEnable 1<<2 +# define PM3FillConfig2D_FBDestReadEnable 1<<3 +# define PM3FillConfig2D_AlphaBlendEnable 1<<4 +# define PM3FillConfig2D_DitherEnable 1<<5 +# define PM3FillConfig2D_ForegroundROPEnable 1<<6 +# define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7) +# define PM3FillConfig2D_BackgroundROPEnable 1<<11 +# define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12) +# define PM3FillConfig2D_UseConstantSource 1<<16 +# define PM3FillConfig2D_FBWriteEnable 1<<17 +# define PM3FillConfig2D_Blocking 1<<18 +# define PM3FillConfig2D_ExternalSourceData 1<<19 +# define PM3FillConfig2D_LUTModeEnable 1<<20 +#define PM3FillFBDestReadBufferAddr 0x8310 +#define PM3FillFBSourceReadBufferAddr 0x8308 +#define PM3FillFBSourceReadBufferOffset 0x8340 +# define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +#define PM3FillFBWriteBufferAddr 0x8300 +#define PM3FillForegroundColor0 0x8328 +#define PM3FillForegroundColor1 0x8358 +#define PM3FillGlyphPosition 0x8368 +# define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff) +# define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16) +#define PM3FillRectanglePosition 0x8348 +# define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) +# define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) + +#if 0 + +/********************************************** +* GLINT Permedia3 Macros * +***********************************************/ + +#define WRITE_REG(base,offset,val) \ + *(volatile unsigned long *)(((unsigned char *)(base)) + offset) = (val) + +#define READ_REG(base,offset) \ + *(volatile unsigned long *)(((unsigned char *)(base)) + offset) + +#define UPDATE_SET_REG(base,offset,val) \ + { \ + unsigned long temp; \ + temp = READ_REG(base,offset); \ + WRITE_REG(base,offset,temp|(val)); \ + } + +#define UPDATE_CLEAR_REG(base,offset,val) \ + { \ + unsigned long temp; \ + temp = READ_REG(base,offset); \ + WRITE_REG(base,offset,temp&(~(val))); \ + } + +#define RAMDAC_DELAY(b,x) do { \ + int delay = x; \ + unsigned char tmp; \ + while(delay--){tmp = READ_REG(b,PM3InFIFOSpace);}; \ +} while(0) + +#define SLOW_WRITE_REG(b,v,r) \ +do{ \ + RAMDAC_DELAY(b,5); \ + WRITE_REG(b,v,r); \ + RAMDAC_DELAY(b,5); \ +}while(0) + +#define RAMDAC_SET_INDEX(b, index) \ +{ \ + SLOW_WRITE_REG (b,PM3RD_IndexHigh,(index>>8)&0xff); \ + SLOW_WRITE_REG (b,PM3RD_IndexLow,index&0xff); \ +} + +#define RAMDAC_SET_REG(b, index, data) \ +{ \ + RAMDAC_SET_INDEX(b, index); \ + SLOW_WRITE_REG(b, PM3RD_IndexedData, data); \ +} + +#define RAMDAC_GET_REG(b, index, temp) \ +{ \ + RAMDAC_SET_INDEX(b, index); \ + temp = READ_REG(b, PM3RD_IndexedData); \ +} +#endif +#endif /* _PM3_REG_H_ */ diff --git a/src/pm3_video.c b/src/pm3_video.c new file mode 100644 index 0000000..0a42417 --- /dev/null +++ b/src/pm3_video.c @@ -0,0 +1,1322 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Sven Luther <luther@dpt-info.u-strasbg.fr> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c,v 1.11.2.1 2003/05/09 02:10:18 dawes Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "glint.h" +#include "glint_regs.h" +#include "pm3_regs.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#ifndef XvExtension +void Permedia3InitVideo(ScreenPtr pScreen) {} +void Permedia3ResetVideo(ScrnInfoPtr pScrn) {} +#else + +static XF86VideoAdaptorPtr Permedia3SetupImageVideo(ScreenPtr); +static void Permedia3InitOffscreenImages(ScreenPtr); +static void Permedia3StopVideo(ScrnInfoPtr, pointer, Bool); +static int Permedia3SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int Permedia3GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static void Permedia3QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int Permedia3PutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int Permedia3QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static void Permedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvColorKey, xvDoubleBuffer, xvAutopaintColorKey, xvFilter; + +void Permedia3InitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + GLINTPtr pGlint = GLINTPTR(pScrn); + int num_adaptors; + + /* Because of bugs in the PM3 when uploading images via the + * bypass to the framebuffer, we always have to use the accelerator. + */ + if (pGlint->NoAccel) + return; + + newAdaptor = Permedia3SetupImageVideo(pScreen); + Permedia3InitOffscreenImages(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + 2047, 2047, + {1, 1} + } +}; + +#define NUM_FORMATS 4 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 4 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, + {XvSettable | XvGettable, 0, 2, "XV_FILTER"}, +}; + +/* + * FOURCC from http://www.webartz.com/fourcc + * Generic GUID for legacy FOURCC XXXXXXXX-0000-0010-8000-00AA00389B71 + */ +#define LE4CC(a,b,c,d) (((CARD32)(a)&0xFF)|(((CARD32)(b)&0xFF)<<8)|(((CARD32)(c)&0xFF)<<16)|(((CARD32)(d)&0xFF)<<24)) +#define GUID4CC(a,b,c,d) { a,b,c,d,0,0,0,0x10,0x80,0,0,0xAA,0,0x38,0x9B,0x71 } + +#define NoOrder LSBFirst + +#define NUM_IMAGES 15 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + /* Planar YVU 4:2:0 (emulated) */ + { LE4CC('Y','V','1','2'), XvYUV, NoOrder, GUID4CC('Y','V','1','2'), + 12, XvPlanar, 3, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU", XvTopToBottom }, + + /* Packed YUYV 4:2:2 */ + { LE4CC('Y','U','Y','2'), XvYUV, NoOrder, GUID4CC('Y','U','Y','2'), + 16, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV", XvTopToBottom }, + + /* Packed UYVY 4:2:2 */ + { LE4CC('U','Y','V','Y'), XvYUV, NoOrder, GUID4CC('U','Y','V','Y'), + 16, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY", XvTopToBottom }, + + /* Packed YUVA 4:4:4 */ + { LE4CC('Y','U','V','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, + 32, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUVA", XvTopToBottom }, + + /* Packed VUYA 4:4:4 */ + { LE4CC('V','U','Y','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, + 32, XvPacked, 1, 0, 0, 0, 0, + 8, 8, 8, 1, 1, 1, 1, 1, 1, "VUYA", XvTopToBottom }, + + /* RGBA 8:8:8:8 */ + { 0x41, XvRGB, LSBFirst, { 0 }, + 32, XvPacked, 1, 24, 0x0000FF, 0x00FF00, 0xFF0000, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGB 5:6:5 */ + { 0x42, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 16, 0x001F, 0x07E0, 0xF800, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, + + /* RGBA 5:5:5:1 */ + { 0x43, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 15, 0x001F, 0x03E0, 0x7C00, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGBA 4:4:4:4 */ + { 0x44, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 12, 0x000F, 0x00F0, 0x0F00, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, + + /* RGB 3:3:2 */ + { 0x46, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 8, 0x07, 0x38, 0xC0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, + + /* BGRA 8:8:8:8 */ + { 0x47, XvRGB, LSBFirst, { 0 }, + 32, XvPacked, 1, 24, 0xFF0000, 0x00FF00, 0x0000FF, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGR 5:6:5 */ + { 0x48, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, + + /* BGRA 5:5:5:1 */ + { 0x49, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 15, 0x7C00, 0x03E0, 0x001F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGRA 4:4:4:4 */ + { 0x4A, XvRGB, LSBFirst, { 0 }, + 16, XvPacked, 1, 12, 0x0F00, 0x00F0, 0x000F, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, + + /* BGR 2:3:3 */ + { 0x4C, XvRGB, NoOrder, { 0 }, + 8, XvPacked, 1, 8, 0xC0, 0x38, 0x07, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, +}; + +#define MAX_BUFFERS 2 + +typedef struct { + FBAreaPtr area[MAX_BUFFERS]; + RegionRec clip; + CARD32 colorKey; + CARD32 videoStatus; + Time offTime; + Time freeTime; + int Video_Shift; + int Format; + Bool ramdacOn; + Bool doubleBuffer; + Bool autopaintColorKey; + int Filter; + int sx, sy; + int offset[MAX_BUFFERS]; + int buffer; +} GLINTPortPrivRec, *GLINTPortPrivPtr; + +#define GET_PORT_PRIVATE(pScrn) \ + (GLINTPortPrivPtr)((GLINTPTR(pScrn))->adaptor->pPortPrivates[0].ptr) + +#define RAMDAC_WRITE(data,index) \ +do{ \ + GLINT_WRITE_REG(((index)>>8)&0xff, PM3RD_IndexHigh); \ + GLINT_WRITE_REG((index)&0xff, PM3RD_IndexLow); \ + GLINT_WRITE_REG(data, PM3RD_IndexedData); \ +}while(0) + +void Permedia3ResetVideo(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + + GLINT_WAIT(15); + GLINT_WRITE_REG(0xfff0|(0xffff<<16), PM3VideoOverlayFifoControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, PM3VideoOverlayMode); + pPriv->ramdacOn = FALSE; + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, PM3RD_VideoOverlayControl); + RAMDAC_WRITE((pPriv->colorKey&0xff0000)>>16, PM3RD_VideoOverlayKeyR); + RAMDAC_WRITE((pPriv->colorKey&0x00ff00)>>8, PM3RD_VideoOverlayKeyG); + RAMDAC_WRITE(pPriv->colorKey&0x0000ff, PM3RD_VideoOverlayKeyB); + GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, PM3VideoOverlayUpdate); +} + + +static XF86VideoAdaptorPtr +Permedia3SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + XF86VideoAdaptorPtr adapt; + GLINTPortPrivPtr pPriv; + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GLINTPortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "Permedia3 Backend Scaler"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + pPriv = (GLINTPortPrivPtr)(&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = Permedia3StopVideo; + adapt->SetPortAttribute = Permedia3SetPortAttribute; + adapt->GetPortAttribute = Permedia3GetPortAttribute; + adapt->QueryBestSize = Permedia3QueryBestSize; + adapt->PutImage = Permedia3PutImage; + adapt->QueryImageAttributes = Permedia3QueryImageAttributes; + + /* FIXME : depth 15 and 16 doesn't work here */ + pPriv->colorKey = pGlint->videoKey; + pPriv->videoStatus = 0; + pPriv->buffer = 0; /* double buffer (or maybe triple later) */ + pPriv->doubleBuffer = TRUE; + pPriv->autopaintColorKey = TRUE; + pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + pGlint->adaptor = adapt; + + xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + xvFilter = MAKE_ATOM("XV_FILTER"); + + Permedia3ResetVideo(pScrn); + + return adapt; +} + + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static void +Permedia3StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + int i; + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if(shutdown) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + } + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if(pPriv->area[i]) { + xf86FreeOffscreenArea(pPriv->area[i]); + pPriv->area[i] = NULL; + } + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } +} + +static int +Permedia3SetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +){ + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (attribute == xvDoubleBuffer) + { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->doubleBuffer = value; + } + else if (attribute == xvColorKey) + { + pPriv->colorKey = value; + GLINT_WAIT(9); + RAMDAC_WRITE((value & 0xff0000)>>16, PM3RD_VideoOverlayKeyR); + RAMDAC_WRITE((value & 0x00ff00)>>8, PM3RD_VideoOverlayKeyG); + RAMDAC_WRITE((value & 0x0000ff), PM3RD_VideoOverlayKeyB); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } + else if (attribute == xvAutopaintColorKey) + { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->autopaintColorKey = value; + } + else if (attribute == xvFilter) + { + if ((value < 0) || (value > 2)) + return BadValue; + switch (value) { + case 0: + pPriv->Filter = PM3VideoOverlayMode_FILTER_OFF; + break; + case 1: + pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; + break; + case 2: + pPriv->Filter = PM3VideoOverlayMode_FILTER_PARTIAL; + break; + } + } + else + return BadMatch; + + return Success; +} + +static int +Permedia3GetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +){ + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + + if (attribute == xvDoubleBuffer) + *value = (pPriv->doubleBuffer) ? 1 : 0; + else if (attribute == xvColorKey) + *value = pPriv->colorKey; + else if (attribute == xvAutopaintColorKey) + *value = (pPriv->autopaintColorKey) ? 1 : 0; + else if (attribute == xvFilter) + *value = pPriv->Filter >> 14; + else + return BadMatch; + + return Success; +} + +static void +Permedia3QueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + if(vid_w > (drw_w << 3)) + drw_w = vid_w >> 3; + if(vid_h > (drw_h << 3)) + drw_h = vid_h >> 3; + + *p_w = drw_w; + *p_h = drw_h; +} + +static void +HWCopySetup(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(4); + GLINT_WRITE_REG(0xffffffff, FBHardwareWriteMask); + GLINT_WRITE_REG( + PM3Config2D_ForegroundROPEnable | + PM3Config2D_ForegroundROP(GXcopy) | + PM3Config2D_FBWriteEnable, + PM3Config2D); + GLINT_WRITE_REG( + PM3RectanglePosition_XOffset(x) | + PM3RectanglePosition_YOffset(y), + PM3RectanglePosition); + GLINT_WRITE_REG( + PM3Render2D_SpanOperation | + PM3Render2D_XPositive | + PM3Render2D_YPositive | + PM3Render2D_Operation_SyncOnHostData | + PM3Render2D_Width(w) | PM3Render2D_Height(h), + PM3Render2D); +} + +static void +HWCopyYV12(ScrnInfoPtr pScrn, CARD8 *Y, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int size = w * h; + CARD8 *V = Y + size; + CARD8 *U = V + (size >> 2); + CARD32 *dst; + int pass2 = 0; + int dwords, i, x = 0; + + dwords = size >> 1; + + w >>= 1; + + while (dwords >= pGlint->FIFOSize) { + dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + for (i = pGlint->FIFOSize - 1; i; i--, Y += 2, x++) { + if (x == w) { + x = 0; + if (pass2 == 0) + pass2 = 1; + else + if (pass2 == 1) { + pass2 = 0; + U += w; + V += w; + } + } + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); + } + dwords -= pGlint->FIFOSize - 1; + } + if (dwords) { + dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + GLINT_WAIT(dwords + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + for (i = dwords; i; i--, Y += 2, x++) { + if (x == w) { + x = 0; + if (pass2 == 0) + pass2 = 1; + else + if (pass2 == 1) { + pass2 = 0; + U += w; + V += w; + } + } + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); + } + } +} + +static void +HWCopyFlat(ScrnInfoPtr pScrn, CARD8 *src, int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + int pitch = pScrn->displayWidth; + CARD8 *tmp_src; + int dwords; + + if (w == pitch) { + dwords = (w * h) >> (2 - pPriv->Video_Shift); + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, pGlint->FIFOSize - 1); + dwords -= (pGlint->FIFOSize - 1); + src += (pGlint->FIFOSize << 2) - 4; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16)|(0x15 << 4) |0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, dwords); + } + } else { + while (h--) { + tmp_src = src; + dwords = w >> (2 - pPriv->Video_Shift); + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, pGlint->FIFOSize - 1); + dwords -= (pGlint->FIFOSize - 1); + src += (pGlint->FIFOSize << 2) - 4; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords-1)<<16)|(0x15<<4) | 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, dwords); + } + src = tmp_src + (w << pPriv->Video_Shift); + } + } +} + +static FBAreaPtr +Permedia3AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int width, int height) +{ + ScreenPtr pScreen; + FBAreaPtr new_area; + + if (area) { + if ((area->box.x2 - area->box.x1 >= width) && + (area->box.y2 - area->box.y1 >= height)) + return area; + + if (xf86ResizeOffscreenArea(area, width, height)) + return area; + + xf86FreeOffscreenArea(area); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); + + if (!new_area) { + int max_width, max_height; + + xf86QueryLargestOffscreenArea(pScreen, &max_width, &max_height, pScrn->bitsPerPixel / 8, 0, PRIORITY_EXTREME); + + if (max_width < width || max_height < height) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); + } + + return new_area; +} + +#define FORMAT_RGB8888 PM3VideoOverlayMode_COLORFORMAT_RGB8888 +#define FORMAT_RGB4444 PM3VideoOverlayMode_COLORFORMAT_RGB4444 +#define FORMAT_RGB5551 PM3VideoOverlayMode_COLORFORMAT_RGB5551 +#define FORMAT_RGB565 PM3VideoOverlayMode_COLORFORMAT_RGB565 +#define FORMAT_RGB332 PM3VideoOverlayMode_COLORFORMAT_RGB332 +#define FORMAT_BGR8888 PM3VideoOverlayMode_COLORFORMAT_BGR8888 +#define FORMAT_BGR4444 PM3VideoOverlayMode_COLORFORMAT_BGR4444 +#define FORMAT_BGR5551 PM3VideoOverlayMode_COLORFORMAT_BGR5551 +#define FORMAT_BGR565 PM3VideoOverlayMode_COLORFORMAT_BGR565 +#define FORMAT_BGR332 PM3VideoOverlayMode_COLORFORMAT_BGR332 +#define FORMAT_CI8 PM3VideoOverlayMode_COLORFORMAT_CI8 +#define FORMAT_VUY444 PM3VideoOverlayMode_COLORFORMAT_VUY444 +#define FORMAT_YUV444 PM3VideoOverlayMode_COLORFORMAT_YUV444 +#define FORMAT_VUY422 PM3VideoOverlayMode_COLORFORMAT_VUY422 +#define FORMAT_YUV422 PM3VideoOverlayMode_COLORFORMAT_YUV422 + +/* Notice, have to check that we dont overflow the deltas here ... */ +static void +compute_scale_factor( + short* src_w, short* dst_w, + unsigned int* shrink_delta, unsigned int* zoom_delta) +{ + /* NOTE: If we don't return reasonable values here then the video + * unit can potential shut off and won't display an image until re-enabled. + * Seems as though the zoom_delta is o.k, and I've not had the problem. + * The 'shrink_delta' is prone to this the most - FIXME ! */ + + if (*src_w >= *dst_w) { + *src_w &= ~0x3; + *dst_w &= ~0x3; + *shrink_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0ffffff0; + *zoom_delta = 1<<16; + if ( ((*shrink_delta * *dst_w) >> 16) & 0x03 ) + *shrink_delta += 0x10; + } else { + *src_w &= ~0x3; + *dst_w &= ~0x3; + *zoom_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0001fff0; + *shrink_delta = 1<<16; + if ( ((*zoom_delta * *dst_w) >> 16) & 0x03 ) + *zoom_delta += 0x10; + } +} + +static void +Permedia3DisplayVideo( + ScrnInfoPtr pScrn, + int id, + int offset, + short width, short height, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, + short drw_w, short drw_h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; + unsigned int shrink, zoom; + unsigned int newx1, newx2; + + /* Let's overlay only to visible parts of the screen */ + if (dstBox->x1 == 0) { + x1 = drw_w - dstBox->x2; + drw_w = dstBox->x2; + } + if (dstBox->x2 == pScrn->frameX1) { + x2 = drw_w - (dstBox->x2 - dstBox->x1); + drw_w = (dstBox->x2 - dstBox->x1); + } + + /* Avoid divide by zero in compute_scale_factor. */ + if (drw_w < 8) + return; + + /* Let's adjust the width of source and dest to be compliant with + * the Permedia3 overlay unit requirement, and compute the X deltas. */ + newx1 = src_w; newx2 = drw_w; + compute_scale_factor(&src_w, &drw_w, &shrink, &zoom); + dstBox->x2 -= (newx2 - drw_w); + + /* We do a long wait here - for everything that needs to be written */ + GLINT_WAIT(39); + GLINT_WRITE_REG(offset>>portPriv->Video_Shift, + portPriv->buffer ? PM3VideoOverlayBase1 : PM3VideoOverlayBase0); + /* Let's set the source pitch. */ + GLINT_WRITE_REG(PM3VideoOverlayStride_STRIDE(pScrn->displayWidth<< + (pScrn->bitsPerPixel>>4) >>portPriv->Video_Shift), + PM3VideoOverlayStride); + /* Let's set the position and size of the visible part of the source. */ + GLINT_WRITE_REG(PM3VideoOverlayWidth_WIDTH(src_w), + PM3VideoOverlayWidth); + GLINT_WRITE_REG(PM3VideoOverlayHeight_HEIGHT(src_h), + PM3VideoOverlayHeight); + GLINT_WRITE_REG( + PM3VideoOverlayOrigin_XORIGIN(x1) | + PM3VideoOverlayOrigin_YORIGIN(y1), + PM3VideoOverlayOrigin); + /* Scale the source to the destinationsize */ + if (src_h == drw_h) { + GLINT_WRITE_REG( + PM3VideoOverlayYDelta_NONE, + PM3VideoOverlayYDelta); + } else { + GLINT_WRITE_REG( + PM3VideoOverlayYDelta_DELTA(src_h,drw_h), + PM3VideoOverlayYDelta); + } + if (src_w == drw_w) { + GLINT_WRITE_REG(1<<16, PM3VideoOverlayShrinkXDelta); + GLINT_WRITE_REG(1<<16, PM3VideoOverlayZoomXDelta); + } else { + GLINT_WRITE_REG(shrink, PM3VideoOverlayShrinkXDelta); + GLINT_WRITE_REG(zoom, PM3VideoOverlayZoomXDelta); + } + GLINT_WRITE_REG(portPriv->buffer, PM3VideoOverlayIndex); + + /* Now set the ramdac video overlay region and mode */ + RAMDAC_WRITE((dstBox->x1&0xff), PM3RD_VideoOverlayXStartLow); + RAMDAC_WRITE((dstBox->x1&0xf00)>>8, PM3RD_VideoOverlayXStartHigh); + RAMDAC_WRITE((dstBox->x2&0xff), PM3RD_VideoOverlayXEndLow); + RAMDAC_WRITE((dstBox->x2&0xf00)>>8,PM3RD_VideoOverlayXEndHigh); + RAMDAC_WRITE((dstBox->y1&0xff), PM3RD_VideoOverlayYStartLow); + RAMDAC_WRITE((dstBox->y1&0xf00)>>8, PM3RD_VideoOverlayYStartHigh); + RAMDAC_WRITE((dstBox->y2&0xff), PM3RD_VideoOverlayYEndLow); + RAMDAC_WRITE((dstBox->y2&0xf00)>>8,PM3RD_VideoOverlayYEndHigh); + + GLINT_WRITE_REG(portPriv->Video_Shift << 5 | + portPriv->Format | + portPriv->Filter | + PM3VideoOverlayMode_BUFFERSYNC_MANUAL | + PM3VideoOverlayMode_FLIP_VIDEO | + PM3VideoOverlayMode_ENABLE, + PM3VideoOverlayMode); + + if (!portPriv->ramdacOn) { + RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | + PM3RD_VideoOverlayControl_KEY_COLOR | + PM3RD_VideoOverlayControl_MODE_MAINKEY | + PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED, + PM3RD_VideoOverlayControl); + portPriv->ramdacOn = TRUE; + } + GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, + PM3VideoOverlayUpdate); +} + +static int +Permedia3PutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data +){ +#if 0 + GLINTPtr pGlint = GLINTPTR(pScrn); +#endif + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + INT32 x1, x2, y1, y2; + int pitch; + int i; + int w_bpp, bpp; + Bool copy_flat = TRUE; + BoxRec dstBox; + + /* Let's find the image format and Video_Shift values */ + switch (id) { + case LE4CC('Y','V','1','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + copy_flat = FALSE; + break; + case LE4CC('Y','U','Y','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + break; + case LE4CC('U','Y','V','Y'): + pPriv->Format = FORMAT_VUY422; + pPriv->Video_Shift = 1; + break; + case LE4CC('Y','U','V','A'): + pPriv->Format = FORMAT_YUV444; + pPriv->Video_Shift = 2; + break; + case LE4CC('V','U','Y','A'): + pPriv->Format = FORMAT_VUY444; + pPriv->Video_Shift = 2; + break; + case 0x41: /* RGBA 8:8:8:8 */ + pPriv->Format = FORMAT_RGB8888; + pPriv->Video_Shift = 2; + break; + case 0x42: /* RGB 5:6:5 */ + pPriv->Format = FORMAT_RGB565; + pPriv->Video_Shift = 1; + break; + case 0x43: /* RGB 1:5:5:5 */ + pPriv->Format = FORMAT_RGB5551; + pPriv->Video_Shift = 1; + break; + case 0x44: /* RGB 4:4:4:4 */ + pPriv->Format = FORMAT_RGB4444; + pPriv->Video_Shift = 1; + break; + case 0x46: /* RGB 2:3:3 */ + pPriv->Format = FORMAT_RGB332; + pPriv->Video_Shift = 0; + break; + case 0x47: /* BGRA 8:8:8:8 */ + pPriv->Format = FORMAT_BGR8888; + pPriv->Video_Shift = 2; + break; + case 0x48: /* BGR 5:6:5 */ + pPriv->Format = FORMAT_BGR565; + pPriv->Video_Shift = 1; + break; + case 0x49: /* BGR 1:5:5:5 */ + pPriv->Format = FORMAT_BGR5551; + pPriv->Video_Shift = 1; + break; + case 0x4A: /* BGR 4:4:4:4 */ + pPriv->Format = FORMAT_BGR4444; + pPriv->Video_Shift = 1; + break; + case 0x4C: /* BGR 2:3:3 */ + pPriv->Format = FORMAT_BGR332; + pPriv->Video_Shift = 0; + break; + default: + return XvBadAlloc; + } + + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + width, height)) + return Success; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + bpp = pScrn->bitsPerPixel >> 3; + pitch = bpp * pScrn->displayWidth; + + w_bpp = (width << pPriv->Video_Shift) >> (pScrn->bitsPerPixel >> 4); + + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if (!(pPriv->area[i] = + Permedia3AllocateMemory(pScrn,pPriv->area[i],w_bpp,src_h))) + return BadAlloc; + + pPriv->offset[i] = (pPriv->area[i]->box.x1 * bpp) + + (pPriv->area[i]->box.y1 * pitch); + } + + HWCopySetup(pScrn, pPriv->area[pPriv->buffer]->box.x1, + pPriv->area[pPriv->buffer]->box.y1, w_bpp, height); + + if (copy_flat) + HWCopyFlat(pScrn, buf, width, height); + else + HWCopyYV12(pScrn, buf, width, height); + + /* paint the color key */ + if(pPriv->autopaintColorKey && !RegionsEqual(&pPriv->clip, clipBoxes)) { + /* update cliplist */ + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); +#if 0 + GLINT_WAIT(1); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->ramdacOn = FALSE; +#endif + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + + Permedia3Sync(pScrn); + + Permedia3DisplayVideo(pScrn, id, pPriv->offset[pPriv->buffer], width,height, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + /* Switch buffer on next run - double buffer */ + if (pPriv->doubleBuffer) { + if (!pPriv->buffer) + pPriv->buffer = 1; + else + pPriv->buffer = 0; + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + return Success; +} + +static int +Permedia3QueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + int size, tmp; + + if(*w > 2047) *w = 2047; + if(*h > 2047) *h = 2047; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: /* YV12 */ + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + default: /* RGB15, RGB16, YUY2 */ + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} + +/****************** Offscreen stuff ***************/ + +typedef struct { + FBAreaPtr area; + Bool isOn; + int Video_Shift; + int Format; + Bool ramdacOn; +} OffscreenPrivRec, * OffscreenPrivPtr; + +static int +Permedia3AllocateSurface( + ScrnInfoPtr pScrn, + int id, + unsigned short w, + unsigned short h, + XF86SurfacePtr surface +){ + FBAreaPtr area; + int fbpitch, bpp; + OffscreenPrivPtr pPriv; + + if((w > 2047) || (h > 2047)) + return BadAlloc; + + w = (w + 1) & ~1; + bpp = pScrn->bitsPerPixel >> 3; + fbpitch = bpp * pScrn->displayWidth; + + if(!(area = Permedia3AllocateMemory(pScrn, NULL, w, h))) + return BadAlloc; + + surface->width = w; + surface->height = h; + + if(!(surface->offsets = xalloc(sizeof(int)))) { + xf86FreeOffscreenArea(area); + return BadAlloc; + } + if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { + xfree(surface->offsets); + xf86FreeOffscreenArea(area); + return BadAlloc; + } + + pPriv->area = area; + pPriv->isOn = FALSE; + + surface->pScrn = pScrn; + surface->id = id; + surface->offsets[0] = (area->box.x1 * bpp) + (area->box.y1 * fbpitch); + surface->devPrivate.ptr = (pointer)pPriv; + + return Success; +} + +static int +Permedia3StopSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + + if(pPriv->isOn) { + GLINTPtr pGlint = GLINTPTR(surface->pScrn); + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->isOn = FALSE; + } + + return Success; +} + +static int +Permedia3FreeSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + + if(pPriv->isOn) + Permedia3StopSurface(surface); + xf86FreeOffscreenArea(pPriv->area); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; +} + +static int +Permedia3GetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value +){ + return Permedia3GetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); +} + +static int +Permedia3SetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value +){ + return Permedia3SetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); +} + +static int +Permedia3DisplaySurface( + XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + ScrnInfoPtr pScrn = surface->pScrn; + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; + INT32 x1, y1, x2, y2; + BoxRec dstBox; + + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + surface->width, surface->height)) + { + return Success; + } + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + /* Let's find the image format and Video_Shift values */ + switch (surface->id) { + case LE4CC('Y','V','1','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + break; + case LE4CC('Y','U','Y','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + break; + case LE4CC('U','Y','V','Y'): + pPriv->Format = FORMAT_VUY422; + pPriv->Video_Shift = 1; + break; + case LE4CC('Y','U','V','A'): + pPriv->Format = FORMAT_YUV444; + pPriv->Video_Shift = 2; + break; + case LE4CC('V','U','Y','A'): + pPriv->Format = FORMAT_VUY444; + pPriv->Video_Shift = 2; + break; + case 0x41: /* RGBA 8:8:8:8 */ + pPriv->Format = FORMAT_RGB8888; + pPriv->Video_Shift = 2; + break; + case 0x42: /* RGB 5:6:5 */ + pPriv->Format = FORMAT_RGB565; + pPriv->Video_Shift = 1; + break; + case 0x43: /* RGB 1:5:5:5 */ + pPriv->Format = FORMAT_RGB5551; + pPriv->Video_Shift = 1; + break; + case 0x44: /* RGB 4:4:4:4 */ + pPriv->Format = FORMAT_RGB4444; + pPriv->Video_Shift = 1; + break; + case 0x46: /* RGB 2:3:3 */ + pPriv->Format = FORMAT_RGB332; + pPriv->Video_Shift = 0; + break; + case 0x47: /* BGRA 8:8:8:8 */ + pPriv->Format = FORMAT_BGR8888; + pPriv->Video_Shift = 2; + break; + case 0x48: /* BGR 5:6:5 */ + pPriv->Format = FORMAT_BGR565; + pPriv->Video_Shift = 1; + break; + case 0x49: /* BGR 1:5:5:5 */ + pPriv->Format = FORMAT_BGR5551; + pPriv->Video_Shift = 1; + break; + case 0x4A: /* BGR 4:4:4:4 */ + pPriv->Format = FORMAT_BGR4444; + pPriv->Video_Shift = 1; + break; + case 0x4C: /* BGR 2:3:3 */ + pPriv->Format = FORMAT_BGR332; + pPriv->Video_Shift = 0; + break; + default: + return XvBadAlloc; + } + + Permedia3DisplayVideo(pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); + + pPriv->isOn = TRUE; + /* we've prempted the XvImage stream so set its free timer */ + if(portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pGlint->VideoTimerCallback = Permedia3VideoTimerCallback; + } + + return Success; +} + +static void +Permedia3InitOffscreenImages(ScreenPtr pScreen) +{ + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | + VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = Permedia3AllocateSurface; + offscreenImages[0].free_surface = Permedia3FreeSurface; + offscreenImages[0].display = Permedia3DisplaySurface; + offscreenImages[0].stop = Permedia3StopSurface; + offscreenImages[0].setAttribute = Permedia3SetSurfaceAttribute; + offscreenImages[0].getAttribute = Permedia3GetSurfaceAttribute; + offscreenImages[0].max_width = 2047; + offscreenImages[0].max_height = 2047; + offscreenImages[0].num_attributes = NUM_ATTRIBUTES; + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); +} + +static void +Permedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + int i; + + if(pPriv->videoStatus & TIMER_MASK) { + if(pPriv->videoStatus & OFF_TIMER) { + if(pPriv->offTime < time) { + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = time + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if(pPriv->freeTime < time) { + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if(pPriv->area[i]) { + xf86FreeOffscreenArea(pPriv->area[i]); + pPriv->area[i] = NULL; + } + } + pPriv->videoStatus = 0; + pGlint->VideoTimerCallback = NULL; + } + } + } else /* shouldn't get here */ + pGlint->VideoTimerCallback = NULL; +} + +#endif /* !XvExtension */ diff --git a/src/pm_accel.c b/src/pm_accel.c new file mode 100644 index 0000000..f999006 --- /dev/null +++ b/src/pm_accel.c @@ -0,0 +1,1199 @@ +/* + * Copyright 1997-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + * + * Permedia accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c,v 1.23 2001/05/29 11:23:38 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "fb.h" + +#include "glint_regs.h" +#include "glint.h" + +#include "miline.h" /* for octants */ +#include "xaalocal.h" /* For replacements */ + +static void PermediaSync(ScrnInfoPtr pScrn); +static void PermediaSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void PermediaSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y, + int len, int dir); +static void PermediaSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void PermediaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, + int y1, int x2, int y2, int w, int h); +static void PermediaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, + int ydir, int rop, unsigned int planemask, + int transparency_color); +static void PermediaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2); +static void PermediaDisableClipping(ScrnInfoPtr pScrn); +static void PermediaSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void PermediaSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +static void PermediaWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int skipleft, + int fg, int bg, int rop,unsigned int planemask); +static void PermediaWritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void PermediaWritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void PermediaWritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w, + int h, unsigned char *src, int srcwidth, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +static void PermediaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned planemask); +static void PermediaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); +static void PermediaLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h, + int a, int d); +static void PermediaPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts); +static void PermediaPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int nseg, xSegment *pSeg); + +void +PermediaInitializeEngine(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* Initialize the Accelerator Engine to defaults */ + + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); + GLINT_SLOW_WRITE_REG(0, dXSub); + GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); + GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(0x400, FilterMode); + GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase); + + switch (pScrn->bitsPerPixel) { + case 8: + GLINT_SLOW_WRITE_REG(0x0, FBReadPixel); /* 8 Bits */ + GLINT_SLOW_WRITE_REG(pGlint->pprod, PMTextureMapFormat); + break; + case 16: + GLINT_SLOW_WRITE_REG(0x1, FBReadPixel); /* 16 Bits */ + GLINT_SLOW_WRITE_REG(pGlint->pprod | 1<<19, PMTextureMapFormat); + break; + case 32: + GLINT_SLOW_WRITE_REG(0x2, FBReadPixel); /* 32 Bits */ + GLINT_SLOW_WRITE_REG(pGlint->pprod | 2<<19, PMTextureMapFormat); + break; + } + pGlint->ROP = 0xFF; + pGlint->ClippingOn = FALSE; + pGlint->startxsub = 0; + pGlint->startxdom = 0; + pGlint->starty = 0; + pGlint->count = 0; + pGlint->dxdom = 0; + pGlint->dy = 1<<16; + GLINT_WAIT(6); + GLINT_WRITE_REG(0, StartXSub); + GLINT_WRITE_REG(0,StartXDom); + GLINT_WRITE_REG(0,StartY); + GLINT_WRITE_REG(0,GLINTCount); + GLINT_WRITE_REG(0,dXDom); + GLINT_WRITE_REG(1<<16,dY); +} + +Bool +PermediaAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + BoxRec AvailFBArea; + + pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + PermediaInitializeEngine(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + infoPtr->Sync = PermediaSync; + + infoPtr->SetClippingRectangle = PermediaSetClippingRectangle; + infoPtr->DisableClipping = PermediaDisableClipping; + infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL; + + infoPtr->SolidFillFlags = 0; + infoPtr->SetupForSolidFill = PermediaSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = PermediaSubsequentFillRectSolid; + infoPtr->SolidLineFlags = 0; + infoPtr->PolySegmentThinSolidFlags = 0; + infoPtr->PolylinesThinSolidFlags = 0; + infoPtr->SetupForSolidLine = PermediaSetupForSolidLine; + infoPtr->SubsequentSolidHorVertLine = PermediaSubsequentHorVertLine; + if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)) + { + infoPtr->SubsequentSolidBresenhamLine = + PermediaSubsequentSolidBresenhamLine; + } + infoPtr->PolySegmentThinSolid = PermediaPolySegmentThinSolidWrapper; + infoPtr->PolylinesThinSolid = PermediaPolylinesThinSolidWrapper; + + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + + infoPtr->SetupForScreenToScreenCopy = PermediaSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = PermediaSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_SCREEN_ORIGIN; + + infoPtr->SetupForMono8x8PatternFill = + PermediaSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + PermediaSubsequentMono8x8PatternFillRect; + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = +#if 0 + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X | +#endif + BIT_ORDER_IN_BYTE_LSBFIRST; + + infoPtr->NumScanlineColorExpandBuffers = 1; + pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4) + + (pScrn->virtualX + * pScrn->bitsPerPixel / 8)); + infoPtr->ScanlineColorExpandBuffers = + pGlint->XAAScanlineColorExpandBuffers; + pGlint->XAAScanlineColorExpandBuffers[0] = + pGlint->IOBase + OutputFIFO + 4; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + PermediaSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + PermediaSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + PermediaSubsequentColorExpandScanline; + + infoPtr->ColorExpandRange = pGlint->FIFOSize; + + infoPtr->WriteBitmap = PermediaWriteBitmap; + + if (pScrn->bitsPerPixel == 8) + infoPtr->WritePixmap = PermediaWritePixmap8bpp; + else + if (pScrn->bitsPerPixel == 16) + infoPtr->WritePixmap = PermediaWritePixmap16bpp; + else + if (pScrn->bitsPerPixel == 32) + infoPtr->WritePixmap = PermediaWritePixmap32bpp; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + if (AvailFBArea.y2 > 1023) AvailFBArea.y2 = 1023; + + xf86InitFBManager(pScreen, &AvailFBArea); + + return (XAAInit(pScreen, infoPtr)); +} + +static void PermediaLoadCoord( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int a, int d +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (w != pGlint->startxsub) { + GLINT_WRITE_REG(w, StartXSub); + pGlint->startxsub = w; + } + if (x != pGlint->startxdom) { + GLINT_WRITE_REG(x,StartXDom); + pGlint->startxdom = x; + } + if (y != pGlint->starty) { + GLINT_WRITE_REG(y,StartY); + pGlint->starty = y; + } + if (h != pGlint->count) { + GLINT_WRITE_REG(h,GLINTCount); + pGlint->count = h; + } + if (a != pGlint->dxdom) { + GLINT_WRITE_REG(a,dXDom); + pGlint->dxdom = a; + } + if (d != pGlint->dy) { + GLINT_WRITE_REG(d,dY); + pGlint->dy = d; + } +} + +static void +PermediaSync(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(2); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); +} + +static void +PermediaSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2 +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WAIT(3); + GLINT_WRITE_REG (((y1&0x0FFF) << 16) | (x1&0x0FFF), ScissorMinXY); + GLINT_WRITE_REG (((y2&0x0FFF) << 16) | (x2&0x0FFF), ScissorMaxXY); + GLINT_WRITE_REG (1, ScissorMode); + pGlint->ClippingOn = TRUE; +} + +static void +PermediaDisableClipping( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + CHECKCLIPPING; +} + +static void +PermediaSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->BltScanDirection = 0; + if (ydir == 1) pGlint->BltScanDirection |= YPositive; + + GLINT_WAIT(4); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + + if ((rop == GXset) || (rop == GXclear)) { + pGlint->FrameBufferReadMode = pGlint->pprod; + } else + if ((rop == GXcopy) || (rop == GXcopyInverted)) { + pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable; + } else { + pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable | + FBRM_DstEnable; + } + LOADROP(rop); +} + +static void +PermediaSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int srcaddr; + int dstaddr; + char align; + int direction; + + if (!(pGlint->BltScanDirection & YPositive)) { + y1 = y1 + h - 1; + y2 = y2 + h - 1; + direction = -1<<16; + } else { + direction = 1<<16; + } + + /* We can only use GXcopy for Packed modes, and less than 32 width + * gives us speed for small blits. */ + if ((w < 32) || (pGlint->ROP != GXcopy)) { + GLINT_WAIT(9); + PermediaLoadCoord(pScrn, x2<<16, y2<<16, (x2+w)<<16, h, 0, direction); + srcaddr = x1; + dstaddr = x2; + GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode); + } else { + GLINT_WAIT(10); + PermediaLoadCoord(pScrn, (x2>>pGlint->BppShift)<<16, y2<<16, + ((x2+w+7)>>pGlint->BppShift)<<16, h, 0, + direction); + srcaddr = (x1 & ~pGlint->bppalign); + dstaddr = (x2 & ~pGlint->bppalign); + align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign); + GLINT_WRITE_REG(pGlint->FrameBufferReadMode | FBRM_Packed | + (align&7)<<20, FBReadMode); + GLINT_WRITE_REG(x2<<16|(x2+w), PackedDataLimits); + } + srcaddr += y1 * pScrn->displayWidth; + dstaddr += y2 * pScrn->displayWidth; + GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset); + GLINT_WRITE_REG(PrimitiveTrapezoid, Render); +} + +static void +PermediaSetupForFillRectSolid( + ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + REPLICATE(color); + + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(color, FBBlockColor); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(color, ConstantColor); + } + LOADROP(rop); +} + +static void +PermediaSubsequentFillRectSolid( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int speed = 0; + if (pGlint->ROP == GXcopy) { + GLINT_WAIT(7); + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + speed = FastFillEnable; + } else { + GLINT_WAIT(9); + GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed | FBRM_DstEnable, FBReadMode); + PermediaLoadCoord(pScrn, (x>>pGlint->BppShift)<<16, y<<16, + ((x+w+7)>>pGlint->BppShift)<<16, h, 0, 1<<16); + GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits); + } + GLINT_WRITE_REG(PrimitiveTrapezoid | speed, Render); +} + +static void +PermediaSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + if (bg == -1) pGlint->FrameBufferReadMode = -1; + else pGlint->FrameBufferReadMode = 0; + pGlint->ForeGroundColor = fg; + pGlint->BackGroundColor = bg; + REPLICATE(pGlint->ForeGroundColor); + REPLICATE(pGlint->BackGroundColor); + + GLINT_WAIT(8); + GLINT_WRITE_REG ((patternx & 0x000000ff), AreaStipplePattern0); + GLINT_WRITE_REG ((patternx & 0x0000ff00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG ((patternx & 0x00ff0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG ((patternx & 0xff000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG ((patterny & 0x000000ff), AreaStipplePattern4); + GLINT_WRITE_REG ((patterny & 0x0000ff00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG ((patterny & 0x00ff0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG ((patterny & 0xff000000) >> 24, AreaStipplePattern7); + + GLINT_WAIT(7); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); + GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0); + LOADROP(rop); +} + +static void +PermediaSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WAIT(8); + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + if (pGlint->FrameBufferReadMode != -1) { + GLINT_WRITE_REG(1<<20|patternx<<7|patterny<<12|UNIT_ENABLE, + AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | TextureEnable | PrimitiveTrapezoid, + Render); + } else { + GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render); + } +} + +static void +PermediaWriteBitmap(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char *srcpntr; + int dwords, height; + register int count; + register CARD32* pattern; + int dobackground = 0; + + w += skipleft; + x -= skipleft; + dwords = (w + 31) >> 5; + + PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h); + + GLINT_WAIT(14); + DO_PLANEMASK(planemask); + LOADROP(rop); + if (bg != -1) dobackground = ForceBackgroundColor; + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + pGlint->BackGroundColor = bg; + pGlint->ForeGroundColor = fg; + REPLICATE(fg); + REPLICATE(bg); + if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) { + pGlint->FrameBufferReadMode = FastFillEnable; + GLINT_WRITE_REG(0, RasterizerMode); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode); + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, ConstantColor); + if (dobackground) { + GLINT_WRITE_REG(bg, Texel0); + pGlint->FrameBufferReadMode = TextureEnable; + } else { + pGlint->FrameBufferReadMode = 0; + } + } + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, Render); + + height = h; + srcpntr = src; + while(height--) { + count = dwords >> 3; + pattern = (CARD32*)srcpntr; + while(count--) { + GLINT_WAIT(8); + GLINT_WRITE_REG(*(pattern), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+1), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+2), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+3), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+4), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+5), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+6), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+7), BitMaskPattern); + pattern+=8; + } + count = dwords & 0x07; + GLINT_WAIT(count); + while (count--) + GLINT_WRITE_REG(*(pattern++), BitMaskPattern); + srcpntr += srcwidth; + } + + PermediaDisableClipping(pScrn); + SET_SYNC_FLAG(infoRec); +} + +static void +PermediaSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dobackground = 0; + + if (bg != -1) dobackground |= ForceBackgroundColor; + pGlint->BackGroundColor = bg; + pGlint->ForeGroundColor = fg; + REPLICATE(fg); + REPLICATE(bg); + GLINT_WAIT(7); + DO_PLANEMASK(planemask); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode); + } + if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) { + pGlint->FrameBufferReadMode = FastFillEnable; + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, FBBlockColor); + GLINT_WRITE_REG(0,RasterizerMode); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(fg, ConstantColor); + GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode); + if (dobackground) { + GLINT_WRITE_REG(bg, Texel0); + pGlint->FrameBufferReadMode = TextureEnable; + } else { + pGlint->FrameBufferReadMode = 0; + } + } + LOADROP(rop); +} + +static void +PermediaSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ + +#if 0 + PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h); +#endif + + pGlint->cpucount = h; + + GLINT_WAIT(8); + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, + Render); +#if defined(__alpha__) + if (0) /* force Alpha to use indirect always */ +#else + if ((pGlint->dwords*h) < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than FIFOSize dword colour expansion */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; + pGlint->ScanlineDirect = 1; + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); + GLINT_WAIT(pGlint->dwords*h); + } else { + /* Use indirect for anything else */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; + pGlint->ScanlineDirect = 0; + } + + pGlint->cpucount--; +} + +static void +PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; + int dwords = pGlint->dwords; + + if (!pGlint->ScanlineDirect) { + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + dwords -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, dwords); + } + } +} + + +static void +PermediaWritePixmap8bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + unsigned char *srcpbyte; + Bool FastTexLoad = FALSE; + + GLINT_WAIT(2); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + + dwords = (w + 3) >> 2; + if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE; + if((rop != GXcopy) || (planemask != ~0)) + FastTexLoad = FALSE; + +#if 0 + if (rop == GXcopy) { + skipleft = 0; + } else { + if((skipleft = (long)src & 0x03)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03); + } + } +#endif + skipleft = 0; + + if(FastTexLoad) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + PermediaSync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = ((y * pScrn->displayWidth) + x) >> 2; + srcp = (CARD32*)src; + GLINT_WAIT(1); + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) + | (0x11 << 4) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + address += infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + GLINT_WAIT(10); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + LOADROP(rop); + GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); + + { + while(h--) { + count = w; + srcpbyte = (unsigned char *)src; + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | + (0x15 << 4) | 0x05, OutputFIFO); + GLINT_MoveBYTE( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned char *)srcpbyte, infoRec->ColorExpandRange-1); + count -= infoRec->ColorExpandRange - 1; + srcpbyte += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveBYTE( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned char *)srcpbyte, count); + } + src += srcwidth; + } + } + } + + SET_SYNC_FLAG(infoRec); +} + +static void +PermediaWritePixmap16bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + unsigned short* srcpword; + Bool FastTexLoad; + + GLINT_WAIT(2); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + + FastTexLoad = FALSE; + dwords = (w + 1) >> 1; + if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE; + if((rop != GXcopy) || (planemask != ~0)) + FastTexLoad = FALSE; + +#if 0 + if (rop == GXcopy) { + skipleft = 0; + } else { + if((skipleft = (long)src & 0x03L)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + } +#endif + skipleft = 0; + + if(FastTexLoad) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + PermediaSync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = ((y * pScrn->displayWidth) + x) >> 1; + srcp = (CARD32*)src; + GLINT_WAIT(1); + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | + (0x11 << 4) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + address += infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + GLINT_WAIT(10); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + LOADROP(rop); + GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); + + { + while(h--) { + count = w; + srcpword = (unsigned short *)src; + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | + (0x15 << 4) | 0x05, OutputFIFO); + GLINT_MoveWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned short *)srcpword,infoRec->ColorExpandRange-1); + count -= infoRec->ColorExpandRange - 1; + srcpword += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (unsigned short *)srcpword, count); + } + src += srcwidth; + } + } + } + + SET_SYNC_FLAG(infoRec); +} + +static void +PermediaWritePixmap32bpp( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, int depth +) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + int skipleft, dwords, count; + CARD32* srcp; + Bool FastTexLoad; + + GLINT_WAIT(3); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + + FastTexLoad = TRUE; + dwords = w; + if((rop != GXcopy) || (planemask != ~0)) + FastTexLoad = FALSE; + +#if 0 + if (!FastTexLoad) { + if((skipleft = (long)src & 0x03L)) { + skipleft /= (bpp>>3); + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + } +#endif + skipleft = 0; + + if(FastTexLoad) { + int address; + + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); + PermediaSync(pScrn); /* we are not using the rasterizer */ + while(h--) { + count = dwords; + address = (y * pScrn->displayWidth) + x; + srcp = (CARD32*)src; + GLINT_WAIT(1); + GLINT_WRITE_REG(address, TextureDownloadOffset); + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | + (0x11 << 4) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + address += infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x11 << 4) | 0x0D is the TAG for TextureData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, + OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + y++; + } + GLINT_WAIT(1); + GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); + } else { + GLINT_WAIT(9); + PermediaLoadCoord(pScrn, (x&0xFFFF)<<16, y<<16, ((x&0xFFFF)+w)<<16, h, 0, 1<<16); + LOADROP(rop); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | + (0x15 << 4) | 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count + 1); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + } + + SET_SYNC_FLAG(infoRec); +} + +static void +PermediaPolylinesThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolyLines(pDraw, pGC, mode, npt, pPts); +} + +static void +PermediaPolySegmentThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolySegment(pDraw, pGC, nseg, pSeg); +} + +static void +PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(color, GLINTColor); + GLINT_WRITE_REG(0, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(7); + if (dir == DEGREES_0) { + PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 1<<16, 0); + } else { + PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 0, 1<<16); + } + + GLINT_WRITE_REG(PrimitiveLine, Render); +} + +static void +PermediaSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dxdom, dy; + + if(dmaj == dmin) { + GLINT_WAIT(7); + if(octant & YDECREASING) { + dy = -1<<16; + } else { + dy = 1<<16; + } + + if(octant & XDECREASING) { + dxdom = -1<<16; + } else { + dxdom = 1<<16; + } + + PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy); + GLINT_WRITE_REG(PrimitiveLine, Render); + return; + } + + fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0, + (octant & XDECREASING) ? -1 : 1, + (octant & YDECREASING) ? -1 : 1, + (octant & YMAJOR) ? Y_AXIS : X_AXIS, + x, y, dmin + e, dmin, -dmaj, len); +} diff --git a/src/pm_dac.c b/src/pm_dac.c new file mode 100644 index 0000000..fed0c38 --- /dev/null +++ b/src/pm_dac.c @@ -0,0 +1,251 @@ +/* + * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Helmut Fahrion, <hf@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c,v 1.11 2002/02/27 18:41:04 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "IBM.h" +#include "TI.h" +#include "glint_regs.h" +#include "glint.h" + +Bool +PermediaInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTRegPtr pReg = &pGlint->ModeReg[0]; + RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn); + RamDacRegRecPtr ramdacReg = &pIBM->ModeReg; + CARD32 temp1, temp2, temp3, temp4; + + STOREREG(Aperture0, 0x00000000); + STOREREG(Aperture1, 0x00000000); + + pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; + pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; + + pReg->glintRegs[DFIFODis >> 3] = 1; + pReg->glintRegs[FIFODis >> 3] = 3; + + temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; + temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; + temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); + pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); + pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); + pReg->glintRegs[PMHbEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal - + mode->CrtcHDisplay); + pReg->glintRegs[PMHgEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal - + mode->CrtcHDisplay); + pReg->glintRegs[PMScreenStride >> 3] = + Shiftbpp(pScrn,pScrn->displayWidth>>1); + + pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; + pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; + pReg->glintRegs[PMVsStart >> 3] = temp2; + pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; + + pReg->glintRegs[PMVideoControl >> 3] = + (((mode->Flags & V_PHSYNC) ? 0x1 : 0x3) << 3) | + (((mode->Flags & V_PVSYNC) ? 0x1 : 0x3) << 5) | 1; + + pReg->glintRegs[VClkCtl >> 3] = 3; + pReg->glintRegs[PMScreenBase >> 3] = 0; + pReg->glintRegs[PMHTotal >> 3] -= 1; /* PMHTotal */ + pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */ + pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */ + pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD; + + switch(pGlint->RamDac->RamDacType) { + case IBM526_RAMDAC: + case IBM526DB_RAMDAC: + { + /* Get the programmable clock values */ + unsigned long m=0,n=0,p=0,c=0; + unsigned long clock; + + clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, + 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); + + ramdacReg->DacRegs[IBMRGB_m0] = m; + ramdacReg->DacRegs[IBMRGB_n0] = n; + ramdacReg->DacRegs[IBMRGB_p0] = p; + ramdacReg->DacRegs[IBMRGB_c0] = c; + + ramdacReg->DacRegs[IBMRGB_pll_ctrl1] = 0x05; + ramdacReg->DacRegs[IBMRGB_pll_ctrl2] = 0x00; + + p = 1; + clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, + 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); + + ramdacReg->DacRegs[IBMRGB_sysclk] = 0x05; + ramdacReg->DacRegs[IBMRGB_sysclk_m] = m; + ramdacReg->DacRegs[IBMRGB_sysclk_n] = n; + ramdacReg->DacRegs[IBMRGB_sysclk_p] = p; + ramdacReg->DacRegs[IBMRGB_sysclk_c] = c; + } + ramdacReg->DacRegs[IBMRGB_misc1] = SENS_DSAB_DISABLE | VRAM_SIZE_32; + ramdacReg->DacRegs[IBMRGB_misc2] = COL_RES_8BIT | PORT_SEL_VRAM; + if (pScrn->depth >= 24) + ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_LCLK; + else + ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_PLL; + ramdacReg->DacRegs[IBMRGB_misc3] = 0; + ramdacReg->DacRegs[IBMRGB_misc_clock] = 1; + ramdacReg->DacRegs[IBMRGB_sync] = 0; + ramdacReg->DacRegs[IBMRGB_hsync_pos] = 0; + ramdacReg->DacRegs[IBMRGB_pwr_mgmt] = 0; + ramdacReg->DacRegs[IBMRGB_dac_op] = 0; + ramdacReg->DacRegs[IBMRGB_pal_ctrl] = 0; + break; + case TI3026_RAMDAC: + { + /* Get the programmable clock values */ + unsigned long m=0,n=0,p=0; + unsigned long clock; + unsigned long q, VCO = 0; + + clock = TIramdacCalculateMNPForClock(pGlint->RefClock, + mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p); + + STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0)); + STORERAMDAC(TIDAC_PIXEL_M, (m & 0x3f)); + STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc)); + STORERAMDAC(TIDAC_PIXEL_VALID, TRUE); + + if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) + n = 65 - ((32 << 2) / pScrn->bitsPerPixel); + else + n = 65 - ((128 << 2) / pScrn->bitsPerPixel); + m = 61; + p = 0; + for (q = 0; q < 8; q++) { + if (q > 0) p = 3; + for ( ; p < 4; p++) { + VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1); + if (VCO >= 110000) { break; } + } + if (VCO >= 110000) { break; } + } + STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38)); + + STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0)); + STORERAMDAC(TIDAC_LOOP_M, (m & 0x3f)); + STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0)); + STORERAMDAC(TIDAC_LOOP_VALID, TRUE); + break; + } + } + + (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg); + + /* The permedia uses a 32bit data path, the TI ramdac code + * defaults to 64bit. So we knock it down to 32bit here */ + if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) + ramdacReg->DacRegs[TIDAC_multiplex_ctrl] -= 1; + + return(TRUE); +} + +void +PermediaSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536); + + glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); + glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); + glintReg->glintRegs[PMFramebufferWriteMask] = + GLINT_READ_REG(PMFramebufferWriteMask); + glintReg->glintRegs[PMBypassWriteMask >> 3] = + GLINT_READ_REG(PMBypassWriteMask); + glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); + glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); + + glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); + glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); + glintReg->glintRegs[PMHgEnd >> 3] = GLINT_READ_REG(PMHgEnd); + glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); + glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); + glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); + glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); + glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); + glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); + glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); + glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); + glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); + glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); + glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); +} + +void +PermediaRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + /* We can't rely on the vgahw layer copying the font information + * back properly, due to problems with MMIO access to VGA space + * so we memcpy the information using the slow routines */ + if (pGlint->STATE) + xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536); + + RESTOREREG(ChipConfig); + RESTOREREG(DFIFODis); + RESTOREREG(FIFODis); + RESTOREREG(Aperture0); + RESTOREREG(Aperture1); + RESTOREREG(PMFramebufferWriteMask); + RESTOREREG(PMBypassWriteMask); + RESTOREREG(PMVideoControl); + RESTOREREG(PMHgEnd); + RESTOREREG(VClkCtl); + RESTOREREG(PMHTotal); + RESTOREREG(PMHbEnd); + RESTOREREG(PMHsStart); + RESTOREREG(PMHsEnd); + RESTOREREG(PMVTotal); + RESTOREREG(PMVbEnd); + RESTOREREG(PMVsStart); + RESTOREREG(PMVsEnd); + RESTOREREG(PMScreenBase); + RESTOREREG(PMScreenStride); +} diff --git a/src/sx_accel.c b/src/sx_accel.c new file mode 100644 index 0000000..36ecd4b --- /dev/null +++ b/src/sx_accel.c @@ -0,0 +1,872 @@ +/* + * Copyright 1997-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + * + * GLINT 300SX accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/sx_accel.c,v 1.8 2001/10/28 03:33:30 tsi Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "fb.h" + +#include "miline.h" + +#include "glint_regs.h" +#include "glint.h" + +#include "xaalocal.h" /* For replacements */ + +static void SXSync(ScrnInfoPtr pScrn); +static void SXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void SXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void SXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, + int patterny, + int fg, int bg, int rop, + unsigned int planemask); +static void SXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int x, int y, + int w, int h); +static void SXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color); +static void SXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h); +#if 0 +static void SXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, + int skipleft, int fg, int bg, int rop, + unsigned int planemask); +static void SXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int rop, + unsigned int planemask, int trans, + int bpp, int depth); +static void SXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, + int bg, int rop, unsigned int planemask); +static void SXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void SXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#endif +static void SXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2,int y2); +static void SXDisableClipping(ScrnInfoPtr pScrn); +static void SXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h, + int a, int d); +static void SXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void SXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1, + int len, int dir); +static void SXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void SXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts); +static void SXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int nseg, xSegment *pSeg); + +#define MAX_FIFO_ENTRIES 15 + +void +SXInitializeEngine(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + /* Initialize the Accelerator Engine to defaults */ + + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); + GLINT_SLOW_WRITE_REG(0x400, FilterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode); + GLINT_SLOW_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode); + GLINT_SLOW_WRITE_REG(0, UpdateLineStippleCounters); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + + pGlint->ROP = 0xFF; + pGlint->ClippingOn = FALSE; + pGlint->startxsub = 0; + pGlint->startxdom = 0; + pGlint->starty = 0; + pGlint->count = 0; + pGlint->dxdom = 0; + pGlint->dy = 1; + pGlint->planemask = 0; + GLINT_SLOW_WRITE_REG(0, StartXSub); + GLINT_SLOW_WRITE_REG(0, StartXDom); + GLINT_SLOW_WRITE_REG(0, StartY); + GLINT_SLOW_WRITE_REG(0, GLINTCount); + GLINT_SLOW_WRITE_REG(0, dXDom); + GLINT_SLOW_WRITE_REG(0, dXSub); + GLINT_SLOW_WRITE_REG(1<<16, dY); +} + +Bool +SXAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + long memory = pGlint->FbMapSize; + BoxRec AvailFBArea; + + pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + SXInitializeEngine(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + infoPtr->Sync = SXSync; + + infoPtr->SetClippingRectangle = SXSetClippingRectangle; + infoPtr->DisableClipping = SXDisableClipping; + infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_SOLID_FILL; + + infoPtr->SolidFillFlags = 0; + infoPtr->SetupForSolidFill = SXSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = SXSubsequentFillRectSolid; + + infoPtr->SolidLineFlags = 0; + infoPtr->PolySegmentThinSolidFlags = 0; + infoPtr->PolylinesThinSolidFlags = 0; + infoPtr->SetupForSolidLine = SXSetupForSolidLine; + infoPtr->SubsequentSolidHorVertLine = SXSubsequentHorVertLine; + infoPtr->SubsequentSolidBresenhamLine = + SXSubsequentSolidBresenhamLine; + infoPtr->PolySegmentThinSolid = SXPolySegmentThinSolidWrapper; + infoPtr->PolylinesThinSolid = SXPolylinesThinSolidWrapper; + + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | + ONLY_LEFT_TO_RIGHT_BITBLT; + infoPtr->SetupForScreenToScreenCopy = SXSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = SXSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS; + infoPtr->SetupForMono8x8PatternFill = SXSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + SXSubsequentMono8x8PatternFillRect; + +#if 0 + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + TRANSPARENCY_ONLY | + BIT_ORDER_IN_BYTE_LSBFIRST; + + infoPtr->NumScanlineColorExpandBuffers = 1; + pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4) + + (pScrn->virtualX + * pScrn->bitsPerPixel / 8)); + infoPtr->ScanlineColorExpandBuffers = + pGlint->XAAScanlineColorExpandBuffers; + pGlint->XAAScanlineColorExpandBuffers[0] = + pGlint->IOBase + OutputFIFO + 4; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + SXSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + SXSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + SXSubsequentColorExpandScanline; + + infoPtr->WriteBitmap = SXWriteBitmap; + infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES; + + infoPtr->WritePixmap = SXWritePixmap; +#endif + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + if (memory > (16383*1024)) memory = 16383*1024; + AvailFBArea.y2 = memory / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047; + + xf86InitFBManager(pScreen, &AvailFBArea); + + return (XAAInit(pScreen, infoPtr)); +} + +static void SXLoadCoord( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int a, int d +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (w != pGlint->startxsub) { + GLINT_WRITE_REG(w<<16, StartXSub); + pGlint->startxsub = w; + } + if (x != pGlint->startxdom) { + GLINT_WRITE_REG(x<<16,StartXDom); + pGlint->startxdom = x; + } + if (y != pGlint->starty) { + GLINT_WRITE_REG(y<<16,StartY); + pGlint->starty = y; + } + if (h != pGlint->count) { + GLINT_WRITE_REG(h,GLINTCount); + pGlint->count = h; + } + if (a != pGlint->dxdom) { + GLINT_WRITE_REG(a<<16,dXDom); + pGlint->dxdom = a; + } + if (d != pGlint->dy) { + GLINT_WRITE_REG(d<<16,dY); + pGlint->dy = d; + } +} + +static void +SXSync( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 readValue; + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(3); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + } while (readValue != Sync_tag); +} + +static void +SXSetupForFillRectSolid( + ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + pGlint->ForeGroundColor = color; + + GLINT_WAIT(6); + REPLICATE(color); + DO_PLANEMASK(planemask); + if (pScrn->bitsPerPixel >= 24) { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(color, ConstantColor); + pGlint->FrameBufferReadMode = 0; + } else + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(color, FBBlockColor); + pGlint->FrameBufferReadMode = FastFillEnable; + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(color, ConstantColor); + pGlint->FrameBufferReadMode = 0; + } + LOADROP(rop); +} + +static void +SXSubsequentFillRectSolid( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(8); + SXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render); +} + +static void +SXSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2 +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(5); + GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY); + GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY); + GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */ + pGlint->ClippingOn = TRUE; +} + +static void +SXDisableClipping( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + CHECKCLIPPING; +} + +static void +SXSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, + int rop, + unsigned int planemask, + int transparency_color +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->BltScanDirection = ydir; + + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +SXSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int srcaddr, dstaddr; + + GLINT_WAIT(10); + + srcaddr = y1 * pScrn->displayWidth + x1; + dstaddr = y2 * pScrn->displayWidth + x2; + GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset); + + if (pGlint->BltScanDirection != 1) { + y1 += h - 1; + y2 += h - 1; + SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1); + } else { + SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1); + } + + GLINT_WRITE_REG(PrimitiveTrapezoid, Render); +} + +#if 0 +static void +SXSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + REPLICATE(fg); + REPLICATE(bg); + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + pGlint->FrameBufferReadMode = FastFillEnable; + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode); + pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation; + GLINT_WRITE_REG(fg, PatternRamData0); + } + LOADROP(rop); +} + +static void +SXSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ + + pGlint->cpucount = h; + + GLINT_WAIT(8); + SXLoadCoord(pScrn, x, y, x+w, 1, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, + Render); +#if defined(__alpha__) + if (0) /* force Alpha to use indirect always */ +#else + if ((pGlint->dwords*h) < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than FIFOSize dword colour expansion */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; + pGlint->ScanlineDirect = 1; + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); + GLINT_WAIT(pGlint->dwords*h); + } else { + /* Use indirect for anything else */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; + pGlint->ScanlineDirect = 0; + } + + pGlint->cpucount--; +} + +static void +SXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; + int dwords = pGlint->dwords; + + if (!pGlint->ScanlineDirect) { + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + dwords -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, dwords); + } + } +} +#endif + +void SXSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (bg == -1) pGlint->FrameBufferReadMode = -1; + else pGlint->FrameBufferReadMode = 0; + pGlint->ForeGroundColor = fg; + pGlint->BackGroundColor = bg; + REPLICATE(pGlint->ForeGroundColor); + REPLICATE(pGlint->BackGroundColor); + + GLINT_WAIT(13); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG((patternx & 0x000000FF), AreaStipplePattern0); + GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG((patterny & 0x000000FF), AreaStipplePattern4); + GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); + + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + if (rop == GXcopy) + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + else + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + LOADROP(rop); +} + +static void +SXSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(12); + SXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + + if (pGlint->FrameBufferReadMode != -1) { + GLINT_WRITE_REG(pGlint->BackGroundColor, ConstantColor); + GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern | + UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render); + } + + GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); + GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12| + UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render); +} + +#if 0 +static void +SXWriteBitmap(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char *srcpntr; + int dwords, height, mode; + Bool SecondPass = FALSE; + register int count; + register CARD32* pattern; + + w += skipleft; + x -= skipleft; + dwords = (w + 31) >> 5; + + SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h); + + GLINT_WAIT(11); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, RasterizerMode); + LOADROP(rop); + if (rop == GXcopy) { + mode = FastFillEnable; + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + mode = 0; + GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + SXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + + if(bg == -1) { + REPLICATE(fg); + GLINT_WAIT(3); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } else if(rop == GXcopy) { + REPLICATE(bg); + GLINT_WAIT(5); + if (rop == GXcopy) { + GLINT_WRITE_REG(bg, FBBlockColor); + } else { + GLINT_WRITE_REG(bg, PatternRamData0); + } + GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render); + REPLICATE(fg); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } else { + SecondPass = TRUE; + REPLICATE(fg); + GLINT_WAIT(3); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } + +SECOND_PASS: + GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render); + + height = h; + srcpntr = src; + while(height--) { + count = dwords >> 3; + pattern = (CARD32*)srcpntr; + while(count--) { + GLINT_WAIT(8); + GLINT_WRITE_REG(*(pattern), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+1), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+2), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+3), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+4), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+5), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+6), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+7), BitMaskPattern); + pattern+=8; + } + count = dwords & 0x07; + GLINT_WAIT(count); + while (count--) + GLINT_WRITE_REG(*(pattern++), BitMaskPattern); + srcpntr += srcwidth; + } + + if(SecondPass) { + SecondPass = FALSE; + REPLICATE(bg); + GLINT_WAIT(4); + GLINT_WRITE_REG(InvertBitMask, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(bg, FBBlockColor); + } else { + GLINT_WRITE_REG(bg, PatternRamData0); + } + goto SECOND_PASS; + } + + GLINT_WAIT(2); + GLINT_WRITE_REG(0, RasterizerMode); + CHECKCLIPPING; + SET_SYNC_FLAG(infoRec); +} + +static void +SXWritePixmap( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, /* bytes */ + int rop, + unsigned int planemask, + int trans, + int bpp, int depth +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp; + int count,dwords, skipleft, Bpp = bpp >> 3; + + if((skipleft = (long)src & 0x03L)) { + skipleft /= Bpp; + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + + switch(Bpp) { + case 1: dwords = (w + 3) >> 2; + break; + case 2: dwords = (w + 1) >> 1; + break; + case 4: dwords = w; + break; + default: return; + } + + SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h); + + GLINT_WAIT(12); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); + SXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x0f << 4) | 0x0e is the TAG for GLINTColor */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x0F << 4) | + 0x0E, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count); + /* (0x0F << 4) | 0x0E is the TAG for GLINTColor */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x0f << 4) | + 0x0e, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + CHECKCLIPPING; + SET_SYNC_FLAG(infoRec); +} +#endif + +static void +SXPolylinesThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolyLines(pDraw, pGC, mode, npt, pPts); +} + +static void +SXPolySegmentThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolySegment(pDraw, pGC, nseg, pSeg); +} + +static void +SXSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(7); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(color, GLINTColor); + GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +SXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(9); + if (dir == DEGREES_0) { + SXLoadCoord(pScrn, x, y, 0, len, 1, 0); + } else { + SXLoadCoord(pScrn, x, y, 0, len, 0, 1); + } + + GLINT_WRITE_REG(PrimitiveLine, Render); +} + +static void +SXSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dxdom, dy; + + if(dmaj == dmin) { + GLINT_WAIT(9); + if(octant & YDECREASING) { + dy = -1; + } else { + dy = 1; + } + + if(octant & XDECREASING) { + dxdom = -1; + } else { + dxdom = 1; + } + + SXLoadCoord(pScrn, x, y, 0, len, dxdom, dy); + GLINT_WRITE_REG(PrimitiveLine, Render); + return; + } + + fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0, + (octant & XDECREASING) ? -1 : 1, + (octant & YDECREASING) ? -1 : 1, + (octant & YMAJOR) ? Y_AXIS : X_AXIS, + x, y, dmin + e, dmin, -dmaj, len); +} diff --git a/src/tx_accel.c b/src/tx_accel.c new file mode 100644 index 0000000..9e30ec3 --- /dev/null +++ b/src/tx_accel.c @@ -0,0 +1,961 @@ +/* + * Copyright 1997-2001 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + * + * GLINT 500TX / MX accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c,v 1.28 2001/05/30 10:07:56 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "fb.h" + +#include "miline.h" + +#include "glint_regs.h" +#include "glint.h" + +#include "xaalocal.h" /* For replacements */ + +static void TXSync(ScrnInfoPtr pScrn); +static void DualTXSync(ScrnInfoPtr pScrn); +static void TXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void TXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void TXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, + int patterny, + int fg, int bg, int rop, + unsigned int planemask); +static void TXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int x, int y, + int w, int h); +static void TXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color); +static void TXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h); +static void TXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, + int skipleft, int fg, int bg, int rop, + unsigned int planemask); +static void TXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, + int x2,int y2); +static void TXDisableClipping(ScrnInfoPtr pScrn); +static void TXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int rop, + unsigned int planemask, int trans, + int bpp, int depth); +static void TXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, + int bg, int rop, unsigned int planemask); +static void TXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft); +static void TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +static void TXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h, + int a, int d); +static void TXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void TXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1, + int len, int dir); +static void TXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, + int len, int octant); +static void TXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int mode, int npt, DDXPointPtr pPts); +static void TXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, + int nseg, xSegment *pSeg); + +void +TXInitializeEngine(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + /* Initialize the Accelerator Engine to defaults */ + pGlint->rasterizerMode = UNIT_DISABLE; + + if (pGlint->MultiAperture) { + pGlint->rasterizerMode = RMMultiGLINT; + + /* Only write the following register to the first chip */ + GLINT_SLOW_WRITE_REG(1, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership); + + /* Only write the following register to the second chip */ + GLINT_SLOW_WRITE_REG(2, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership); + + /* Make sure the rest of the register writes go to both chip's */ + GLINT_SLOW_WRITE_REG(3, BroadcastMask); + + pGlint->pprod |= FBRM_ScanlineInt2; + } + + GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode); + GLINT_SLOW_WRITE_REG(pGlint->rasterizerMode, RasterizerMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + GLINT_SLOW_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_SLOW_WRITE_REG(0, dXSub); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode); + GLINT_SLOW_WRITE_REG(0, UpdateLineStippleCounters); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); + GLINT_SLOW_WRITE_REG(0x400, FilterMode); + GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask); + GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PatternRamMode); + + switch (pScrn->bitsPerPixel) { + case 8: + GLINT_SLOW_WRITE_REG(0x2, PixelSize); + break; + case 16: + GLINT_SLOW_WRITE_REG(0x1, PixelSize); + break; + case 32: + GLINT_SLOW_WRITE_REG(0x0, PixelSize); + break; + } + pGlint->ROP = 0xFF; + pGlint->ClippingOn = FALSE; + pGlint->startxsub = 0; + pGlint->startxdom = 0; + pGlint->starty = 0; + pGlint->count = 0; + pGlint->dxdom = 0; + pGlint->dy = 1; + pGlint->planemask = 0; + GLINT_SLOW_WRITE_REG(0, StartXSub); + GLINT_SLOW_WRITE_REG(0, StartXDom); + GLINT_SLOW_WRITE_REG(0, StartY); + GLINT_SLOW_WRITE_REG(0, GLINTCount); + GLINT_SLOW_WRITE_REG(0, dXDom); + GLINT_SLOW_WRITE_REG(1<<16, dY); +} + +Bool +TXAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + long memory = pGlint->FbMapSize; + BoxRec AvailFBArea; + + pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; + + TXInitializeEngine(pScrn); + + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + if (pGlint->MultiAperture) + infoPtr->Sync = DualTXSync; + else + infoPtr->Sync = TXSync; + + infoPtr->SetClippingRectangle = TXSetClippingRectangle; + infoPtr->DisableClipping = TXDisableClipping; + infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_SOLID_FILL; + + infoPtr->SolidFillFlags = 0; + infoPtr->SetupForSolidFill = TXSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = TXSubsequentFillRectSolid; + + infoPtr->SolidLineFlags = 0; + infoPtr->PolySegmentThinSolidFlags = 0; + infoPtr->PolylinesThinSolidFlags = 0; + infoPtr->SetupForSolidLine = TXSetupForSolidLine; + infoPtr->SubsequentSolidHorVertLine = TXSubsequentHorVertLine; + if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)) + { + infoPtr->SubsequentSolidBresenhamLine = + TXSubsequentSolidBresenhamLine; + } + infoPtr->PolySegmentThinSolid = TXPolySegmentThinSolidWrapper; + infoPtr->PolylinesThinSolid = TXPolylinesThinSolidWrapper; + + if (!pGlint->MultiAperture) { + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | + ONLY_LEFT_TO_RIGHT_BITBLT; + infoPtr->SetupForScreenToScreenCopy = TXSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = TXSubsequentScreenToScreenCopy; + } + + infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS; + infoPtr->SetupForMono8x8PatternFill = TXSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = TXSubsequentMono8x8PatternFillRect; + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + TRANSPARENCY_ONLY | + BIT_ORDER_IN_BYTE_LSBFIRST; + + infoPtr->NumScanlineColorExpandBuffers = 1; + pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4) + + (pScrn->virtualX + * pScrn->bitsPerPixel / 8)); + infoPtr->ScanlineColorExpandBuffers = + pGlint->XAAScanlineColorExpandBuffers; + pGlint->XAAScanlineColorExpandBuffers[0] = + pGlint->IOBase + OutputFIFO + 4; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + TXSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + TXSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + TXSubsequentColorExpandScanline; + + infoPtr->ColorExpandRange = pGlint->FIFOSize; + + infoPtr->WriteBitmap = TXWriteBitmap; + infoPtr->WritePixmap = TXWritePixmap; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + if (memory > (16383*1024)) memory = 16383*1024; + AvailFBArea.y2 = memory / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095; + + xf86InitFBManager(pScreen, &AvailFBArea); + + return (XAAInit(pScreen, infoPtr)); +} + +static void TXLoadCoord( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int a, int d +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + +#ifndef XF86DRI + if (w != pGlint->startxsub) { + GLINT_WRITE_REG(w<<16, StartXSub); + pGlint->startxsub = w; + } + if (x != pGlint->startxdom) { + GLINT_WRITE_REG(x<<16,StartXDom); + pGlint->startxdom = x; + } + if (y != pGlint->starty) { + GLINT_WRITE_REG(y<<16,StartY); + pGlint->starty = y; + } + if (h != pGlint->count) { + GLINT_WRITE_REG(h,GLINTCount); + pGlint->count = h; + } + if (a != pGlint->dxdom) { + GLINT_WRITE_REG(a<<16,dXDom); + pGlint->dxdom = a; + } + if (d != pGlint->dy) { + GLINT_WRITE_REG(d<<16,dY); + pGlint->dy = d; + } +#else + GLINT_WRITE_REG(w<<16, StartXSub); + GLINT_WRITE_REG(x<<16,StartXDom); + GLINT_WRITE_REG(y<<16,StartY); + GLINT_WRITE_REG(h,GLINTCount); + GLINT_WRITE_REG(a<<16,dXDom); + GLINT_WRITE_REG(d<<16,dY); + pGlint->startxsub = w; + pGlint->startxdom = x; + pGlint->starty = y; + pGlint->count = h; + pGlint->dxdom = a; + pGlint->dy = d; +#endif +} + +static void +TXSync( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 readValue; + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(2); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + } while (readValue != Sync_tag); +} + +static void +DualTXSync( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned long readValue; + + CHECKCLIPPING; + + while (GLINT_READ_REG(DMACount) != 0); + GLINT_WAIT(3); + + /* hack! this shouldn't need to be reloaded */ + GLINT_WRITE_REG(3, BroadcastMask); + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + + /* Read 1st MX until Sync Tag shows */ + ACCESSCHIP1(); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + } while (readValue != Sync_tag); + + ACCESSCHIP2(); + /* Read 2nd MX until Sync Tag shows */ + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + readValue = GLINT_READ_REG(OutputFIFO); + } while (readValue != Sync_tag); + + ACCESSCHIP1(); +} + + +static void +TXSetupForFillRectSolid( + ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + pGlint->ForeGroundColor = color; + + GLINT_WAIT(5); + REPLICATE(color); + DO_PLANEMASK(planemask); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + GLINT_WRITE_REG(color, FBBlockColor); + pGlint->FrameBufferReadMode = FastFillEnable; + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode); + GLINT_WRITE_REG(color, PatternRamData0); + pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation; + } + LOADROP(rop); +} + +static void +TXSubsequentFillRectSolid( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(7); + TXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render); +} + +static void +TXSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2 +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(3); + GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY); + GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY); + GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */ + pGlint->ClippingOn = TRUE; +} + +static void +TXDisableClipping( + ScrnInfoPtr pScrn +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + CHECKCLIPPING; +} + +static void +TXSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, + int rop, + unsigned int planemask, + int transparency_color +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->BltScanDirection = ydir; + + GLINT_WAIT(5); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +TXSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int srcaddr, dstaddr; + + GLINT_WAIT(8); + if (pGlint->BltScanDirection != 1) { + y1 += h - 1; + y2 += h - 1; + TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1); + } else { + TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1); + } + + srcaddr = y1 * pScrn->displayWidth + x1; + dstaddr = y2 * pScrn->displayWidth + x2; + + GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset); + GLINT_WRITE_REG(PrimitiveTrapezoid| FastFillEnable | SpanOperation, Render); +} + +static void +TXSetupForScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + REPLICATE(fg); + REPLICATE(bg); + GLINT_WAIT(6); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + pGlint->FrameBufferReadMode = FastFillEnable; + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode); + pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation; + GLINT_WRITE_REG(fg, PatternRamData0); + } + LOADROP(rop); +} + +static void +TXSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ + + pGlint->cpucount = h; + + GLINT_WAIT(8); + TXLoadCoord(pScrn, x, y, (x+w), h, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, + Render); +#if defined(__alpha__) + if (0) /* force Alpha to use indirect always */ +#else + if ((pGlint->dwords*h) < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than FIFOSize dword colour expansion */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; + pGlint->ScanlineDirect = 1; + GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); + GLINT_WAIT(pGlint->dwords*h); + } else { + /* Use indirect for anything else */ + pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; + pGlint->ScanlineDirect = 0; + } + + pGlint->cpucount--; +} + +static void +TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; + int dwords = pGlint->dwords; + + if (!pGlint->ScanlineDirect) { + while(dwords >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, pGlint->FIFOSize - 1); + dwords -= pGlint->FIFOSize - 1; + srcp += pGlint->FIFOSize - 1; + } + if(dwords) { + GLINT_WAIT(dwords + 1); + GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, dwords); + } + } +} + +void TXSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (bg == -1) pGlint->FrameBufferReadMode = -1; + else pGlint->FrameBufferReadMode = 0; + pGlint->ForeGroundColor = fg; + pGlint->BackGroundColor = bg; + REPLICATE(pGlint->ForeGroundColor); + REPLICATE(pGlint->BackGroundColor); + + GLINT_WAIT(13); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG((patternx & 0x000000FF), AreaStipplePattern0); + GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8, AreaStipplePattern1); + GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2); + GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); + GLINT_WRITE_REG((patterny & 0x000000FF), AreaStipplePattern4); + GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8, AreaStipplePattern5); + GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6); + GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); + + if (rop == GXcopy) { + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode); + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +TXSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + int span = 0; + + GLINT_WAIT(12); + TXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + + if (pGlint->FrameBufferReadMode != -1) { + if (pGlint->ROP == GXcopy) { + GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor); + span = 0; + } else { + GLINT_WRITE_REG(pGlint->BackGroundColor, PatternRamData0); + span = SpanOperation; + } + GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern | + UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable | + PrimitiveTrapezoid, Render); + } + + if (pGlint->ROP == GXcopy) { + GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor); + span = 0; + } else { + GLINT_WRITE_REG(pGlint->ForeGroundColor, PatternRamData0); + span = SpanOperation; + } + GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12| + UNIT_ENABLE, AreaStippleMode); + GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable | + PrimitiveTrapezoid, Render); +} + +static void +TXWriteBitmap(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + unsigned char *srcpntr; + int dwords, height, mode; + Bool SecondPass = FALSE; + register int count; + register CARD32* pattern; + + w += skipleft; + x -= skipleft; + dwords = (w + 31) >> 5; + + TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h); + + GLINT_WAIT(11); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode); + LOADROP(rop); + if (rop == GXcopy) { + mode = 0; + GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode); + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + mode = SpanOperation; + GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode); + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + TXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + + if(bg == -1) { + REPLICATE(fg); + GLINT_WAIT(3); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } else if(rop == GXcopy) { + REPLICATE(bg); + GLINT_WAIT(5); + if (rop == GXcopy) { + GLINT_WRITE_REG(bg, FBBlockColor); + } else { + GLINT_WRITE_REG(bg, PatternRamData0); + } + GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render); + REPLICATE(fg); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } else { + SecondPass = TRUE; + REPLICATE(fg); + GLINT_WAIT(3); + if (rop == GXcopy) { + GLINT_WRITE_REG(fg, FBBlockColor); + } else { + GLINT_WRITE_REG(fg, PatternRamData0); + } + } + +SECOND_PASS: + GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render); + + height = h; + srcpntr = src; + while(height--) { + count = dwords >> 3; + pattern = (CARD32*)srcpntr; + while(count--) { + GLINT_WAIT(8); + GLINT_WRITE_REG(*(pattern), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+1), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+2), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+3), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+4), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+5), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+6), BitMaskPattern); + GLINT_WRITE_REG(*(pattern+7), BitMaskPattern); + pattern+=8; + } + count = dwords & 0x07; + GLINT_WAIT(count); + while (count--) + GLINT_WRITE_REG(*(pattern++), BitMaskPattern); + srcpntr += srcwidth; + } + + if(SecondPass) { + SecondPass = FALSE; + REPLICATE(bg); + GLINT_WAIT(4); + GLINT_WRITE_REG(InvertBitMask | pGlint->rasterizerMode, RasterizerMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(bg, FBBlockColor); + } else { + GLINT_WRITE_REG(bg, PatternRamData0); + } + goto SECOND_PASS; + } + + GLINT_WAIT(2); + GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode); + CHECKCLIPPING; + SET_SYNC_FLAG(infoRec); +} + +static void +TXWritePixmap( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char *src, + int srcwidth, /* bytes */ + int rop, + unsigned int planemask, + int trans, + int bpp, int depth +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GLINTPtr pGlint = GLINTPTR(pScrn); + CARD32 *srcp; + int count,dwords, skipleft, Bpp = bpp >> 3; + + if((skipleft = (long)src & 0x03L)) { + skipleft /= Bpp; + + x -= skipleft; + w += skipleft; + + src = (unsigned char*)((long)src & ~0x03L); + } + + switch(Bpp) { + case 1: dwords = (w + 3) >> 2; + break; + case 2: dwords = (w + 1) >> 1; + break; + case 4: dwords = w; + break; + default: return; + } + + TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h); + + GLINT_WAIT(12); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(0, PatternRamMode); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); + TXLoadCoord(pScrn, x, y, x+w, h, 0, 1); + GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | SpanOperation | + SyncOnHostData, Render); + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= infoRec->ColorExpandRange) { + GLINT_WAIT(infoRec->ColorExpandRange); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, infoRec->ColorExpandRange - 1); + count -= infoRec->ColorExpandRange - 1; + srcp += infoRec->ColorExpandRange - 1; + } + if(count) { + GLINT_WAIT(count); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)srcp, count); + } + src += srcwidth; + } + CHECKCLIPPING; + SET_SYNC_FLAG(infoRec); +} + +static void +TXPolylinesThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolyLines(pDraw, pGC, mode, npt, pPts); +} + +static void +TXPolySegmentThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); + pGlint->CurrentGC = pGC; + pGlint->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); + XAAPolySegment(pDraw, pGC, nseg, pSeg); +} + +static void +TXSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(5); + DO_PLANEMASK(planemask); + GLINT_WRITE_REG(color, GLINTColor); + if (rop == GXcopy) { + GLINT_WRITE_REG(pGlint->pprod, FBReadMode); + } else { + GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); + } + LOADROP(rop); +} + +static void +TXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + GLINT_WAIT(7); + if (dir == DEGREES_0) { + TXLoadCoord(pScrn, x, y, 0, len, 1, 0); + } else { + TXLoadCoord(pScrn, x, y, 0, len, 0, 1); + } + + GLINT_WRITE_REG(PrimitiveLine, Render); +} + +static void +TXSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, + int x, int y, int dmaj, int dmin, int e, int len, int octant) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + int dxdom, dy; + + if(dmaj == dmin) { + GLINT_WAIT(7); + if(octant & YDECREASING) { + dy = -1; + } else { + dy = 1; + } + + if(octant & XDECREASING) { + dxdom = -1; + } else { + dxdom = 1; + } + + TXLoadCoord(pScrn, x, y, 0, len, dxdom, dy); + GLINT_WRITE_REG(PrimitiveLine, Render); + return; + } + + fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0, + (octant & XDECREASING) ? -1 : 1, + (octant & YDECREASING) ? -1 : 1, + (octant & YMAJOR) ? Y_AXIS : X_AXIS, + x, y, dmin + e, dmin, -dmaj, len); +} diff --git a/src/tx_dac.c b/src/tx_dac.c new file mode 100644 index 0000000..8924e96 --- /dev/null +++ b/src/tx_dac.c @@ -0,0 +1,397 @@ +/* + * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Dirk Hohndel, <hohndel@suse.de> + * Stefan Dirsch, <sndirsch@suse.de> + * Helmut Fahrion, <hf@suse.de> + * + * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and + * Siemens Nixdorf Informationssysteme + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c,v 1.15 2001/05/29 11:23:38 alanh Exp $ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "IBM.h" +#include "TI.h" +#include "glint_regs.h" +#include "glint.h" + +Bool +TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + RamDacHWRecPtr pRamDac = RAMDACHWPTR(pScrn); + RamDacRegRecPtr ramdacReg = &pRamDac->ModeReg; + CARD32 temp1, temp2, temp3, temp4; + + if (pGlint->numMultiDevices == 2) { + STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn); + } + + if (pGlint->MultiAperture) { + /* + * Setup HW + * + * Note: The order of discovery for the MX devices is dependent + * on which way the resource allocation code decides to scan the + * bus. This setup assumes the first MX found owns the even + * scanlines. Should the implementation change an scan the bus + * in the opposite direction, then simple invert the indices for + * MultiPciInfo below. If this is setup wrong, the bug will appear + * as incorrect scanline interleaving when software rendering. + */ + STOREREG(GMultGLINTAperture, pGlint->realWidth); + STOREREG(GMultGLINT1, + pGlint->MultiPciInfo[0]->memBase[2] & 0xFF800000); + STOREREG(GMultGLINT2, + pGlint->MultiPciInfo[1]->memBase[2] & 0xFF800000); + } + + if (IS_GMX2000 || IS_GLORIAXXL) { + pReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO); + pReg->glintRegs[LBMemoryEDO >> 3] &= ~(LBEDOMask | + LBEDOBankSizeMask | + LBTwoPageDetectorMask); + pReg->glintRegs[LBMemoryEDO >> 3] |= (LBEDOEnabled | + LBEDOBankSize4M | + LBTwoPageDetector); + pReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl); + pReg->glintRegs[LBMemoryCtl >> 3] &= ~(LBNumBanksMask | + LBPageSizeMask | + LBRASCASLowMask | + LBRASPrechargeMask | + LBCASLowMask | + LBPageModeMask | + LBRefreshCountMask); + pReg->glintRegs[LBMemoryCtl >> 3] |= (LBNumBanks2 | + LBPageSize1024 | + LBRASCASLow2 | + LBRASPrecharge2 | + LBCASLow1 | + LBPageModeEnabled | + (0x20 << LBRefreshCountShift)); + } + + STOREREG(Aperture0, 0); + STOREREG(Aperture1, 0); + + STOREREG(DFIFODis, GLINT_READ_REG(DFIFODis) & 0xFFFFFFFE); + STOREREG(FIFODis, GLINT_READ_REG(FIFODis) | 0x01); + + temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; + temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; + temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; + temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + + STOREREG(VTGHLimit, Shiftbpp(pScrn, mode->CrtcHTotal)); + STOREREG(VTGHSyncEnd, Shiftbpp(pScrn, temp1 + temp3)); + STOREREG(VTGHSyncStart, Shiftbpp(pScrn, temp1)); + STOREREG(VTGHBlankEnd, + Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); + + STOREREG(VTGVLimit, mode->CrtcVTotal); + STOREREG(VTGVSyncEnd, temp2 + temp4); + STOREREG(VTGVSyncStart, temp2); + STOREREG(VTGVBlankEnd, mode->CrtcVTotal - mode->CrtcVDisplay); + + if (IS_GMX2000) { + STOREREG(VTGPolarity, 0xba); + } else { + STOREREG(VTGPolarity, (((mode->Flags & V_PHSYNC ? 0:2)<<2) | + ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0))); + } + + STOREREG(VClkCtl, 0); + STOREREG(VTGVGateStart, mode->CrtcVTotal - mode->CrtcVDisplay - 1); + STOREREG(VTGVGateEnd, mode->CrtcVTotal - mode->CrtcVDisplay); + + /* This is ugly */ + if (pGlint->UseFireGL3000) { + STOREREG(VTGSerialClk, 0x05); + STOREREG(VTGHGateStart, + Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1)); + STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1); + STOREREG(FBModeSel, 0x907); + STOREREG(VTGModeCtl, 0x00); + } else + if (IS_GMX2000) { + STOREREG(VTGSerialClk, 0x02); + STOREREG(VTGHGateStart, + Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1)); + STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1); + STOREREG(FBModeSel, 0x907); + STOREREG(VTGModeCtl, 0x04); + } else { + STOREREG(VTGSerialClk, 0x05); + STOREREG(VTGHGateStart, + Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay) - 2); + STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 2); + STOREREG(FBModeSel, 0x0A07); + STOREREG(VTGModeCtl, 0x44); + } + + if (IS_GMX2000 || IS_GLORIAXXL) { + STOREREG(FBMemoryCtl, 0x800); /* Optimum memory timings */ + } else { + STOREREG(FBMemoryCtl, GLINT_READ_REG(FBMemoryCtl)); + } + + /* Override FBModeSel for 300SX chip */ + if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || + ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && + (pGlint->MultiChip == PCI_CHIP_300SX)) ) { + switch (pScrn->bitsPerPixel) { + case 8: + STOREREG(FBModeSel, 0x905); + break; + case 16: + STOREREG(FBModeSel, 0x903); + break; + case 32: + STOREREG(FBModeSel, 0x901); + break; + } + } + + switch (pGlint->RamDac->RamDacType) { + case IBM526DB_RAMDAC: + case IBM526_RAMDAC: + { + /* Get the programmable clock values */ + unsigned long m=0,n=0,p=0,c=0; + unsigned long clock; + + clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, + 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); + + STORERAMDAC(IBMRGB_m0, m); + STORERAMDAC(IBMRGB_n0, n); + STORERAMDAC(IBMRGB_p0, p); + STORERAMDAC(IBMRGB_c0, c); + + STORERAMDAC(IBMRGB_pll_ctrl1, 0x05); + STORERAMDAC(IBMRGB_pll_ctrl2, 0x00); + + p = 1; + clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, + 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); + + STORERAMDAC(IBMRGB_sysclk, 0x05); + STORERAMDAC(IBMRGB_sysclk_m, m); + STORERAMDAC(IBMRGB_sysclk_n, n); + STORERAMDAC(IBMRGB_sysclk_p, p); + STORERAMDAC(IBMRGB_sysclk_c, c); + } + STORERAMDAC(IBMRGB_misc1, SENS_DSAB_DISABLE | VRAM_SIZE_64); + STORERAMDAC(IBMRGB_misc2, COL_RES_8BIT | PORT_SEL_VRAM | PCLK_SEL_PLL); + STORERAMDAC(IBMRGB_misc3, 0); + STORERAMDAC(IBMRGB_misc_clock, 1); + STORERAMDAC(IBMRGB_sync, 0); + STORERAMDAC(IBMRGB_hsync_pos, 0); + STORERAMDAC(IBMRGB_pwr_mgmt, 0); + STORERAMDAC(IBMRGB_dac_op, 0); + STORERAMDAC(IBMRGB_pal_ctrl, 0); + + break; + case IBM640_RAMDAC: + { + /* Get the programmable clock values */ + unsigned long m=0,n=0,p=0,c=0; + unsigned long clock; + + clock = IBMramdac640CalculateMNPCForClock(pGlint->RefClock, mode->Clock, + 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); + + STORERAMDAC(RGB640_PLL_N, n); + STORERAMDAC(RGB640_PLL_M, m); + STORERAMDAC(RGB640_PLL_P, p<<1); + STORERAMDAC(RGB640_PLL_CTL, c | IBM640_PLL_EN); + STORERAMDAC(RGB640_AUX_PLL_CTL, 0); /* Disable AUX PLL */ + } + STORERAMDAC(RGB640_PIXEL_INTERLEAVE, 0x00); + + temp1 = IBM640_RDBK | IBM640_VRAM; + if (pScrn->rgbBits == 8) + temp1 |= IBM640_PSIZE8; + STORERAMDAC(RGB640_VGA_CONTROL, temp1); + + STORERAMDAC(RGB640_DAC_CONTROL, IBM640_DACENBL | IBM640_SHUNT); + STORERAMDAC(RGB640_OUTPUT_CONTROL, IBM640_RDAI | IBM640_WATCTL); + STORERAMDAC(RGB640_SYNC_CONTROL, 0x00); + STORERAMDAC(RGB640_VRAM_MASK0, 0xFF); + STORERAMDAC(RGB640_VRAM_MASK1, 0xFF); + STORERAMDAC(RGB640_VRAM_MASK2, 0x0F); + + STOREREG(VTGModeCtl, 0x04); + break; + + case TI3026_RAMDAC: + case TI3030_RAMDAC: + { + /* Get the programmable clock values */ + unsigned long m=0,n=0,p=0; + unsigned long clock; + unsigned long q, VCO = 0; + + clock = TIramdacCalculateMNPForClock(pGlint->RefClock, + mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p); + + STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0)); + STORERAMDAC(TIDAC_PIXEL_M, (m & 0x3f)); + STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc)); + STORERAMDAC(TIDAC_PIXEL_VALID, TRUE); + + if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) + n = 65 - ((64 << 2) / pScrn->bitsPerPixel); + else + n = 65 - ((128 << 2) / pScrn->bitsPerPixel); + m = 61; + p = 0; + for (q = 0; q < 8; q++) { + if (q > 0) p = 3; + for ( ; p < 4; p++) { + VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1); + if (VCO >= 110000) { break; } + } + if (VCO >= 110000) { break; } + } + STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38)); + + STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0)); + STORERAMDAC(TIDAC_LOOP_M, (m & 0x3f)); + STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0)); + STORERAMDAC(TIDAC_LOOP_VALID, TRUE); + } + if (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) + STOREREG(VTGModeCtl, 0x04); + break; + } + + /* Now use helper routines to setup bpp for this driver */ + (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg); + + return(TRUE); +} + +void +TXSave(ScrnInfoPtr pScrn, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (pGlint->numMultiDevices == 2) { + SAVEREG(GCSRAperture); + } + + if (pGlint->MultiAperture) { + SAVEREG(GMultGLINTAperture); + SAVEREG(GMultGLINT1); + SAVEREG(GMultGLINT2); + } + + SAVEREG(Aperture0); + SAVEREG(Aperture1); + + SAVEREG(DFIFODis); + + if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) { + SAVEREG(FIFODis); + SAVEREG(VTGModeCtl); + } + + SAVEREG(VClkCtl); + SAVEREG(VTGPolarity); + SAVEREG(VTGHLimit); + SAVEREG(VTGHBlankEnd); + SAVEREG(VTGHSyncStart); + SAVEREG(VTGHSyncEnd); + SAVEREG(VTGVLimit); + SAVEREG(VTGVBlankEnd); + SAVEREG(VTGVSyncStart); + SAVEREG(VTGVSyncEnd); + SAVEREG(VTGVGateStart); + SAVEREG(VTGVGateEnd); + SAVEREG(VTGSerialClk); + SAVEREG(FBModeSel); + SAVEREG(VTGHGateStart); + SAVEREG(VTGHGateEnd); + SAVEREG(FBMemoryCtl); + + if (IS_GMX2000 || IS_GLORIAXXL) { + SAVEREG(LBMemoryEDO); + SAVEREG(LBMemoryCtl); + } +} + +void +TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (pGlint->numMultiDevices == 2) { + RESTOREREG(GCSRAperture); + } + + if (pGlint->MultiAperture) { + RESTOREREG(GMultGLINTAperture); + RESTOREREG(GMultGLINT1); + RESTOREREG(GMultGLINT2); + } + + RESTOREREG(Aperture0); + RESTOREREG(Aperture1); + + RESTOREREG(DFIFODis); + + if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) { + RESTOREREG(FIFODis); + RESTOREREG(VTGModeCtl); + } + + RESTOREREG(VTGPolarity); + RESTOREREG(VClkCtl); + RESTOREREG(VTGSerialClk); + RESTOREREG(VTGHLimit); + RESTOREREG(VTGHSyncStart); + RESTOREREG(VTGHSyncEnd); + RESTOREREG(VTGHBlankEnd); + RESTOREREG(VTGVLimit); + RESTOREREG(VTGVSyncStart); + RESTOREREG(VTGVSyncEnd); + RESTOREREG(VTGVBlankEnd); + RESTOREREG(VTGVGateStart); + RESTOREREG(VTGVGateEnd); + RESTOREREG(FBModeSel); + RESTOREREG(VTGHGateStart); + RESTOREREG(VTGHGateEnd); + RESTOREREG(FBMemoryCtl); + + if (IS_GMX2000 || IS_GLORIAXXL) { + RESTOREREG(LBMemoryEDO); + RESTOREREG(LBMemoryCtl); + } +} |