summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c b/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c
new file mode 100755
index 0000000..b4638df
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/cyber5k/cyber5k_overlay.c
@@ -0,0 +1,376 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+
+#include "cyber5k.h"
+#include "cyber5k_overlay.h"
+#include "regs.h"
+#include "mmio.h"
+
+static int overlay_byte_per_pixel = 2;
+static int overlay_init = 0;
+
+static unsigned char savedReg74, savedReg75; /*FIFO control registers for 2D Graphics*/
+static unsigned char savedRegD9[2], savedRegDA[2], savedRegDD[2]; /*FIFO control registers for Overlay*/
+/*Following is our FIFO policy number, should be programmed to
+0x3CE/0x74, 0x3CE/0x75, 0x3CE(0x3C4)/0xD9, 0x3CE(0x3C4)/0xDA,
+0x3CE(0x3c4)/0xDD respectively in order to get a best memory bandwidth.
+Current value is a group of experence value based on 70MHZ EDO/SG RAM.*/
+static unsigned char bFIFOPolicyNum[5] = {0x10, 0x10, 0x1C, 0x1C, 0x06};
+
+
+static void
+cyber_videoreg_mask( unsigned char index, unsigned char value, unsigned char mask )
+{
+ unsigned char tmp;
+
+ cyber_out8( cyber_mmio, GRAINDEX, index );
+ tmp = cyber_in8( cyber_mmio, GRADATA );
+ tmp &= mask;
+ tmp |= value;
+ cyber_out8( cyber_mmio, GRADATA, tmp );
+}
+
+static void
+cyber_seqreg_mask( unsigned char index, unsigned char value, unsigned char mask )
+{
+ unsigned char tmp;
+
+ cyber_out8( cyber_mmio, SEQINDEX, index );
+ tmp = cyber_in8( cyber_mmio, SEQDATA );
+
+ tmp &= mask;
+ tmp |= value;
+ cyber_out8( cyber_mmio, SEQDATA, tmp );
+}
+
+static void
+cyber_overlayreg_mask( unsigned char index, unsigned char value, unsigned char mask ) {
+ unsigned char tmp;
+
+ cyber_out8( cyber_mmio, GRAINDEX, index );
+ tmp = cyber_in8( cyber_mmio, GRADATA );
+
+ tmp &= mask;
+ tmp |= value;
+ cyber_out8(cyber_mmio, GRADATA, tmp);
+}
+
+void cyber_cleanup_overlay(void)
+{
+ /*restore FIFO control regs*/
+ cyber_seqreg_mask(0xA7, 0x0, ~0x5);
+
+
+ if (!overlay_init)
+ return;
+ overlay_init = 0;
+
+
+ cyber_grphw(0x74, savedReg74);
+ cyber_grphw(0x75, savedReg75);
+
+ cyber_grphw(0xD9, savedRegD9[0]);
+ cyber_grphw(0xDA, savedRegDA[0]);
+ cyber_grphw(0xDD, savedRegDD[0]);
+
+ cyber_seqw(0xD9, savedRegD9[1]);
+ cyber_seqw(0xDA, savedRegDA[1]);
+ cyber_seqw(0xDD, savedRegDD[1]);
+}
+
+void cyber_init_overlay(void)
+{
+ /*Clear Overlay path first*/
+ cyber_grphw(DISP_CTL_I, 0x00);
+
+ /* Video Display Vertical Starting Line (may not need initiate here)*/
+ cyber_grphw(DEST_RECT_TOP_L, 0x00);
+ cyber_grphw(DEST_RECT_TOP_H, 0x00);
+
+ /* Overlay Vertical DDA Increment Value*/
+ cyber_grphw(DDA_Y_INC_L, 0x00);
+ cyber_grphw(DDA_Y_INC_H, 0x10);
+
+ /* Video Memory Starting Address*/
+ cyber_grphw(MEMORY_START_L, 0x00);
+ cyber_grphw(MEMORY_START_M, 0x0f);
+ cyber_grphw(MEMORY_START_H, 0x03); /* Temporary fixed to 0x30f00 = 0xc3c00 >> 2*/
+ /* 0x3c00 = 0x300*0x14 = 768*20*/
+
+ /* Video Display Horizontal Starting Pixel -- may not need init here*/
+ cyber_grphw(DEST_RECT_LEFT_L, 0x20);
+ cyber_grphw(DEST_RECT_LEFT_H, 0x00);
+
+ /* Video Display Horizontal Ending Pixel -- may not need init here*/
+ cyber_grphw(DEST_RECT_RIGHT_L, 0x60);
+ cyber_grphw(DEST_RECT_RIGHT_H, 0x01);
+
+ /* Video Display Vertical Ending Line -- may not need init here*/
+ cyber_grphw(DEST_RECT_BOTTOM_L, 0xe0);
+ cyber_grphw(DEST_RECT_BOTTOM_H, 0x00);
+
+ /* Video Color Compare Register*/
+ cyber_grphw(COLOR_CMP_RED, 0x00);
+ cyber_grphw(COLOR_CMP_GREEN,0x00);
+ cyber_grphw(COLOR_CMP_BLUE, 0x00);
+
+ /* Video Horizontal DDA Increment Value*/
+ cyber_grphw(DDA_X_INC_L, 0x00);
+ cyber_grphw(DDA_X_INC_H, 0x10);
+
+ /* Video Format Control*/
+ cyber_grphw(VIDEO_FORMAT, 0x00);
+
+ /* Video Misc Control*/
+ cyber_grphw(MISC_CTL_I, 0x00);
+
+ cyber_grphw(MISC_CTL_I, 0x01); /* Video Misc Control*/
+
+ /*default to colorkey*/
+ cyber_grphw(DISP_CTL_I, 0x04 );
+
+#ifdef NTSCTVOUT /*if your TV output mode is NTSC*/
+ cyber_seqreg_mask(0xA6, 0x20, ~0x30);
+#else /*if your TV output mode is PAL*/
+ cyber_seqreg_mask(0xA6, 0x30, ~0x30);
+#endif
+
+
+ if (overlay_init)
+ return;
+ overlay_init = 1;
+
+
+
+/* the following code is commented out, since saved values are not clean if */
+/* DirectFB crashed while underlay was enabled, hardcoded bootup */
+/* values instead (see below) */
+
+/*
+ cyber_out8(cyber_mmio, GRAINDEX, 0x74);
+ savedReg74 = cyber_in8(cyber_mmio, GRADATA);
+ cyber_out8(cyber_mmio, GRAINDEX, 0x75);
+ savedReg75 = cyber_in8(cyber_mmio, GRADATA);
+
+ cyber_out8(cyber_mmio, GRAINDEX, 0xD9);
+ savedRegD9[0] = cyber_in8(cyber_mmio, GRADATA);
+ cyber_out8(cyber_mmio, GRAINDEX, 0xDA);
+ savedRegDA[0] = cyber_in8(cyber_mmio, GRADATA);
+ cyber_out8(cyber_mmio, GRAINDEX, 0xDD);
+ savedRegDD[0] = cyber_in8(cyber_mmio, GRADATA);
+
+ cyber_out8(cyber_mmio, SEQINDEX, 0xD9);
+ savedRegD9[1] = cyber_in8(cyber_mmio, SEQDATA);
+ cyber_out8(cyber_mmio, SEQINDEX, 0xDA);
+ savedRegDA[1] = cyber_in8(cyber_mmio, SEQDATA);
+ cyber_out8(cyber_mmio, SEQINDEX, 0xDD);
+ savedRegDD[1] = cyber_in8(cyber_mmio, SEQDATA);
+ */
+
+
+ savedReg74 = 0x1b;
+ savedReg74 = 0x1e;
+
+ savedRegD9[0] = 0x0f;
+ savedRegDA[0] = 0x1b;
+ savedRegDD[0] = 0x00;
+
+ savedRegD9[1] = 0x0f;
+ savedRegDA[1] = 0x1b;
+ savedRegDD[1] = 0x00;
+}
+
+void cyber_change_overlay_fifo(void)
+{
+ cyber_grphw(0x74, bFIFOPolicyNum[0]);
+ cyber_grphw(0x75, bFIFOPolicyNum[1]);
+ cyber_grphw(0xD9, bFIFOPolicyNum[2]);
+ cyber_grphw(0xDA, bFIFOPolicyNum[3]);
+
+ cyber_videoreg_mask(0xA6, 0x08, ~0x08);
+ cyber_videoreg_mask(0xF1, 0x40, (unsigned char)(~0xC0));
+ cyber_overlayreg_mask(FIFO_CTL_I, bFIFOPolicyNum[4] & 0x05, ~0x05);
+ cyber_overlayreg_mask(FIFO_CTL_I, 0x2, ~0x02);
+}
+
+void cyber_set_overlay_format(int format) {
+ switch (format) {
+ case OVERLAY_YUV422:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x00, 0xF8 );
+ overlay_byte_per_pixel = 2;
+ break;
+ case OVERLAY_RGB555:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x01, 0xF8 );
+ overlay_byte_per_pixel = 2;
+ break;
+ case OVERLAY_RGB565:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x02, 0xF8 );
+ overlay_byte_per_pixel = 2;
+ break;
+ case OVERLAY_RGB888:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x03, 0xF8 );
+ overlay_byte_per_pixel = 3;
+ break;
+ case OVERLAY_RGB8888:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x04, 0xF8 );
+ overlay_byte_per_pixel = 4;
+ break;
+ case OVERLAY_RGB8:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x05, 0xF8 );
+ overlay_byte_per_pixel = 1;
+ break;
+ case OVERLAY_RGB4444:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x06, 0xF8 );
+ overlay_byte_per_pixel = 2;
+ break;
+ case OVERLAY_RGB8T:
+ cyber_overlayreg_mask( VIDEO_FORMAT, 0x07, 0xF8 );
+ overlay_byte_per_pixel = 1;
+ break;
+ }
+}
+
+void cyber_set_overlay_mode(int mode)
+{
+ switch (mode) {
+ case OVERLAY_COLORKEY:
+ cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xFD );
+ break;
+ case OVERLAY_WINDOWKEY:
+ default:
+ cyber_overlayreg_mask( DISP_CTL_I, 0x02, 0xFD );
+ break;
+ }
+}
+
+void cyber_set_overlay_srcaddr(int addr, int x, int y, int width, int pitch)
+{
+ unsigned char bHigh;
+ int wByteFetch;
+
+ addr += y * pitch + x * overlay_byte_per_pixel;
+ addr >>= 2;
+
+ /*playback start addr*/
+ cyber_grphw( MEMORY_START_L, (unsigned char)( addr & 0x0000FF) );
+ cyber_grphw( MEMORY_START_M, (unsigned char)((addr & 0x00FF00) >> 8) );
+ cyber_grphw( MEMORY_START_H, (unsigned char)((addr & 0xFF0000) >> 16) );
+
+ /* pitch is a multiple of 64 bits*/
+ pitch >>= 3; /* 64 bit address field*/
+ wByteFetch = (width * overlay_byte_per_pixel + 7) >> 3;
+
+ bHigh = (unsigned char)(pitch >> 8) & 0x0F;
+ bHigh = bHigh | (((unsigned char)(wByteFetch >> 8)) << 4 );
+
+ cyber_grphw( MEMORY_PITCH_L, (unsigned char)(pitch) );
+ cyber_grphw( MEMORY_PITCH_H, bHigh );
+
+ cyber_grphw( MEMORY_OFFSET_PHASE, (unsigned char)(wByteFetch) );
+
+ if (width > 720) /*Turn off interpolation*/
+ cyber_overlayreg_mask( DISP_CTL_I, 0x20, 0xDF );
+ else { /*Turn off interpolation*/
+ if (width > 360) { /* Y Only*/
+ cyber_seqreg_mask(0xA6, 0x40, ~0x40);
+ }
+ else {
+ cyber_seqreg_mask(0xA6, 0x00, ~0x40);
+ }
+
+ cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xDF );
+ }
+}
+
+void cyber_set_overlay_window(int left, int top, int right, int bottom)
+{
+ cyber_grphw( DEST_RECT_LEFT_L, (unsigned char)(left ) );
+ cyber_grphw( DEST_RECT_LEFT_H, (unsigned char)(left >> 8) );
+ cyber_grphw( DEST_RECT_RIGHT_L, (unsigned char)(right ) );
+ cyber_grphw( DEST_RECT_RIGHT_H, (unsigned char)(right >> 8) );
+
+ cyber_grphw( DEST_RECT_TOP_L, (unsigned char)(top ) );
+ cyber_grphw( DEST_RECT_TOP_H, (unsigned char)(top >> 8) );
+ cyber_grphw( DEST_RECT_BOTTOM_L, (unsigned char)(bottom ) );
+ cyber_grphw( DEST_RECT_BOTTOM_H, (unsigned char)(bottom >> 8) );
+}
+
+void cyber_set_overlay_scale( unsigned char bEnableBob, int wSrcXExt, int wDstXExt, int wSrcYExt, int wDstYExt )
+{
+ int dwScale;
+
+ cyber_grphw( DDA_X_INIT_L, 0x0 ); /* set to 0x800;*/
+ cyber_grphw( DDA_X_INIT_H, 0x8 );
+ if ( wSrcXExt == wDstXExt )
+ dwScale = 0x1000;
+ else
+ dwScale = ( wSrcXExt * 0x1000 ) / wDstXExt;
+ cyber_grphw( DDA_X_INC_L, (unsigned char)( dwScale & 0x00FF) );
+ cyber_grphw( DDA_X_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) );
+
+ cyber_grphw( DDA_Y_INIT_L, 0x0 ); /* set to 0x800;*/
+ cyber_grphw( DDA_Y_INIT_H, 0x8 );
+
+ if ( wSrcYExt == wDstYExt )
+ dwScale = 0x1000;
+ else
+ dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt;
+
+
+ if (bEnableBob == 0) {/*Disable Bob mode*/
+ cyber_seqreg_mask(0xA7, 0x0, ~0x5); /*Bob/Weave disable*/
+ }
+ else {/*Enable Bob mode*/
+ wSrcYExt = wSrcYExt / 2;
+ if (wSrcYExt == wDstYExt)
+ dwScale = 0x1000;
+ else
+ dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt;
+ if (dwScale <= 0x815 && dwScale >= 0x7eb) {
+ cyber_seqreg_mask(0xA7, 0x5, ~0x5); /*Bob/Weave enable*/
+ }
+ else {
+ cyber_seqreg_mask(0xA7, 0x4, ~0x5); /*Bob/Weave enable*/
+ }
+ }
+
+ cyber_grphw( DDA_Y_INC_L, (unsigned char)( dwScale & 0x00FF) );
+ cyber_grphw( DDA_Y_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) );
+}
+
+void cyber_enable_overlay(int enable)
+{
+ if (enable)
+ cyber_overlayreg_mask( DISP_CTL_I, 0x84, (unsigned char)(~0x84) );
+ else
+ cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0x7F ); /* Disable Vafc !!!*/
+}