abort on Init table command not found when parsing bios
[nouveau] / src / nv_cursor.c
1  /***************************************************************************\
2 |*                                                                           *|
3 |*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
4 |*                                                                           *|
5 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
6 |*     international laws.  Users and possessors of this source code are     *|
7 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
8 |*     use this code in individual and commercial software.                  *|
9 |*                                                                           *|
10 |*     Any use of this source code must include,  in the user documenta-     *|
11 |*     tion and  internal comments to the code,  notices to the end user     *|
12 |*     as follows:                                                           *|
13 |*                                                                           *|
14 |*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
15 |*                                                                           *|
16 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
17 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
18 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
19 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
20 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
21 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
22 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
23 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
24 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
25 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
26 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
27 |*                                                                           *|
28 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
29 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
30 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
31 |*     computer  software  documentation,"  as such  terms  are  used in     *|
32 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
33 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
34 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
35 |*     all U.S. Government End Users  acquire the source code  with only     *|
36 |*     those rights set forth herein.                                        *|
37 |*                                                                           *|
38  \***************************************************************************/
39
40 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.13 2004/03/13 22:07:05 mvojkovi Exp $ */
41
42 #include "nv_include.h"
43
44 #include "cursorstr.h"
45
46 /****************************************************************************\
47 *                                                                            *
48 *                          HW Cursor Entrypoints                             *
49 *                                                                            *
50 \****************************************************************************/
51
52 #define NV_CURSOR_X 64
53 #define NV_CURSOR_Y 64
54
55 #define CURSOR_X_SHIFT 0
56 #define CURSOR_Y_SHIFT 16
57 #define CURSOR_POS_MASK 0xffff
58
59 #define TRANSPARENT_PIXEL   0
60
61 #define ConvertToRGB555(c)  (((c & 0xf80000) >> 9 ) | /* Blue  */           \
62                             ((c & 0xf800) >> 6 )    | /* Green */           \
63                             ((c & 0xf8) >> 3 )      | /* Red   */           \
64                             0x8000)                   /* Set upper bit, else we get complete transparency. */
65
66 #define ConvertToRGB888(c) (c | 0xff000000)
67
68 #define BYTE_SWAP_32(c)  ((c & 0xff000000) >> 24) |  \
69                          ((c & 0xff0000) >> 8) |     \
70                          ((c & 0xff00) << 8) |       \
71                          ((c & 0xff) << 24)
72
73 /* Limit non-alpha cursors to 32x32 (x2 bytes) */
74 #define MAX_CURSOR_SIZE 32
75
76 /* Limit alpha cursors to 32x32 (x4 bytes) */
77 #define MAX_CURSOR_SIZE_ALPHA (MAX_CURSOR_SIZE * 2)
78
79 static void 
80 ConvertCursor1555(NVPtr pNv, CARD32 *src, CARD16 *dst)
81 {
82     CARD32 b, m;
83     int i, j;
84     
85     for ( i = 0; i < MAX_CURSOR_SIZE; i++ ) {
86         b = *src++;
87         m = *src++;
88         for ( j = 0; j < MAX_CURSOR_SIZE; j++ ) {
89 #if X_BYTE_ORDER == X_BIG_ENDIAN
90             if ( m & 0x80000000)
91                 *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
92             else
93                 *dst = TRANSPARENT_PIXEL;
94             b <<= 1;
95             m <<= 1;
96 #else
97             if ( m & 1 )
98                 *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
99             else
100                 *dst = TRANSPARENT_PIXEL;
101             b >>= 1;
102             m >>= 1;
103 #endif
104             dst++;
105         }
106     }
107 }
108
109
110 static void
111 ConvertCursor8888(NVPtr pNv, CARD32 *src, CARD32 *dst)
112 {
113     CARD32 b, m;
114     int i, j;
115    
116     /* Iterate over each byte in the cursor. */
117     for ( i = 0; i < MAX_CURSOR_SIZE * 4; i++ ) {
118         b = *src++;
119         m = *src++;
120         for ( j = 0; j < MAX_CURSOR_SIZE; j++ ) {
121 #if X_BYTE_ORDER == X_BIG_ENDIAN
122             if ( m & 0x80000000)
123                 *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
124             else
125                 *dst = TRANSPARENT_PIXEL;
126             b <<= 1;
127             m <<= 1;
128 #else
129             if ( m & 1 )
130                 *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
131             else
132                 *dst = TRANSPARENT_PIXEL;
133             b >>= 1;
134             m >>= 1;
135 #endif
136             dst++;
137         }
138     }
139 }
140
141
142 static void
143 TransformCursor (NVPtr pNv)
144 {
145     CARD32 *tmp;
146     int i, dwords;
147
148     /* convert to color cursor */
149     if(pNv->alphaCursor) {
150        dwords = MAX_CURSOR_SIZE_ALPHA * MAX_CURSOR_SIZE_ALPHA;
151        if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
152        ConvertCursor8888(pNv, pNv->curImage, tmp);
153     } else {
154        dwords = (MAX_CURSOR_SIZE * MAX_CURSOR_SIZE) >> 1;
155        if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
156        ConvertCursor1555(pNv, pNv->curImage, (CARD16*)tmp);
157     }
158
159     for(i = 0; i < dwords; i++)
160         pNv->CURSOR[i] = tmp[i];
161
162     DEALLOCATE_LOCAL(tmp);
163 }
164
165 static void
166 NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
167 {
168     NVPtr pNv = NVPTR(pScrn);
169
170     /* save copy of image for color changes */
171     memcpy(pNv->curImage, src, (pNv->alphaCursor) ? 1024 : 256);
172
173     TransformCursor(pNv);
174 }
175
176 static void
177 NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
178 {
179         NVPtr pNv = NVPTR(pScrn);
180         nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, (x & 0xFFFF) | (y << 16));
181 }
182
183 static void
184 NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
185 {
186     NVPtr pNv = NVPTR(pScrn);
187     CARD32 fore, back;
188
189     if(pNv->alphaCursor) {
190         fore = ConvertToRGB888(fg);
191         back = ConvertToRGB888(bg);
192 #if X_BYTE_ORDER == X_BIG_ENDIAN
193         if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
194            fore = BYTE_SWAP_32(fore);
195            back = BYTE_SWAP_32(back);
196         }
197 #endif
198     } else {
199         fore = ConvertToRGB555(fg);
200         back = ConvertToRGB555(bg);
201 #if X_BYTE_ORDER == X_BIG_ENDIAN
202         if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
203            fore = ((fore & 0xff) << 8) | (fore >> 8);
204            back = ((back & 0xff) << 8) | (back >> 8);
205         }
206 #endif
207    }
208
209     if ((pNv->curFg != fore) || (pNv->curBg != back)) {
210         pNv->curFg = fore;
211         pNv->curBg = back;
212             
213         TransformCursor(pNv);
214     }
215 }
216
217
218 static void 
219 NVShowCursor(ScrnInfoPtr pScrn)
220 {
221         NVPtr pNv = NVPTR(pScrn);
222         /* Enable cursor - X-Windows mode */
223         NVShowHideCursor(pNv, 1);
224 }
225
226 static void
227 NVHideCursor(ScrnInfoPtr pScrn)
228 {
229         NVPtr pNv = NVPTR(pScrn);
230         /* Disable cursor */
231         NVShowHideCursor(pNv, 0);
232 }
233
234 static Bool 
235 NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
236 {
237         return TRUE;
238 }
239
240 #ifdef ARGB_CURSOR
241 static Bool 
242 NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
243 {
244     if((pCurs->bits->width <= MAX_CURSOR_SIZE_ALPHA) && (pCurs->bits->height <= MAX_CURSOR_SIZE_ALPHA))
245         return TRUE;
246
247     return FALSE;
248 }
249
250 static void
251 NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
252 {
253     NVPtr pNv = NVPTR(pScrn);
254     CARD32 *image = pCurs->bits->argb;
255     CARD32 *dst = (CARD32*)pNv->CURSOR;
256     CARD32 alpha, tmp;
257     int x, y, w, h;
258
259     w = pCurs->bits->width;
260     h = pCurs->bits->height;
261
262     if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {  /* premultiply */
263        for(y = 0; y < h; y++) {
264           for(x = 0; x < w; x++) {
265              alpha = *image >> 24;
266              if(alpha == 0xff)
267                 tmp = *image;
268              else {
269                 tmp = (alpha << 24) |
270                          (((*image & 0xff) * alpha) / 255) |
271                         ((((*image & 0xff00) * alpha) / 255) & 0xff00) |
272                        ((((*image & 0xff0000) * alpha) / 255) & 0xff0000); 
273              }
274              image++;
275 #if X_BYTE_ORDER == X_BIG_ENDIAN
276              *dst++ = BYTE_SWAP_32(tmp);
277 #else
278              *dst++ = tmp;
279 #endif
280          }
281          for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
282              *dst++ = 0;
283       }
284     } else {
285        for(y = 0; y < h; y++) {
286           for(x = 0; x < w; x++)
287               *dst++ = *image++;
288           for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
289               *dst++ = 0;
290        }
291     }
292
293     if(y < MAX_CURSOR_SIZE_ALPHA)
294       memset(dst, 0, MAX_CURSOR_SIZE_ALPHA * (MAX_CURSOR_SIZE_ALPHA - y) * 4);
295 }
296 #endif
297
298 Bool 
299 NVCursorInit(ScreenPtr pScreen)
300 {
301     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
302     NVPtr pNv = NVPTR(pScrn);
303     xf86CursorInfoPtr infoPtr;
304
305     infoPtr = xf86CreateCursorInfoRec();
306     if(!infoPtr) return FALSE;
307     
308     pNv->CursorInfoRec = infoPtr;
309
310     if(pNv->alphaCursor)
311        infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE_ALPHA;
312     else
313        infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE;
314
315     infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
316                      HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32; 
317     infoPtr->SetCursorColors = NVSetCursorColors;
318     infoPtr->SetCursorPosition = NVSetCursorPosition;
319     infoPtr->LoadCursorImage = NVLoadCursorImage;
320     infoPtr->HideCursor = NVHideCursor;
321     infoPtr->ShowCursor = NVShowCursor;
322     infoPtr->UseHWCursor = NVUseHWCursor;
323
324 #ifdef ARGB_CURSOR
325     if(pNv->alphaCursor) {
326        infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
327        infoPtr->LoadCursorARGB = NVLoadCursorARGB;
328     }
329 #endif
330
331     return(xf86InitCursor(pScreen, infoPtr));
332 }
333
334 #ifdef ENABLE_RANDR12
335
336 #define CURSOR_PTR ((CARD32*)pNv->Cursor->map)
337
338 Bool NVCursorInitRandr12(ScreenPtr pScreen)
339 {
340         ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
341         NVPtr pNv = NVPTR(pScrn);
342         int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
343                         HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
344         int cursor_size = 0;
345         if (pNv->alphaCursor) { /* >= NV11 */
346                 cursor_size = MAX_CURSOR_SIZE_ALPHA;
347                 flags |= HARDWARE_CURSOR_ARGB;
348         } else {
349                 cursor_size = MAX_CURSOR_SIZE;
350         }
351         return xf86_cursors_init(pScreen, cursor_size, cursor_size, flags);
352 }
353
354 void nv_crtc_show_cursor(xf86CrtcPtr crtc)
355 {
356         int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1) | 1;
357         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
358 }
359
360 void nv_crtc_hide_cursor(xf86CrtcPtr crtc)
361 {
362         int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1) & ~1;
363         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
364 }
365
366 void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
367 {
368         ScrnInfoPtr pScrn = crtc->scrn;
369         NVPtr pNv = NVPTR(pScrn);
370         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
371         xf86OutputPtr output = NULL;
372         int i;
373
374         /* We need our output, so we know our ramdac */
375         for (i = 0; i < xf86_config->num_output; i++) {
376                 output = xf86_config->output[i];
377
378                 if (output->crtc == crtc) {
379                         /* TODO: Add a check if an output was found? */
380                         break;
381                 }
382         }
383
384         NVOutputWriteRAMDAC(output, NV_RAMDAC_CURSOR_POS, ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | (y << CURSOR_Y_SHIFT));
385 }
386
387 void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
388 {
389         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
390         ScrnInfoPtr pScrn = crtc->scrn;
391         NVPtr pNv = NVPTR(pScrn);
392         CARD32 fore, back;
393
394         if(pNv->alphaCursor) {
395                 fore = ConvertToRGB888(fg);
396                 back = ConvertToRGB888(bg);
397 #if X_BYTE_ORDER == X_BIG_ENDIAN
398                 if(pNv->NVArch == 0x11) {
399                         fore = BYTE_SWAP_32(fore);
400                         back = BYTE_SWAP_32(back);
401                 }
402 #endif
403         } else {
404                 fore = ConvertToRGB555(fg);
405                 back = ConvertToRGB555(bg);
406 #if X_BYTE_ORDER == X_BIG_ENDIAN
407                 if(pNv->NVArch == 0x11) {
408                         fore = ((fore & 0xff) << 8) | (fore >> 8);
409                         back = ((back & 0xff) << 8) | (back >> 8);
410                 }
411 #endif
412         }
413
414         /* Eventually this must be replaced as well */
415         if ((pNv->curFg != fore) || (pNv->curBg != back)) {
416                 pNv->curFg = fore;
417                 pNv->curBg = back;
418                 TransformCursor(pNv);
419         }
420 }
421
422
423
424 void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
425 {
426         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
427         ScrnInfoPtr pScrn = crtc->scrn;
428         NVPtr pNv = NVPTR(pScrn);
429
430         /* save copy of image for color changes */
431         memcpy(pNv->curImage, image, 256);
432
433         /* Eventually this has to be replaced as well */
434         TransformCursor(pNv);
435 }
436
437 void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
438 {
439         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
440         ScrnInfoPtr pScrn = crtc->scrn;
441         NVPtr pNv = NVPTR(pScrn);
442
443         /* Copy the cursor straight into the right registers */
444         memcpy(CURSOR_PTR, image, 16384);
445 }
446
447 #endif /* ENABLE_RANDR12 */