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