1301ea0f4Smrg
2301ea0f4Smrg/**************************************************************************
3301ea0f4Smrg
4301ea0f4SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5301ea0f4SmrgAll Rights Reserved.
6301ea0f4Smrg
7301ea0f4SmrgPermission is hereby granted, free of charge, to any person obtaining a
8301ea0f4Smrgcopy of this software and associated documentation files (the
9301ea0f4Smrg"Software"), to deal in the Software without restriction, including
10301ea0f4Smrgwithout limitation the rights to use, copy, modify, merge, publish,
11301ea0f4Smrgdistribute, sub license, and/or sell copies of the Software, and to
12301ea0f4Smrgpermit persons to whom the Software is furnished to do so, subject to
13301ea0f4Smrgthe following conditions:
14301ea0f4Smrg
15301ea0f4SmrgThe above copyright notice and this permission notice (including the
16301ea0f4Smrgnext paragraph) shall be included in all copies or substantial portions
17301ea0f4Smrgof the Software.
18301ea0f4Smrg
19301ea0f4SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20301ea0f4SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21301ea0f4SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22301ea0f4SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23301ea0f4SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24301ea0f4SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25301ea0f4SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26301ea0f4Smrg
27301ea0f4Smrg**************************************************************************/
28301ea0f4Smrg
29301ea0f4Smrg/*
30301ea0f4Smrg * Authors:
31301ea0f4Smrg *   Daryll Strauss <daryll@precisioninsight.com>
32301ea0f4Smrg *
33301ea0f4Smrg */
34301ea0f4Smrg
35301ea0f4Smrg#ifdef HAVE_CONFIG_H
36301ea0f4Smrg#include "config.h"
37301ea0f4Smrg#endif
38301ea0f4Smrg
39301ea0f4Smrg#include "xf86.h"
40301ea0f4Smrg#include "xf86_OSproc.h"
41301ea0f4Smrg#include "compiler.h"
42301ea0f4Smrg
43301ea0f4Smrg#include "xf86fbman.h"
44301ea0f4Smrg
45301ea0f4Smrg#include "vgaHW.h"
46301ea0f4Smrg#include "xf86xv.h"
47301ea0f4Smrg#include "i740.h"
48301ea0f4Smrg
49301ea0f4Smrgstatic void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
50301ea0f4Smrgstatic void I740ShowCursor(ScrnInfoPtr pScrn);
51301ea0f4Smrgstatic void I740HideCursor(ScrnInfoPtr pScrn);
52301ea0f4Smrgstatic void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
53301ea0f4Smrgstatic void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
54301ea0f4Smrgstatic Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
55301ea0f4Smrg
56301ea0f4SmrgBool
57301ea0f4SmrgI740CursorInit(ScreenPtr pScreen)
58301ea0f4Smrg{
59301ea0f4Smrg  ScrnInfoPtr pScrn;
60301ea0f4Smrg  I740Ptr pI740;
61301ea0f4Smrg  xf86CursorInfoPtr infoPtr;
62301ea0f4Smrg  FBAreaPtr fbarea;
63301ea0f4Smrg
64213fdd94Smrg  pScrn = xf86ScreenToScrn(pScreen);
65301ea0f4Smrg  pI740 = I740PTR(pScrn);
66301ea0f4Smrg  pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
67301ea0f4Smrg  if (!infoPtr) return FALSE;
68301ea0f4Smrg
69301ea0f4Smrg  infoPtr->MaxWidth = 64;
70301ea0f4Smrg  infoPtr->MaxHeight = 64;
71301ea0f4Smrg  infoPtr->Flags =  HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
72301ea0f4Smrg    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
73301ea0f4Smrg    HARDWARE_CURSOR_INVERT_MASK |
74301ea0f4Smrg    HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
75301ea0f4Smrg    HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
76301ea0f4Smrg    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
77301ea0f4Smrg
78301ea0f4Smrg  infoPtr->SetCursorColors = I740SetCursorColors;
79301ea0f4Smrg  infoPtr->SetCursorPosition = I740SetCursorPosition;
80301ea0f4Smrg  infoPtr->LoadCursorImage = I740LoadCursorImage;
81301ea0f4Smrg  infoPtr->HideCursor = I740HideCursor;
82301ea0f4Smrg  infoPtr->ShowCursor = I740ShowCursor;
83301ea0f4Smrg  infoPtr->UseHWCursor = I740UseHWCursor;
84301ea0f4Smrg
85301ea0f4Smrg/*
86301ea0f4Smrg * Allocate a region the full width and tall enough
87301ea0f4Smrg * that at least 6K of video memory is consumed.
88301ea0f4Smrg * Then use a 1 kilobyte piece that is 4K byte aligned
89301ea0f4Smrg * within that region. KAO.
90301ea0f4Smrg */
91301ea0f4Smrg  fbarea = xf86AllocateOffscreenArea(pScreen,
92301ea0f4Smrg				pScrn->displayWidth,
93301ea0f4Smrg				((6*1024)/(pScrn->displayWidth*pI740->cpp))+1,
94301ea0f4Smrg				0,0,0,0);
95301ea0f4Smrg  if (fbarea == NULL) {
96301ea0f4Smrg    pI740->CursorStart=0;
97301ea0f4Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
98301ea0f4Smrg	       "Hardware cursor disabled due to failure allocating offscreen memory.\n");
99301ea0f4Smrg  }
100301ea0f4Smrg  else {
101301ea0f4Smrg    pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000);
102301ea0f4Smrg  }
103301ea0f4Smrg  /*
104301ea0f4Smrg   * Perhaps move the cursor to the beginning of the frame buffer
105301ea0f4Smrg   * so that it never fails?
106301ea0f4Smrg   */
107301ea0f4Smrg  if (pI740->CursorStart>4*1024*1024) {
108301ea0f4Smrg    pI740->CursorStart=0;
109301ea0f4Smrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
110301ea0f4Smrg	       "Disabling hardware cursor due to large framebuffer\n");
111301ea0f4Smrg  }
112301ea0f4Smrg  return xf86InitCursor(pScreen, infoPtr);
113301ea0f4Smrg}
114301ea0f4Smrg
115301ea0f4Smrgstatic Bool
116301ea0f4SmrgI740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
117301ea0f4Smrg  ScrnInfoPtr pScrn;
118301ea0f4Smrg  I740Ptr pI740;
119301ea0f4Smrg
120213fdd94Smrg  pScrn = xf86ScreenToScrn(pScreen);
121301ea0f4Smrg  pI740 = I740PTR(pScrn);
122301ea0f4Smrg  if (pScrn->currentMode->Flags&V_DBLSCAN)
123301ea0f4Smrg    return FALSE;
124301ea0f4Smrg  if (!pI740->CursorStart) return FALSE;
125301ea0f4Smrg  return TRUE;
126301ea0f4Smrg}
127301ea0f4Smrg
128301ea0f4Smrgstatic void
129301ea0f4SmrgI740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) {
130301ea0f4Smrg  I740Ptr pI740;
131301ea0f4Smrg  int x, y;
132301ea0f4Smrg  CARD8 *pcurs;
133301ea0f4Smrg
134301ea0f4Smrg  pI740 = I740PTR(pScrn);
135301ea0f4Smrg  pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart);
136301ea0f4Smrg  for (y = 0; y < 64; y++) {
137301ea0f4Smrg    for (x = 0; x < 64 / 4; x++) {
138301ea0f4Smrg      *pcurs++ = *src++;
139301ea0f4Smrg    }
140301ea0f4Smrg  }
141301ea0f4Smrg}
142301ea0f4Smrg
143301ea0f4Smrgstatic void
144301ea0f4SmrgI740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
145301ea0f4Smrg  I740Ptr pI740;
146301ea0f4Smrg  int flag;
147301ea0f4Smrg
148301ea0f4Smrg  pI740 = I740PTR(pScrn);
149301ea0f4Smrg  if (x >= 0) flag = CURSOR_X_POS;
150301ea0f4Smrg  else {
151301ea0f4Smrg    flag = CURSOR_X_NEG;
152301ea0f4Smrg    x=-x;
153301ea0f4Smrg  }
154301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF);
155301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
156301ea0f4Smrg
157301ea0f4Smrg  if (y >= 0) flag = CURSOR_Y_POS;
158301ea0f4Smrg  else {
159301ea0f4Smrg    flag = CURSOR_Y_NEG;
160301ea0f4Smrg    y=-y;
161301ea0f4Smrg  }
162301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF);
163301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
164301ea0f4Smrg}
165301ea0f4Smrg
166301ea0f4Smrgstatic void
167301ea0f4SmrgI740ShowCursor(ScrnInfoPtr pScrn) {
168301ea0f4Smrg  I740Ptr pI740;
169301ea0f4Smrg  unsigned char tmp;
170301ea0f4Smrg
171301ea0f4Smrg  pI740 = I740PTR(pScrn);
172301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO,
173301ea0f4Smrg		      (pI740->CursorStart & 0x0000F000) >> 8);
174301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI,
175301ea0f4Smrg		      (pI740->CursorStart & 0x003F0000) >> 16);
176301ea0f4Smrg  pI740->writeControl(pI740, XRX, CURSOR_CONTROL,
177301ea0f4Smrg		      CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
178301ea0f4Smrg
179301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
180301ea0f4Smrg  tmp |= HW_CURSOR_ENABLE;
181301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
182301ea0f4Smrg}
183301ea0f4Smrg
184301ea0f4Smrgstatic void
185301ea0f4SmrgI740HideCursor(ScrnInfoPtr pScrn) {
186301ea0f4Smrg  unsigned char tmp;
187301ea0f4Smrg  I740Ptr pI740;
188301ea0f4Smrg
189301ea0f4Smrg  pI740 = I740PTR(pScrn);
190301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
191301ea0f4Smrg  tmp &= ~HW_CURSOR_ENABLE;
192301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
193301ea0f4Smrg}
194301ea0f4Smrg
195301ea0f4Smrgstatic void
196301ea0f4SmrgI740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
197301ea0f4Smrg  int tmp;
198301ea0f4Smrg  I740Ptr pI740;
199301ea0f4Smrg
200301ea0f4Smrg  pI740 = I740PTR(pScrn);
201301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
202301ea0f4Smrg  tmp |= EXTENDED_PALETTE;
203301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
204301ea0f4Smrg
205301ea0f4Smrg  pI740->writeStandard(pI740, DACMASK, 0xFF);
206301ea0f4Smrg  pI740->writeStandard(pI740, DACWX, 0x04);
207301ea0f4Smrg
208301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16);
209301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8);
210301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF));
211301ea0f4Smrg
212301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16);
213301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8);
214301ea0f4Smrg  pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF));
215301ea0f4Smrg
216301ea0f4Smrg  tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
217301ea0f4Smrg  tmp &= ~EXTENDED_PALETTE;
218301ea0f4Smrg  pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
219301ea0f4Smrg}
220301ea0f4Smrg
221301ea0f4Smrg
222301ea0f4Smrg
223