summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/matrox/matrox_spic.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_spic.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c b/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c
new file mode 100755
index 0000000..cca8392
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_spic.c
@@ -0,0 +1,314 @@
+/*
+ (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 <config.h>
+
+#include <stdio.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+typedef struct {
+ CoreLayerRegionConfig config;
+
+ /* Stored registers */
+ struct {
+ /* CRTC2 sub picture */
+ u32 c2DATACTL;
+
+ u32 c2SPICSTARTADD0;
+ u32 c2SPICSTARTADD1;
+ u32 c2SUBPICLUT;
+ } regs;
+} MatroxSpicLayerData;
+
+static void spic_calc_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+static void spic_set_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic );
+
+#define SPIC_SUPPORTED_OPTIONS (DLOP_ALPHACHANNEL | DLOP_OPACITY)
+
+/**********************/
+
+static int
+spicLayerDataSize( void )
+{
+ return sizeof(MatroxSpicLayerData);
+}
+
+static DFBResult
+spicInitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY;
+ description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE;
+
+ /* set name */
+ snprintf( description->name,
+ DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Matrox CRTC2 Sub-Picture" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE |
+ DLCONF_OPTIONS | DLCONF_SURFACE_CAPS;
+
+ config->width = 720;
+ config->height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576;
+ config->pixelformat = DSPF_ALUT44;
+ config->buffermode = DLBM_FRONTONLY;
+ config->options = DLOP_NONE;
+ config->surface_caps = DSCAPS_INTERLACED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicTestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ CoreLayerRegionConfigFlags fail = 0;
+
+ if (config->options & ~SPIC_SUPPORTED_OPTIONS)
+ fail |= CLRCF_OPTIONS;
+
+ /* Can't have both at the same time */
+ if (config->options & DLOP_ALPHACHANNEL && config->options & DLOP_OPACITY)
+ fail |= CLRCF_OPTIONS;
+
+ switch (config->opacity) {
+ case 0x00:
+ case 0xFF:
+ break;
+ default:
+ if (!(config->options & DLOP_OPACITY))
+ fail |= CLRCF_OPACITY;
+ }
+
+ if (config->surface_caps & ~(DSCAPS_INTERLACED | DSCAPS_SEPARATED))
+ fail |= CLRCF_SURFACE_CAPS;
+
+ if (config->format != DSPF_ALUT44)
+ fail |= CLRCF_FORMAT;
+
+ if (config->width != 720)
+ fail |= CLRCF_WIDTH;
+
+ if (config->surface_caps & DSCAPS_INTERLACED) {
+ if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576))
+ fail |= CLRCF_HEIGHT;
+ } else {
+ if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 240 : 288))
+ fail |= CLRCF_HEIGHT;
+ }
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicAddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+spicSetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+ MatroxDeviceData *mdev = mdrv->device_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ /* remember configuration */
+ mspic->config = *config;
+
+ if (updated & CLRCF_PALETTE) {
+ u8 y, cb, cr;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ RGB_TO_YCBCR( palette->entries[i].r,
+ palette->entries[i].g,
+ palette->entries[i].b,
+ y, cb, cr );
+
+ mspic->regs.c2SUBPICLUT = (cr << 24) | (cb << 16) | (y << 8) | i;
+ mga_out32( mmio, mspic->regs.c2SUBPICLUT, C2SUBPICLUT );
+ }
+ }
+
+ if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT | CLRCF_SURFACE_CAPS |
+ CLRCF_OPTIONS | CLRCF_OPACITY | CLRCF_SURFACE)) {
+ spic_calc_buffer( mdrv, mspic, surface, lock );
+ spic_set_buffer( mdrv, mspic );
+
+ mspic->regs.c2DATACTL = mga_in32( mmio, C2DATACTL );
+
+ if (surface->config.caps & DSCAPS_INTERLACED || mdev->crtc2_separated)
+ mspic->regs.c2DATACTL &= ~C2OFFSETDIVEN;
+ else
+ mspic->regs.c2DATACTL |= C2OFFSETDIVEN;
+
+ if (config->opacity)
+ mspic->regs.c2DATACTL |= C2SUBPICEN;
+ else
+ mspic->regs.c2DATACTL &= ~C2SUBPICEN;
+
+ if (config->options & DLOP_ALPHACHANNEL)
+ mspic->regs.c2DATACTL &= ~C2STATICKEYEN;
+ else
+ mspic->regs.c2DATACTL |= C2STATICKEYEN;
+
+ mspic->regs.c2DATACTL &= ~C2STATICKEY;
+ mspic->regs.c2DATACTL |= ((config->opacity + 1) << 20) & C2STATICKEY;
+
+ mga_out32( mmio, mspic->regs.c2DATACTL, C2DATACTL);
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicRemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mspic->regs.c2DATACTL = mga_in32( mmio, C2DATACTL );
+
+ mspic->regs.c2DATACTL &= ~C2SUBPICEN;
+
+ mga_out32( mmio, mspic->regs.c2DATACTL, C2DATACTL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+spicFlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
+ MatroxSpicLayerData *mspic = (MatroxSpicLayerData*) layer_data;
+
+ spic_calc_buffer( mdrv, mspic, surface, lock );
+ spic_set_buffer( mdrv, mspic );
+
+ dfb_surface_flip( surface, false );
+
+ return DFB_OK;
+}
+
+DisplayLayerFuncs matroxSpicFuncs = {
+ .LayerDataSize = spicLayerDataSize,
+ .InitLayer = spicInitLayer,
+
+ .TestRegion = spicTestRegion,
+ .AddRegion = spicAddRegion,
+ .SetRegion = spicSetRegion,
+ .RemoveRegion = spicRemoveRegion,
+ .FlipRegion = spicFlipRegion,
+};
+
+/* internal */
+
+static void spic_calc_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ unsigned int field_offset = lock->pitch;
+
+ mspic->regs.c2SPICSTARTADD1 = lock->offset;
+ mspic->regs.c2SPICSTARTADD0 = lock->offset;
+
+ if (surface->config.caps & DSCAPS_SEPARATED)
+ field_offset *= surface->config.size.h / 2;
+
+ if (surface->config.caps & DSCAPS_INTERLACED)
+ mspic->regs.c2SPICSTARTADD0 += field_offset;
+}
+
+static void spic_set_buffer( MatroxDriverData *mdrv,
+ MatroxSpicLayerData *mspic )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_out32( mmio, mspic->regs.c2SPICSTARTADD0, C2SPICSTARTADD0 );
+ mga_out32( mmio, mspic->regs.c2SPICSTARTADD1, C2SPICSTARTADD1 );
+}