1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrjälä <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 #include <config.h>
30 
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 
35 #include <fbdev/fb.h>
36 
37 #include <sys/mman.h>
38 #include <fcntl.h>
39 #include <sys/ioctl.h>
40 
41 #include <directfb.h>
42 
43 #include <fusion/shmalloc.h>
44 
45 #include <core/coredefs.h>
46 #include <core/coretypes.h>
47 
48 #include <core/state.h>
49 #include <core/gfxcard.h>
50 #include <core/windows.h>
51 #include <core/layers.h>
52 #include <core/screens.h>
53 #include <core/surface.h>
54 
55 #include <gfx/convert.h>
56 
57 #include <core/graphics_driver.h>
58 
59 DFB_GRAPHICS_DRIVER( cyber5k )
60 
61 #include "regs.h"
62 #include "mmio.h"
63 #include "cyber5k.h"
64 #include "cyber5k_alpha.h"
65 
66 
67 /* HACK */
68 volatile u8 *cyber_mmio = NULL;
69 
70 
71 /* FIXME: support for destination color keying */
72 
73 #define CYBER5K_DRAWING_FLAGS \
74                (DSDRAW_NOFX)
75 
76 #define CYBER5K_DRAWING_FUNCTIONS \
77                (DFXL_DRAWLINE | DFXL_DRAWRECTANGLE | DFXL_FILLRECTANGLE)
78 
79 #define CYBER5K_BLITTING_FLAGS \
80                (DSBLIT_SRC_COLORKEY)
81 
82 #define CYBER5K_BLITTING_FUNCTIONS \
83                (DFXL_BLIT)
84 
85 static bool cyber5kFillRectangle( void *drv, void *dev, DFBRectangle *rect );
86 static bool cyber5kFillRectangle24( void *drv, void *dev, DFBRectangle *rect );
87 static bool cyber5kDrawRectangle( void *drv, void *dev, DFBRectangle *rect );
88 static bool cyber5kDrawRectangle24( void *drv, void *dev, DFBRectangle *rect );
89 static bool cyber5kBlit( void *drv, void *dev,
90                          DFBRectangle *rect, int dx, int dy );
91 static bool cyber5kBlit24( void *drv, void *dev,
92                            DFBRectangle *rect, int dx, int dy );
93 
cyber5kEngineSync(void * drv,void * dev)94 static DFBResult cyber5kEngineSync( void *drv, void *dev )
95 {
96      CyberDriverData *cdrv = (CyberDriverData*) drv;
97      CyberDeviceData *cdev = (CyberDeviceData*) dev;
98 
99      cyber_waitidle( cdrv, cdev );
100 
101      return DFB_OK;
102 }
103 
cyber5kCheckState(void * drv,void * dev,CardState * state,DFBAccelerationMask accel)104 static void cyber5kCheckState( void *drv, void *dev,
105                                CardState *state, DFBAccelerationMask accel )
106 {
107      /* check destination format first */
108      switch (state->destination->config.format) {
109           case DSPF_RGB16:
110           case DSPF_RGB24:
111           case DSPF_RGB32:
112           case DSPF_ARGB:
113                break;
114           default:
115                return;
116      }
117 
118      if (DFB_DRAWING_FUNCTION( accel )) {
119           /* if there are no other drawing flags than the supported */
120           if (state->drawingflags & ~CYBER5K_DRAWING_FLAGS)
121                return;
122 
123           state->accel |= CYBER5K_DRAWING_FUNCTIONS;
124 
125           /* no line drawing in 24bit mode */
126           if (state->destination->config.format == DSPF_RGB24)
127                state->accel &= ~DFXL_DRAWLINE;
128      }
129      else {
130           /* if there are no other blitting flags than the supported
131              and the source and destination formats are the same */
132           if (state->blittingflags & ~CYBER5K_BLITTING_FLAGS)
133                return;
134           if (state->source->config.format != state->destination->config.format)
135                return;
136 
137           state->accel |= CYBER5K_BLITTING_FUNCTIONS;
138      }
139 }
140 
141 static inline void
cyber5k_validate_dst(CyberDriverData * cdrv,CyberDeviceData * cdev,CardState * state,GraphicsDeviceFuncs * funcs)142 cyber5k_validate_dst( CyberDriverData *cdrv, CyberDeviceData *cdev,
143                       CardState *state, GraphicsDeviceFuncs *funcs )
144 {
145      CoreSurface   *dest   = state->destination;
146 
147      if (cdev->v_dst)
148           return;
149 
150      cdev->dst_pixeloffset = state->dst.offset /
151                              DFB_BYTES_PER_PIXEL(dest->config.format);
152      cdev->dst_pixelpitch  = state->dst.pitch /
153                              DFB_BYTES_PER_PIXEL(dest->config.format);
154 
155      switch (dest->config.format) {
156           case DSPF_RGB16:
157                funcs->FillRectangle = cyber5kFillRectangle;
158                funcs->DrawRectangle = cyber5kDrawRectangle;
159                funcs->Blit          = cyber5kBlit;
160                cyber_out16( cdrv->mmio_base, DSTWIDTH, cdev->dst_pixelpitch - 1 );
161                cyber_out8( cdrv->mmio_base, COPFMT, 1 );
162                break;
163           case DSPF_RGB24:
164                funcs->FillRectangle = cyber5kFillRectangle24;
165                funcs->DrawRectangle = cyber5kDrawRectangle24;
166                funcs->Blit          = cyber5kBlit24;
167                cyber_out16( cdrv->mmio_base, DSTWIDTH, cdev->dst_pixelpitch*3 -1);
168                cyber_out8( cdrv->mmio_base, COPFMT, 2 );
169                break;
170           case DSPF_RGB32:
171           case DSPF_ARGB:
172                funcs->FillRectangle = cyber5kFillRectangle;
173                funcs->DrawRectangle = cyber5kDrawRectangle;
174                funcs->Blit          = cyber5kBlit;
175                cyber_out16( cdrv->mmio_base, DSTWIDTH, cdev->dst_pixelpitch - 1 );
176                cyber_out8( cdrv->mmio_base, COPFMT, 3 );
177                break;
178           default:
179                D_BUG( "unexpected pixelformat!" );
180                break;
181      }
182 
183      cdev->v_dst = 1;
184 }
185 
186 static inline void
cyber5k_validate_src(CyberDriverData * cdrv,CyberDeviceData * cdev,CardState * state)187 cyber5k_validate_src( CyberDriverData *cdrv,
188                       CyberDeviceData *cdev, CardState *state )
189 {
190      CoreSurface   *source = state->source;
191 
192      if (cdev->v_src)
193           return;
194 
195      cdev->src_pixeloffset = state->src.offset /
196                              DFB_BYTES_PER_PIXEL(source->config.format);
197      cdev->src_pixelpitch  = state->src.pitch /
198                              DFB_BYTES_PER_PIXEL(source->config.format);
199 
200      cyber_out16( cdrv->mmio_base, SRC1WIDTH,
201                   state->src.pitch /DFB_BYTES_PER_PIXEL(source->config.format) - 1);
202 
203      cdev->v_src = 1;
204 }
205 
206 static inline void
cyber5k_validate_color(CyberDriverData * cdrv,CyberDeviceData * cdev,CardState * state)207 cyber5k_validate_color( CyberDriverData *cdrv,
208                         CyberDeviceData *cdev, CardState *state )
209 {
210      u32 fill_color = 0;
211 
212      if (cdev->v_color)
213           return;
214 
215      switch (state->destination->config.format) {
216           case DSPF_RGB16:
217                fill_color = PIXEL_RGB16( state->color.r,
218                                          state->color.g,
219                                          state->color.b );
220                break;
221           case DSPF_RGB24:
222           case DSPF_RGB32:
223                fill_color = PIXEL_RGB32( state->color.r,
224                                          state->color.g,
225                                          state->color.b );
226                break;
227           case DSPF_ARGB:
228                fill_color = PIXEL_ARGB( state->color.a,
229                                         state->color.r,
230                                         state->color.g,
231                                         state->color.b );
232                break;
233           default:
234                D_BUG( "unexpected pixelformat!" );
235                break;
236      }
237 
238      cyber_out32( cdrv->mmio_base, FCOLOR, fill_color );
239 
240      cdev->v_src_colorkey = 0;
241 
242      cdev->v_color = 1;
243 }
244 
245 static inline void
cyber5k_validate_src_colorkey(CyberDriverData * cdrv,CyberDeviceData * cdev,CardState * state)246 cyber5k_validate_src_colorkey( CyberDriverData *cdrv,
247                                CyberDeviceData *cdev, CardState *state )
248 {
249      if (cdev->v_src_colorkey)
250           return;
251 
252      cyber_out32( cdrv->mmio_base, FCOLOR, state->src_colorkey );
253      cyber_out32( cdrv->mmio_base, BCOLOR, state->src_colorkey );
254 
255      cdev->v_color = 0;
256 
257      cdev->v_src_colorkey = 1;
258 }
259 
260 static inline void
cyber5k_validate_blitting_cmd(CyberDriverData * cdrv,CyberDeviceData * cdev,CardState * state)261 cyber5k_validate_blitting_cmd( CyberDriverData *cdrv,
262                                CyberDeviceData *cdev, CardState *state )
263 {
264      if (cdev->v_blitting_cmd)
265           return;
266 
267      cdev->blitting_cmd = COP_PXBLT | PAT_FIXFGD | FGD_IS_SRC1;
268 
269      if (state->blittingflags & DSBLIT_SRC_COLORKEY)
270           cdev->blitting_cmd |= TRANS_ENABLE | TRANS_IS_SRC1 | TRANS_INVERT;
271 
272      cdev->v_blitting_cmd = 1;
273 }
274 
cyber5kSetState(void * drv,void * dev,GraphicsDeviceFuncs * funcs,CardState * state,DFBAccelerationMask accel)275 static void cyber5kSetState( void *drv, void *dev, GraphicsDeviceFuncs *funcs,
276                              CardState *state, DFBAccelerationMask accel )
277 {
278      CyberDriverData *cdrv = (CyberDriverData*) drv;
279      CyberDeviceData *cdev = (CyberDeviceData*) dev;
280 
281      if (state->mod_hw) {
282           if (state->mod_hw & SMF_DESTINATION)
283                cdev->v_dst = cdev->v_color = 0;
284           else if (state->mod_hw & SMF_COLOR)
285                cdev->v_color = 0;
286 
287           if (state->mod_hw & SMF_SOURCE)
288                cdev->v_src = cdev->v_src_colorkey = 0;
289           else if (state->mod_hw & SMF_SRC_COLORKEY)
290                cdev->v_src_colorkey = 0;
291 
292           if (state->mod_hw & SMF_BLITTING_FLAGS)
293                cdev->v_blitting_cmd = 0;
294      }
295 
296      cyber5k_validate_dst( cdrv, cdev, state, funcs );
297 
298      switch (accel) {
299           case DFXL_DRAWLINE:
300           case DFXL_DRAWRECTANGLE:
301           case DFXL_FILLRECTANGLE:
302                cyber5k_validate_color( cdrv, cdev, state );
303 
304                state->set = CYBER5K_DRAWING_FUNCTIONS;
305                break;
306 
307           case DFXL_BLIT:
308                cyber5k_validate_src( cdrv, cdev, state );
309                cyber5k_validate_blitting_cmd( cdrv, cdev, state );
310 
311                if (state->blittingflags & DSBLIT_SRC_COLORKEY)
312                     cyber5k_validate_src_colorkey( cdrv, cdev, state );
313 
314                state->set = CYBER5K_BLITTING_FUNCTIONS;
315                break;
316 
317           default:
318                D_BUG( "unexpected drawing/blitting function!" );
319                break;
320      }
321 
322      state->mod_hw = 0;
323 }
324 
cyber5kFillRectangle(void * drv,void * dev,DFBRectangle * rect)325 static bool cyber5kFillRectangle( void *drv, void *dev, DFBRectangle *rect )
326 {
327      CyberDriverData *cdrv = (CyberDriverData*) drv;
328      CyberDeviceData *cdev = (CyberDeviceData*) dev;
329      volatile u8     *mmio = cdrv->mmio_base;
330 
331      cyber_waitidle( cdrv, cdev );
332 
333      cyber_out32( mmio, DSTPTR, cdev->dst_pixeloffset +
334                   rect->y * cdev->dst_pixelpitch +
335                   rect->x );
336 
337      cyber_out32( mmio, HEIGHTWIDTH, ((rect->h-1) << 16) | (rect->w-1) );
338      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
339 
340      return true;
341 }
342 
cyber5kFillRectangle24(void * drv,void * dev,DFBRectangle * rect)343 static bool cyber5kFillRectangle24( void *drv, void *dev, DFBRectangle *rect )
344 {
345      CyberDriverData *cdrv = (CyberDriverData*) drv;
346      CyberDeviceData *cdev = (CyberDeviceData*) dev;
347      volatile u8     *mmio = cdrv->mmio_base;
348 
349      cyber_waitidle( cdrv, cdev );
350 
351      cyber_out32( mmio, DSTPTR, (cdev->dst_pixeloffset +
352                                  rect->y * cdev->dst_pixelpitch +
353                                  rect->x) * 3 );
354      cyber_out8( mmio, DSTXROT, rect->x & 7 );
355 
356      cyber_out32( mmio, HEIGHTWIDTH, ((rect->h-1) << 16) | (rect->w-1) );
357      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
358 
359      return true;
360 }
361 
cyber5kDrawRectangle(void * drv,void * dev,DFBRectangle * rect)362 static bool cyber5kDrawRectangle( void *drv, void *dev, DFBRectangle *rect )
363 {
364      CyberDriverData *cdrv = (CyberDriverData*) drv;
365      CyberDeviceData *cdev = (CyberDeviceData*) dev;
366      volatile u8     *mmio = cdrv->mmio_base;
367 
368      u32 dst = cdev->dst_pixeloffset +
369                rect->y * cdev->dst_pixelpitch + rect->x;
370 
371      cyber_waitidle( cdrv, cdev );
372      cyber_out32( mmio, DSTPTR, dst );
373      cyber_out32( mmio, DIMW, 0 );
374      cyber_out32( mmio, DIMH, rect->h - 1 );
375      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
376 
377      cyber_waitidle( cdrv, cdev );
378      cyber_out32( mmio, DSTPTR, dst + rect->w - 1);
379      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
380 
381      cyber_waitidle( cdrv, cdev );
382      cyber_out32( mmio, DSTPTR, dst );
383      cyber_out32( mmio, DIMW, rect->w - 1 );
384      cyber_out32( mmio, DIMH, 0 );
385      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
386 
387      cyber_waitidle( cdrv, cdev );
388      cyber_out32( mmio, DSTPTR, dst + cdev->dst_pixelpitch * (rect->h - 1) );
389      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
390 
391      return true;
392 }
393 
cyber5kDrawRectangle24(void * drv,void * dev,DFBRectangle * rect)394 static bool cyber5kDrawRectangle24( void *drv, void *dev, DFBRectangle *rect )
395 {
396      CyberDriverData *cdrv = (CyberDriverData*) drv;
397      CyberDeviceData *cdev = (CyberDeviceData*) dev;
398      volatile u8     *mmio = cdrv->mmio_base;
399 
400      u32 dst = cdev->dst_pixeloffset +
401                (rect->y * cdev->dst_pixelpitch + rect->x) * 3;
402 
403      cyber_waitidle( cdrv, cdev );
404      cyber_out8( mmio, DSTXROT, rect->x & 7 );
405      cyber_out32( mmio, DSTPTR, dst );
406      cyber_out32( mmio, DIMW, rect->w - 1 );
407      cyber_out32( mmio, DIMH, 0 );
408      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
409 
410      cyber_waitidle( cdrv, cdev );
411      cyber_out32( mmio, DSTPTR, dst + cdev->dst_pixelpitch * (rect->h-1) * 3 );
412      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
413 
414      cyber_waitidle( cdrv, cdev );
415      cyber_out32( mmio, DSTPTR, dst );
416      cyber_out32( mmio, DIMW, 0 );
417      cyber_out32( mmio, DIMH, rect->h - 1 );
418      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
419 
420      cyber_waitidle( cdrv, cdev );
421      cyber_out8( mmio, DSTXROT, (rect->x + rect->w - 1) & 7 );
422      cyber_out32( mmio, DSTPTR, dst + (rect->w-1) * 3 );
423      cyber_out32( mmio, PIXOP, COP_PXBLT | PAT_FIXFGD );
424 
425      return true;
426 }
427 
cyber5kDrawLine(void * drv,void * dev,DFBRegion * line)428 static bool cyber5kDrawLine( void *drv, void *dev, DFBRegion *line )
429 {
430      CyberDriverData *cdrv = (CyberDriverData*) drv;
431      CyberDeviceData *cdev = (CyberDeviceData*) dev;
432      volatile u8     *mmio = cdrv->mmio_base;
433 
434      u32 cmd = COP_LINE_DRAW | PAT_FIXFGD;
435 
436      int dx;
437      int dy;
438 
439      dx = line->x2 - line->x1;
440      dy = line->y2 - line->y1;
441 
442      if (dx < 0) {
443           dx = -dx;
444           cmd |= DX_NEG;
445      }
446      if (dy < 0) {
447           dy = -dy;
448           cmd |= DY_NEG;
449      }
450      if (dx < dy) {
451           int tmp;
452           cmd |= YMAJOR;
453           tmp = dx;
454           dx = dy;
455           dy = tmp;
456      }
457 
458      cyber_waitidle( cdrv, cdev );
459      cyber_out32( mmio, DSTPTR,
460                   cdev->dst_pixeloffset +
461                   line->y1 * cdev->dst_pixelpitch + line->x1);
462 
463      cyber_out16( mmio, DIMW          , dx);
464      cyber_out16( mmio, K1          , 2*dy);
465      cyber_out16( mmio, ERRORTERM, 2*dy-dx);
466      cyber_out32( mmio, K2      ,2*(dy-dx));
467      cyber_out32( mmio, PIXOP        , cmd);
468 
469      return true;
470 }
471 
cyber5kBlit(void * drv,void * dev,DFBRectangle * rect,int dx,int dy)472 static bool cyber5kBlit( void *drv, void *dev, DFBRectangle *rect, int dx, int dy )
473 {
474      CyberDriverData *cdrv = (CyberDriverData*) drv;
475      CyberDeviceData *cdev = (CyberDeviceData*) dev;
476      volatile u8     *mmio = cdrv->mmio_base;
477 
478      u32 cmd = cdev->blitting_cmd;
479 
480      cyber_waitidle( cdrv, cdev );
481 
482      if (rect->x < dx) {
483           cmd |= DEC_X;
484 
485           rect->x += rect->w - 1;
486           dx      += rect->w - 1;
487      }
488 
489      if (rect->y < dy) {
490           cmd |= DEC_Y;
491 
492           rect->y += rect->h - 1;
493           dy      += rect->h - 1;
494      }
495 
496      cyber_out32( mmio, DSTPTR,
497                   cdev->dst_pixeloffset + dy * cdev->dst_pixelpitch + dx );
498      cyber_out32( mmio, SRC1PTR,
499                   cdev->src_pixeloffset +
500                   rect->y * cdev->src_pixelpitch + rect->x );
501      cyber_out32( mmio, HEIGHTWIDTH, ((rect->h-1) << 16) | (rect->w-1) );
502      cyber_out32( mmio, PIXOP      , cmd);
503 
504      return true;
505 }
506 
cyber5kBlit24(void * drv,void * dev,DFBRectangle * rect,int dx,int dy)507 static bool cyber5kBlit24( void *drv, void *dev, DFBRectangle *rect, int dx, int dy )
508 {
509      CyberDriverData *cdrv = (CyberDriverData*) drv;
510      CyberDeviceData *cdev = (CyberDeviceData*) dev;
511      volatile u8     *mmio = cdrv->mmio_base;
512 
513      u32 cmd = cdev->blitting_cmd;
514      u32 src = 0;
515      u32 dst = 0;
516 
517      cyber_waitidle( cdrv, cdev );
518 
519      if (rect->x < dx) {
520           cmd |= DEC_X;
521 
522           rect->x += rect->w - 1;
523           dx      += rect->w - 1;
524 
525           src += 2;
526           dst += 2;
527      }
528 
529      if (rect->y < dy) {
530           cmd |= DEC_Y;
531 
532           rect->y += rect->h - 1;
533           dy      += rect->h - 1;
534      }
535 
536      src += cdev->src_pixeloffset + rect->y * cdev->dst_pixelpitch + rect->x;
537      dst += cdev->dst_pixeloffset + dy * cdev->dst_pixelpitch + dx;
538 
539      cyber_out32( mmio, DSTPTR     , src );
540      cyber_out32( mmio, SRC1PTR    , dst );
541      cyber_out32( mmio, HEIGHTWIDTH, ((rect->h-1) << 16) | (rect->w-1) );
542      cyber_out32( mmio, PIXOP      , cmd );
543 
544      return true;
545 }
546 
547 /* primary layer hooks */
548 
549 #define OSD_OPTIONS      (DLOP_ALPHACHANNEL | DLOP_SRC_COLORKEY | DLOP_OPACITY)
550 
551 DisplayLayerFuncs  oldPrimaryFuncs;
552 void              *oldPrimaryDriverData;
553 
554 static DFBResult
osdInitLayer(CoreLayer * layer,void * driver_data,void * layer_data,DFBDisplayLayerDescription * description,DFBDisplayLayerConfig * config,DFBColorAdjustment * adjustment)555 osdInitLayer( CoreLayer                  *layer,
556               void                       *driver_data,
557               void                       *layer_data,
558               DFBDisplayLayerDescription *description,
559               DFBDisplayLayerConfig      *config,
560               DFBColorAdjustment         *adjustment )
561 {
562      DFBResult ret;
563 
564      /* call the original initialization function first */
565      ret = oldPrimaryFuncs.InitLayer( layer,
566                                       oldPrimaryDriverData,
567                                       layer_data, description,
568                                       config, adjustment );
569      if (ret)
570           return ret;
571 
572      /* set name */
573      snprintf(description->name,
574               DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "CyberPro OSD");
575 
576      /* add support for options */
577      config->flags |= DLCONF_OPTIONS;
578 
579      /* add some capabilities */
580      description->caps |= DLCAPS_ALPHACHANNEL |
581                           DLCAPS_OPACITY | DLCAPS_SRC_COLORKEY;
582 
583      return DFB_OK;
584 }
585 
586 static DFBResult
osdTestRegion(CoreLayer * layer,void * driver_data,void * layer_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags * failed)587 osdTestRegion( CoreLayer                  *layer,
588                void                       *driver_data,
589                void                       *layer_data,
590                CoreLayerRegionConfig      *config,
591                CoreLayerRegionConfigFlags *failed )
592 {
593      DFBResult                  ret;
594      CoreLayerRegionConfigFlags fail = 0;
595      DFBDisplayLayerOptions     options = config->options;
596 
597      /* remove options before calling the original function */
598      config->options = DLOP_NONE;
599 
600      /* call the original function */
601      ret = oldPrimaryFuncs.TestRegion( layer, oldPrimaryDriverData,
602                                        layer_data, config, &fail );
603 
604      /* check options if specified */
605      if (options) {
606           /* any unsupported option wanted? */
607           if (options & ~OSD_OPTIONS)
608                fail |= CLRCF_OPTIONS;
609 
610           /* opacity and alpha channel cannot be used at once */
611           if ((options & (DLOP_OPACITY | DLOP_ALPHACHANNEL)) ==
612               (DLOP_OPACITY | DLOP_ALPHACHANNEL))
613           {
614                fail |= CLRCF_OPTIONS;
615           }
616      }
617 
618      /* restore options */
619      config->options = options;
620 
621      if (failed)
622           *failed = fail;
623 
624      if (fail)
625           return DFB_UNSUPPORTED;
626 
627      return ret;
628 }
629 
630 static DFBResult
osdSetRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags updated,CoreSurface * surface,CorePalette * palette,CoreSurfaceBufferLock * lock)631 osdSetRegion( CoreLayer                  *layer,
632               void                       *driver_data,
633               void                       *layer_data,
634               void                       *region_data,
635               CoreLayerRegionConfig      *config,
636               CoreLayerRegionConfigFlags  updated,
637               CoreSurface                *surface,
638               CorePalette                *palette,
639               CoreSurfaceBufferLock      *lock )
640 {
641      DFBResult ret;
642 
643      /* call the original function */
644      ret = oldPrimaryFuncs.SetRegion( layer, oldPrimaryDriverData,
645                                       layer_data, region_data,
646                                       config, updated, surface,
647                                       palette, lock );
648      if (ret)
649           return ret;
650 
651      /* select pixel based or global alpha */
652      if (config->options & DLOP_ALPHACHANNEL)
653           cyber_select_alpha_src( ALPHA_GRAPHICS );
654      else
655           cyber_select_alpha_src( ALPHA_REGISTER );
656 
657      cyber_set_alpha_reg( config->opacity,
658                           config->opacity,
659                           config->opacity );
660 
661      /* source color keying */
662      cyber_select_RAM_addr( RAM_CPU );
663      cyber_set_alpha_RAM_reg( 0, 0x00, 0x00, 0x00 );
664      cyber_select_magic_alpha_src( ALPHA_LOOKUP );
665      cyber_enable_magic_alpha_blend( config->options & DLOP_SRC_COLORKEY );
666 
667      /* FIXME: hardcoded black color key */
668      cyber_set_magic_match_reg( 0, 0, 0 );
669 
670      return DFB_OK;
671 }
672 
673 DisplayLayerFuncs newPrimaryFuncs = {
674      .InitLayer  = osdInitLayer,
675 
676      .TestRegion = osdTestRegion,
677      .SetRegion  = osdSetRegion,
678 };
679 
680 /* exported symbols */
681 
682 static int
driver_probe(CoreGraphicsDevice * device)683 driver_probe( CoreGraphicsDevice *device )
684 {
685      switch (dfb_gfxcard_get_accelerator( device )) {
686           case FB_ACCEL_IGS_CYBER2000:
687           case FB_ACCEL_IGS_CYBER2010:
688           case FB_ACCEL_IGS_CYBER5000:
689 #ifdef FB_ACCEL_IGS_CYBER5K
690           case FB_ACCEL_IGS_CYBER5K:          /* CyberPro 5xxx */
691 #endif
692                return 1;
693      }
694 
695      return 0;
696 }
697 
698 static void
driver_get_info(CoreGraphicsDevice * device,GraphicsDriverInfo * info)699 driver_get_info( CoreGraphicsDevice *device,
700                  GraphicsDriverInfo *info )
701 {
702      /* fill driver info structure */
703      snprintf( info->name,
704                DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
705                "Cyber Pro Driver" );
706 
707      snprintf( info->vendor,
708                DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
709                "directfb.org" );
710 
711      info->version.major = 0;
712      info->version.minor = 4;
713 
714      info->driver_data_size = sizeof (CyberDriverData);
715      info->device_data_size = sizeof (CyberDeviceData);
716 }
717 
718 static DFBResult
driver_init_driver(CoreGraphicsDevice * device,GraphicsDeviceFuncs * funcs,void * driver_data,void * device_data,CoreDFB * core)719 driver_init_driver( CoreGraphicsDevice  *device,
720                     GraphicsDeviceFuncs *funcs,
721                     void                *driver_data,
722                     void                *device_data,
723                     CoreDFB             *core )
724 {
725      CyberDriverData *cdrv = (CyberDriverData*) driver_data;
726 
727      /* gain access to memory mapped registers */
728      cdrv->mmio_base = (volatile u8*) dfb_gfxcard_map_mmio( device, 0, -1 );
729      if (!cdrv->mmio_base)
730           return DFB_IO;
731 
732      /* HACK */
733      cyber_mmio = cdrv->mmio_base;
734 
735      /* fill acceleration function table */
736      funcs->EngineSync    = cyber5kEngineSync;
737      funcs->CheckState    = cyber5kCheckState;
738      funcs->SetState      = cyber5kSetState;
739 
740      funcs->FillRectangle = cyber5kFillRectangle;
741      funcs->DrawRectangle = cyber5kDrawRectangle;
742      funcs->DrawLine      = cyber5kDrawLine;
743      funcs->Blit          = cyber5kBlit;
744 
745      /* install primary layer hooks */
746      dfb_layers_hook_primary( device, driver_data, &newPrimaryFuncs,
747                               &oldPrimaryFuncs, &oldPrimaryDriverData );
748 
749      /* add the video underlay */
750      switch (dfb_gfxcard_get_accelerator( device )) {
751           case FB_ACCEL_IGS_CYBER5000:
752 #ifdef FB_ACCEL_IGS_CYBER5K
753           case FB_ACCEL_IGS_CYBER5K:          /* CyberPro 5xxx */
754 #endif
755                dfb_layers_register( dfb_screens_at(DSCID_PRIMARY),
756                                     driver_data, &cyberUnderlayFuncs );
757      }
758 
759      return DFB_OK;
760 }
761 
762 static DFBResult
driver_init_device(CoreGraphicsDevice * device,GraphicsDeviceInfo * device_info,void * driver_data,void * device_data)763 driver_init_device( CoreGraphicsDevice *device,
764                     GraphicsDeviceInfo *device_info,
765                     void               *driver_data,
766                     void               *device_data )
767 {
768      CyberDriverData *cdrv = (CyberDriverData*) driver_data;
769      volatile u8     *mmio = cdrv->mmio_base;
770 
771      /* fill device info */
772      snprintf( device_info->name,
773                DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Cyber Pro" );
774 
775      snprintf( device_info->vendor,
776                DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "TVIA" );
777 
778 
779      device_info->caps.flags    = 0;
780      device_info->caps.accel    = CYBER5K_DRAWING_FUNCTIONS |
781                                   CYBER5K_BLITTING_FUNCTIONS;
782      device_info->caps.drawing  = CYBER5K_DRAWING_FLAGS;
783      device_info->caps.blitting = CYBER5K_BLITTING_FLAGS;
784 
785      device_info->limits.surface_byteoffset_alignment = 16;
786      device_info->limits.surface_pixelpitch_alignment = 4;
787 
788 
789      /* set fifo policy at startup */
790      cyber_grphw(0x74, 0x1b);
791      cyber_grphw(0x75, 0x1e);
792 
793      cyber_grphw(0xD9, 0x0f);
794      cyber_grphw(0xDA, 0x1b);
795      cyber_grphw(0xDD, 0x00);
796 
797      cyber_seqw(0xD9, 0x0f);
798      cyber_seqw(0xDA, 0x1b);
799      cyber_seqw(0xDD, 0x00);
800 
801 
802 
803      cyber_out8 (mmio, COPFLAGS, 1);
804      cyber_out8 (mmio, FMIX , 0x03);
805 
806      return DFB_OK;
807 }
808 
809 static void
driver_close_device(CoreGraphicsDevice * device,void * driver_data,void * device_data)810 driver_close_device( CoreGraphicsDevice *device,
811                      void               *driver_data,
812                      void               *device_data )
813 {
814 }
815 
816 static void
driver_close_driver(CoreGraphicsDevice * device,void * driver_data)817 driver_close_driver( CoreGraphicsDevice *device,
818                      void               *driver_data )
819 {
820      CyberDriverData *cdrv = (CyberDriverData*) driver_data;
821 
822      dfb_gfxcard_unmap_mmio( device, cdrv->mmio_base, -1 );
823 }
824 
825