From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- .../gfxdrivers/savage/savage_streams_old.c | 916 +++++++++++++++++++++ 1 file changed, 916 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/savage/savage_streams_old.c (limited to 'Source/DirectFB/gfxdrivers/savage/savage_streams_old.c') diff --git a/Source/DirectFB/gfxdrivers/savage/savage_streams_old.c b/Source/DirectFB/gfxdrivers/savage/savage_streams_old.c new file mode 100755 index 0000000..72673a2 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/savage/savage_streams_old.c @@ -0,0 +1,916 @@ +/* + (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 , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + 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 + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "savage.h" +#include "savage_streams_old.h" +#include "mmio.h" +#include "savage_bci.h" + +/* #define SAVAGE_DEBUG */ +#ifdef SAVAGE_DEBUG + #define SVGDBG(x...) fprintf(stderr, "savage_streams_old:" x) +#else + #define SVGDBG(x...) +#endif + +typedef struct { + DFBRectangle dest; + CoreLayerRegionConfig config; + int video_pitch; + + struct { + /* secondary stream registers */ + u32 SSTREAM_CTRL; + u32 SSTREAM_H_SCALE; + u32 BLEND_CTRL; + u32 SSTREAM_MULTIBUF; + u32 SSTREAM_FB_ADDR0; + u32 SSTREAM_FB_ADDR1; + u32 SSTREAM_STRIDE; + u32 SSTREAM_V_SCALE; + u32 SSTREAM_V_INIT_VALUE; + u32 SSTREAM_SRC_LINE_COUNT; + u32 SSTREAM_WIN_START; + u32 SSTREAM_WIN_SIZE; + u32 SSTREAM_FB_CB_ADDR; + u32 SSTREAM_FB_CR_ADDR; + u32 SSTREAM_CBCR_STRIDE; + u32 SSTREAM_FB_SIZE; + u32 SSTREAM_FB_ADDR2; + u32 CHROMA_KEY_CONTROL; + u32 CHROMA_KEY_UPPER_BOUND; + } regs; +} SavageSecondaryLayerData; + +typedef struct { + CoreLayerRegionConfig config; + CoreSurfaceBufferLock *lock; + bool init; + + struct { + /* primary stream registers */ + u32 PSTREAM_CTRL; + u32 PSTREAM_FB_ADDR0; + u32 PSTREAM_FB_ADDR1; + u32 PSTREAM_STRIDE; + u32 PSTREAM_WIN_START; + u32 PSTREAM_WIN_SIZE; + u32 PSTREAM_FB_SIZE; + } regs; +} SavagePrimaryLayerData; + +DisplayLayerFuncs savage_pfuncs; +void *savage_pdriver_data; + +/* function prototypes */ +static void +secondary_set_regs (SavageDriverData *sdrv, + SavageSecondaryLayerData *slay); +static void +secondary_calc_regs(SavageDriverData *sdrv, + SavageSecondaryLayerData *slay, + CoreLayer *layer, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock); + +static DFBResult +savage_secondary_calc_colorkey( SavageDriverData *sdrv, + SavageSecondaryLayerData *slay, + CoreLayerRegionConfig *config, + const DFBColorKey *key, + DFBSurfacePixelFormat format ); +static void +primary_set_regs (SavageDriverData *sdrv, + SavagePrimaryLayerData *play); +static void +primary_calc_regs (SavageDriverData *sdrv, + SavagePrimaryLayerData *play, + CoreLayer *layer, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock); + +static inline +void waitretrace (void) +{ + iopl(3); + while ((inb (0x3da) & 0x8)) + ; + + while (!(inb (0x3da) & 0x8)) + ; +} + +static void +streamOnOff(SavageDriverData * sdrv, int on) +{ + volatile u8 *mmio = sdrv->mmio_base; + + waitretrace(); + + if (on) { + vga_out8( mmio, 0x3d4, 0x23 ); + vga_out8( mmio, 0x3d5, 0x00 ); + + vga_out8( mmio, 0x3d4, 0x26 ); + vga_out8( mmio, 0x3d5, 0x00 ); + + /* turn on stream operation */ + vga_out8( mmio, 0x3d4, 0x67 ); + vga_out8( mmio, 0x3d5, 0x0c ); + } + else { + /* turn off stream operation */ + vga_out8( mmio, 0x3d4, 0x67 ); + vga_out8( mmio, 0x3d5, vga_in8( mmio, 0x3d5 ) & ~0x0c ); + } +} + +/* secondary layer functions */ +static int +savageSecondaryLayerDataSize( void ) +{ + SVGDBG("savageSecondaryLayerDataSize\n"); + return sizeof(SavageSecondaryLayerData); +} + +static DFBResult +savageSecondaryInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *default_config, + DFBColorAdjustment *default_adj ) +{ + SVGDBG("savageSecondaryInitLayer\n"); + + /* set capabilities and type */ + description->caps = DLCAPS_SURFACE | DLCAPS_SCREEN_LOCATION | + DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST | + DLCAPS_OPACITY | DLCAPS_HUE | DLCAPS_SATURATION | + DLCAPS_ALPHACHANNEL | DLCAPS_SRC_COLORKEY | + DLCAPS_DST_COLORKEY; + description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE; + + /* set name */ + snprintf(description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, + "Savage Secondary Stream"); + + /* fill out the default configuration */ + default_config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | + DLCONF_OPTIONS; + default_config->width = 640; + default_config->height = 480; + default_config->pixelformat = DSPF_YUY2; + default_config->buffermode = DLBM_FRONTONLY; + default_config->options = DLOP_NONE; + + /* fill out default color adjustment, + only fields set in flags will be accepted from applications */ + default_adj->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | + DCAF_HUE | DCAF_SATURATION; + default_adj->brightness = 0x8000; + default_adj->contrast = 0x8000; + default_adj->hue = 0x8000; + default_adj->saturation = 0x8000; + + return DFB_OK; +} + +static DFBResult +savageSecondaryRemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + volatile u8 *mmio = sdrv->mmio_base; + + SVGDBG("savageSecondaryRemoveRegion\n"); + + /* put primary stream on top of secondary stream */ + savage_out32(mmio, SAVAGE_BLEND_CONTROL, + SAVAGE_BLEND_CONTROL_COMP_PSTREAM); + + return DFB_OK; +} + +static DFBResult +savageSecondaryTestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfigFlags fail = 0; + + SVGDBG("savageSecondaryTestRegion\n"); + + /* check for unsupported options */ + /* savage only supports one option at a time */ + switch (config->options) { + case DLOP_NONE: + case DLOP_ALPHACHANNEL: + case DLOP_SRC_COLORKEY: + case DLOP_DST_COLORKEY: + case DLOP_OPACITY: + break; + default: + fail |= CLRCF_OPTIONS; + break; + } + + /* check pixel format */ + switch (config->format) { + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB24: + case DSPF_RGB32: + case DSPF_YUY2: + case DSPF_UYVY: + case DSPF_I420: + case DSPF_YV12: + break; + default: + fail |= CLRCF_FORMAT; + } + + /* check width */ + if (config->width > 2048 || config->width < 1) + fail |= CLRCF_WIDTH; + + /* check height */ + if (config->height > 2048 || config->height < 1) + fail |= CLRCF_HEIGHT; + + switch (config->format) { + case DSPF_YUY2: + case DSPF_UYVY: + case DSPF_I420: + case DSPF_YV12: + /* secondary is in YUV format */ + if (config->dest.w < (config->source.w / 2)) + fail |= CLRCF_SOURCE | CLRCF_DEST; + if (config->dest.h < (config->source.h / 32)) + fail |= CLRCF_SOURCE | CLRCF_DEST; + break; + default: + /* secondary is in RGB format */ + if (config->dest.w < config->source.w) + fail |= CLRCF_SOURCE | CLRCF_DEST; + if (config->dest.h < config->source.h) + fail |= CLRCF_SOURCE | CLRCF_DEST; + break; + } + + /* write back failing fields */ + if (failed) + *failed = fail; + + /* return failure if any field failed */ + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +savageSecondarySetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + SavageSecondaryLayerData *slay = (SavageSecondaryLayerData*) layer_data; + + SVGDBG("savageSecondarySetConfiguration w:%i h:%i bpp:%i\n", + config->width, config->height, + DFB_BYTES_PER_PIXEL(config->pixelformat) * 8); + + /* remember configuration */ + slay->config = *config; + + switch (config->options & (DLOP_SRC_COLORKEY | DLOP_DST_COLORKEY)) { + case DLOP_SRC_COLORKEY: + savage_secondary_calc_colorkey(sdrv, slay, config, &config->src_key, + config->format); + break; + case DLOP_DST_COLORKEY: + savage_secondary_calc_colorkey(sdrv, slay, config, &config->dst_key, + dfb_primary_layer_pixelformat()); + break; + default: + slay->regs.CHROMA_KEY_CONTROL = 0; + slay->regs.CHROMA_KEY_UPPER_BOUND = 0; + break; + } + + secondary_calc_regs(sdrv, slay, layer, config, surface, lock); + + secondary_set_regs(sdrv, slay); + + return DFB_OK; +} + +static void +savage_secondary_calc_opacity( SavageDriverData *sdrv, + SavageSecondaryLayerData *slay, + CoreLayerRegionConfig *config ) +{ + u8 opacity = config->opacity; + + switch (opacity) { + case 0: + /* put primary stream on top of secondary stream */ + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_PSTREAM; + break; + case 0xFF: + /* put secondary stream on top of primary stream */ + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_SSTREAM; + break; + default: + /* reverse opacity */ + opacity = 7 - (opacity >> 5); + + /* for some reason opacity can not be zero */ + if (opacity == 0) + opacity = 1; + + /* dissolve primary and secondary stream */ + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_DISSOLVE | KP_KS(opacity,0); + break; + } +} + +static DFBResult +savage_secondary_calc_colorkey( SavageDriverData *sdrv, + SavageSecondaryLayerData *slay, + CoreLayerRegionConfig *config, + const DFBColorKey *key, + DFBSurfacePixelFormat format ) +{ + u32 reg; + + switch (format) { + case DSPF_ARGB1555: + case DSPF_RGB16: + reg = 0x14000000; + break; + case DSPF_RGB24: + case DSPF_RGB32: + reg = 0x17000000; + break; + default: + return DFB_UNSUPPORTED; + } + + slay->regs.CHROMA_KEY_CONTROL = reg | (key->r << 16) | (key->g << 8) | (key->b); + slay->regs.CHROMA_KEY_UPPER_BOUND = 0x00000000 | (key->r << 16) | (key->g << 8) | (key->b); + + return DFB_OK; +} + + +static DFBResult +savageSecondaryFlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + SavageSecondaryLayerData *slay = (SavageSecondaryLayerData*) layer_data; + + SVGDBG("savageSecondaryFlipRegion\n"); + + dfb_surface_flip( surface, false ); + + secondary_calc_regs(sdrv, slay, layer, &slay->config, surface, lock); + secondary_set_regs(sdrv, slay); + + if (flags & DSFLIP_WAIT) + dfb_screen_wait_vsync( dfb_screens_at( DSCID_PRIMARY ) ); + + return DFB_OK; +} + + +static DFBResult +savageSecondarySetColorAdjustment( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + SavageSecondaryLayerData *slay = (SavageSecondaryLayerData*) layer_data; + volatile u8 *mmio = sdrv->mmio_base; + + SVGDBG("savageSecondaryColorAdjustment b:%i c:%i h:%i s:%i\n", + adj->brightness, adj->contrast, adj->hue, adj->saturation); + + if ((slay->regs.SSTREAM_FB_SIZE & 0x00400000) == 0) { + /* secondary is in YUV format */ + u32 reg; + long sat = adj->saturation * 16 / 65536; + double hue = (adj->hue - 0x8000) * 3.141592654 / 32768.0; + unsigned char hs1 = ((char)(sat * cos(hue))) & 0x1f; + unsigned char hs2 = ((char)(sat * sin(hue))) & 0x1f; + + reg = 0x80008000 | (adj->brightness >> 8) | + ((adj->contrast & 0xf800) >> 3) | (hs1 << 16) | (hs2 << 24); + + savage_out32(mmio, SAVAGE_COLOR_ADJUSTMENT, reg); + + return DFB_OK; + } + else { + /* secondary is in RGB format */ + return DFB_UNSUPPORTED; + } +} + +DisplayLayerFuncs savageSecondaryFuncs = { + .LayerDataSize = savageSecondaryLayerDataSize, + .InitLayer = savageSecondaryInitLayer, + .RemoveRegion = savageSecondaryRemoveRegion, + .TestRegion = savageSecondaryTestRegion, + .SetRegion = savageSecondarySetRegion, + .FlipRegion = savageSecondaryFlipRegion, + .SetColorAdjustment = savageSecondarySetColorAdjustment, +}; + +/* secondary internal */ +static void +secondary_set_regs(SavageDriverData *sdrv, SavageSecondaryLayerData *slay) +{ + volatile u8 *mmio = sdrv->mmio_base; + + SVGDBG("secondary_set_regs\n"); + + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_CONTROL, + slay->regs.SSTREAM_CTRL); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_HORIZONTAL_SCALING, + slay->regs.SSTREAM_H_SCALE); + savage_out32(mmio, SAVAGE_BLEND_CONTROL, + slay->regs.BLEND_CTRL); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_MULTIPLE_BUFFER_SUPPORT, + slay->regs.SSTREAM_MULTIBUF); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS0, + slay->regs.SSTREAM_FB_ADDR0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS1, + slay->regs.SSTREAM_FB_ADDR1); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS2, + slay->regs.SSTREAM_FB_ADDR2); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_SIZE, + slay->regs.SSTREAM_FB_SIZE); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_STRIDE, + slay->regs.SSTREAM_STRIDE); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_VERTICAL_SCALING, + slay->regs.SSTREAM_V_SCALE); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_SOURCE_LINE_COUNT, + slay->regs.SSTREAM_SRC_LINE_COUNT); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_VERTICAL_INITIAL_VALUE, + slay->regs.SSTREAM_V_INIT_VALUE); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_WINDOW_START, + slay->regs.SSTREAM_WIN_START); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_WINDOW_SIZE, + slay->regs.SSTREAM_WIN_SIZE); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FB_CB_ADDRESS, + slay->regs.SSTREAM_FB_CB_ADDR); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FB_CR_ADDRESS, + slay->regs.SSTREAM_FB_CR_ADDR); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_CBCR_STRIDE, + slay->regs.SSTREAM_CBCR_STRIDE); + + savage_out32(mmio, SAVAGE_CHROMA_KEY_CONTROL, + slay->regs.CHROMA_KEY_CONTROL); + savage_out32(mmio, SAVAGE_CHROMA_KEY_UPPER_BOUND, + slay->regs.CHROMA_KEY_UPPER_BOUND); + + /* Set FIFO L2 on second stream. */ + { + int pitch = slay->video_pitch; + unsigned char cr92; + + SVGDBG("FIFO L2 pitch:%i\n", pitch); + pitch = (pitch + 7) / 8; + vga_out8(mmio, 0x3d4, 0x92); + cr92 = vga_in8( mmio, 0x3d5); + vga_out8(mmio, 0x3d5, (cr92 & 0x40) | (pitch >> 8) | 0x80); + vga_out8(mmio, 0x3d4, 0x93); + vga_out8(mmio, 0x3d5, pitch); + } +} + +static void +secondary_calc_regs(SavageDriverData *sdrv, + SavageSecondaryLayerData *slay, + CoreLayer *layer, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock) +{ + DFBRectangle *source = &config->source; + DFBRectangle *dest = &config->dest; + + /* source size */ + const int src_w = source->w; + const int src_h = source->h; + /* destination size */ + const int drw_w = dest->w; + const int drw_h = dest->h; + + SVGDBG("secondary_calc_regs x:%i y:%i w:%i h:%i\n", + dest->x, dest->y, dest->w, dest->h); + SVGDBG("w:%i h:%i pitch:%i video.offset:%x\n", + source->w, source->h, lock->pitch, lock->offset); + + slay->video_pitch = 1; + slay->regs.SSTREAM_FB_SIZE = (((lock->pitch * + surface->config.size.h) / 8) - 1) & 0x003fffff; + + switch (surface->config.format) { + case DSPF_ARGB1555: + SVGDBG("secondary set to DSPF_ARGB1555\n"); + slay->regs.SSTREAM_FB_SIZE |= 0x00400000; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_KRGB16; + break; + case DSPF_RGB16: + SVGDBG("secondary set to DSPF_RGB16\n"); + slay->regs.SSTREAM_FB_SIZE |= 0x00400000; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_RGB16; + break; + case DSPF_RGB24: + SVGDBG("secondary set to DSPF_RGB24\n"); + slay->regs.SSTREAM_FB_SIZE |= 0x00400000; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_RGB24; + break; + case DSPF_RGB32: + SVGDBG("secondary set to DSPF_RGB32\n"); + slay->regs.SSTREAM_FB_SIZE |= 0x00400000; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_RGB32; + break; + case DSPF_YUY2: + SVGDBG("secondary set to DSPF_YUY2\n"); + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_YCbCr422; + break; + case DSPF_UYVY: + SVGDBG("secondary set to DSPF_UYVY\n"); + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_CbYCrY422; + break; + case DSPF_I420: + SVGDBG("secondary set to DSPF_I420\n"); + slay->video_pitch = 2; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_YCbCr420; + slay->regs.SSTREAM_FB_CB_ADDR = lock->offset + + (surface->config.size.h * lock->pitch); + slay->regs.SSTREAM_FB_CR_ADDR = slay->regs.SSTREAM_FB_CB_ADDR + + ((surface->config.size.h * lock->pitch)/4); + slay->regs.SSTREAM_CBCR_STRIDE = ((lock->pitch/2) + & 0x00001fff); + break; + case DSPF_YV12: + SVGDBG("secondary set to DSPF_YV12\n"); + slay->video_pitch = 2; + slay->regs.SSTREAM_CTRL = SAVAGE_SECONDARY_STREAM_CONTROL_SSIDF_YCbCr420; + slay->regs.SSTREAM_FB_CR_ADDR = lock->offset + + surface->config.size.h * lock->pitch; + slay->regs.SSTREAM_FB_CB_ADDR = slay->regs.SSTREAM_FB_CR_ADDR + + (surface->config.size.h * lock->pitch)/4; + slay->regs.SSTREAM_CBCR_STRIDE = ((lock->pitch/2) + & 0x00001fff); + break; + default: + D_BUG("unexpected secondary pixelformat"); + return; + } + + slay->regs.SSTREAM_CTRL |= src_w; + + switch (config->options) { + case DLOP_ALPHACHANNEL: + SVGDBG("secondary option DLOP_ALPHACHANNEL\n"); + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_ALPHA; + break; + case DLOP_SRC_COLORKEY: + SVGDBG("secondary option DLOP_SRC_COLORKEY\n"); + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_SCOLORKEY; + break; + case DLOP_DST_COLORKEY: + SVGDBG("secondary option DLOP_DST_COLORKEY\n"); + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_PCOLORKEY; + break; + case DLOP_OPACITY: + SVGDBG("secondary option DLOP_OPACITY\n"); + savage_secondary_calc_opacity( sdrv, slay, config ); + break; + case DLOP_NONE: + SVGDBG("secondary option default\n"); + slay->regs.BLEND_CTRL = SAVAGE_BLEND_CONTROL_COMP_SSTREAM; + break; + default: + D_BUG("unexcpected layer option"); + } + + slay->regs.SSTREAM_H_SCALE = ((32768 * src_w) / drw_w) & 0x0000FFFF; + slay->regs.SSTREAM_V_SCALE = ((32768 * src_h) / drw_h) & 0x000FFFFF; + slay->regs.SSTREAM_V_INIT_VALUE = 0; + slay->regs.SSTREAM_SRC_LINE_COUNT = src_h & 0x7ff; + slay->regs.SSTREAM_MULTIBUF = 0; + slay->regs.SSTREAM_FB_ADDR0 = lock->offset & 0x01ffffff; + slay->regs.SSTREAM_FB_ADDR1 = 0; + slay->regs.SSTREAM_FB_ADDR2 = 0; + slay->regs.SSTREAM_STRIDE = lock->pitch & 0x00001fff; + slay->regs.SSTREAM_WIN_START = OS_XY(dest->x, dest->y); + slay->regs.SSTREAM_WIN_SIZE = OS_WH(drw_w, drw_h); + + /* remember pitch */ + slay->video_pitch *= lock->pitch; +} + +/* primary layer functions */ +static int +savagePrimaryLayerDataSize( void ) +{ + SVGDBG("savagePrimaryLayerDataSize\n"); + return sizeof(SavagePrimaryLayerData); +} + +static DFBResult +savagePrimaryInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *default_config, + DFBColorAdjustment *default_adj ) +{ + SavagePrimaryLayerData *play = (SavagePrimaryLayerData*) layer_data; + DFBResult ret; + + SVGDBG("savagePrimaryInitLayer w:%i h:%i bpp:%i\n", + dfb_config->mode.width, dfb_config->mode.height, + dfb_config->mode.depth); + + /* call the original initialization function first */ + ret = savage_pfuncs.InitLayer (layer, driver_data, layer_data, + description, default_config, default_adj); + if (ret) + return ret; + + /* set name */ + snprintf(description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, + "Savage Primary Stream"); + + /* add support for options */ + default_config->flags |= DLCONF_OPTIONS; + default_config->options = DLOP_NONE; + + /* add capabilities */ + description->caps |= DLCAPS_SCREEN_LOCATION; + + play->init = false; + + return DFB_OK; +} + +static DFBResult +savagePrimarySetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + SavagePrimaryLayerData *play = (SavagePrimaryLayerData*) layer_data; + DFBResult ret; + + SVGDBG("savagePrimarySetConfiguration w:%i h:%i bpp:%i\n", + config->width, config->height, + DFB_BYTES_PER_PIXEL(config->format) * 8); + + ret = savage_pfuncs.SetRegion(layer, driver_data, layer_data, region_data, + config, updated, surface, palette, lock); + if (ret != DFB_OK) + return ret; + + /* remember configuration */ + play->config = *config; + play->lock = lock; + + primary_calc_regs(sdrv, play, layer, config, surface, lock); + primary_set_regs(sdrv, play); + + return DFB_OK; +} + +DisplayLayerFuncs savagePrimaryFuncs = { + .LayerDataSize = savagePrimaryLayerDataSize, + .InitLayer = savagePrimaryInitLayer, + .SetRegion = savagePrimarySetRegion, +}; + +/* primary internal */ +static void +primary_set_regs(SavageDriverData *sdrv, SavagePrimaryLayerData *play) +{ + volatile u8 *mmio = sdrv->mmio_base; + + SVGDBG("primary_set_regs\n"); + + /* turn streams on */ + streamOnOff(sdrv, 1); + + /* setup primary stream */ + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_WINDOW_START, + play->regs.PSTREAM_WIN_START); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_WINDOW_SIZE, + play->regs.PSTREAM_WIN_SIZE); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_FRAME_BUFFER_ADDRESS0, + play->regs.PSTREAM_FB_ADDR0); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_FRAME_BUFFER_ADDRESS1, + play->regs.PSTREAM_FB_ADDR1); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_STRIDE, + play->regs.PSTREAM_STRIDE); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_CONTROL, + play->regs.PSTREAM_CTRL); + savage_out32(mmio, SAVAGE_PRIMARY_STREAM_FRAME_BUFFER_SIZE, + play->regs.PSTREAM_FB_SIZE); + + if (!play->init) { + /* tweak */ + /* fifo fetch delay register */ + vga_out8( mmio, 0x3d4, 0x85 ); + SVGDBG( "cr85: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + vga_out8( mmio, 0x3d5, 0x00 ); + + /* force high priority for display channel memory */ + vga_out8( mmio, 0x3d4, 0x88 ); + SVGDBG( "cr88: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + vga_out8( mmio, 0x3d5, vga_in8( mmio, 0x3d5 ) & ~0x01 ); + + /* primary stream timeout register */ + vga_out8( mmio, 0x3d4, 0x71 ); + SVGDBG( "cr71: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + + /* secondary stream timeout register */ + vga_out8( mmio, 0x3d4, 0x73 ); + SVGDBG( "cr73: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + + /* set primary stream to use memory mapped io */ + vga_out8( mmio, 0x3d4, 0x69 ); + SVGDBG( "cr69: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + vga_out8( mmio, 0x3d5, vga_in8( mmio, 0x3d5 ) | 0x80 ); + + /* enable certain registers to be loaded on vsync */ + vga_out8( mmio, 0x3d4, 0x51 ); + SVGDBG( "cr51: 0x%02x\n", vga_in8( mmio, 0x3d5 ) ); + vga_out8( mmio, 0x3d5, vga_in8( mmio, 0x3d5 ) | 0x80 ); + + /* setup secondary stream */ + savage_out32(mmio, SAVAGE_CHROMA_KEY_CONTROL, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_CONTROL, 0); + savage_out32(mmio, SAVAGE_CHROMA_KEY_UPPER_BOUND, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_HORIZONTAL_SCALING, 0); + savage_out32(mmio, SAVAGE_COLOR_ADJUSTMENT, 0); + savage_out32(mmio, SAVAGE_BLEND_CONTROL, 1 << 24); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_MULTIPLE_BUFFER_SUPPORT, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS0, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS1, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_ADDRESS2, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_FRAME_BUFFER_SIZE, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_STRIDE, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_VERTICAL_SCALING, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_SOURCE_LINE_COUNT, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_VERTICAL_INITIAL_VALUE, 0); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_WINDOW_START, + OS_XY(0xfffe, 0xfffe)); + savage_out32(mmio, SAVAGE_SECONDARY_STREAM_WINDOW_SIZE, + OS_WH(10,2)); + + play->init = true; + } +} + +static void +primary_calc_regs(SavageDriverData *sdrv, + SavagePrimaryLayerData *play, + CoreLayer *layer, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock) +{ + DFBRectangle *dest = &config->dest; + + SVGDBG("primary_calc_regs w:%i h:%i pitch:%i video.offset:%x\n", + surface->config.size.w, surface->config.size.h, lock->pitch, lock->offset); + + switch (surface->config.format) { + case DSPF_ARGB1555: + SVGDBG("primary set to DSPF_ARGB1555\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_KRGB16; + break; + case DSPF_RGB16: + SVGDBG("primary set to DSPF_RGB16\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_RGB16; + break; + case DSPF_RGB24: + SVGDBG("primary set to DSPF_RGB24 (unaccelerated)\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_RGB24; + break; + case DSPF_RGB32: + SVGDBG("primary set to DSPF_RGB32\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_RGB32; + break; + case DSPF_ARGB: + SVGDBG("primary set to DSPF_ARGB\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_ARGB; + break; + case DSPF_RGB332: + SVGDBG("primary set to DSPF_RGB332\n"); + play->regs.PSTREAM_CTRL = SAVAGE_PRIMARY_STREAM_CONTROL_PSIDF_CLUT; + break; + default: + D_BUG("unexpected primary pixelformat"); + return; + } + + play->regs.PSTREAM_FB_ADDR0 = lock->offset & 0x01ffffff; + play->regs.PSTREAM_FB_ADDR1 = 0; + play->regs.PSTREAM_STRIDE = lock->pitch & 0x00001fff; + play->regs.PSTREAM_WIN_START = OS_XY(dest->x, dest->y); + play->regs.PSTREAM_WIN_SIZE = OS_WH(dest->w, dest->h); + play->regs.PSTREAM_FB_SIZE = (((lock->pitch * + surface->config.size.h) / 8) - 1) & 0x003fffff; +} +/* end of code */ -- cgit