diff options
Diffstat (limited to 'Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c')
-rwxr-xr-x | Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c new file mode 100755 index 0000000..d15871d --- /dev/null +++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c @@ -0,0 +1,412 @@ +#ifdef SH7722_DEBUG_LAYER +#define DIRECT_ENABLE_DEBUG +#endif + + +#include <config.h> + +#include <stdio.h> + +#include <sys/mman.h> + +#include <asm/types.h> + +#include <directfb.h> + +#include <fusion/fusion.h> +#include <fusion/shmalloc.h> + +#include <core/core.h> +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/layers.h> +#include <core/palette.h> +#include <core/surface.h> +#include <core/surface_buffer.h> +#include <core/system.h> + +#include <gfx/convert.h> + +#include <misc/conf.h> + +#include <direct/memcpy.h> +#include <direct/messages.h> + +#include "sh7722.h" +#include "sh7722_types.h" +#include "sh7722_multi.h" + + +D_DEBUG_DOMAIN( SH7722_Layer, "SH7722/Layer", "Renesas SH7722 Layers" ); + +/**********************************************************************************************************************/ + +static int +sh7722LayerDataSize( void ) +{ + return sizeof(SH7722MultiLayerData); +} + +static int +sh7722RegionDataSize( void ) +{ + return sizeof(SH7722MultiRegionData); +} + +static DFBResult +sh7722InitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = sdrv->dev; + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + /* set capabilities and type */ + description->caps = DLCAPS_SURFACE | DLCAPS_SCREEN_POSITION | DLCAPS_SRC_COLORKEY | DLCAPS_WINDOWS; + description->type = DLTF_GRAPHICS; + description->regions = 4; + + /* set name */ + snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Multi Window" ); + + /* fill out the default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS; + config->width = sdev->lcd_width; + config->height = sdev->lcd_height; + config->pixelformat = DSPF_NV16; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_NONE; + + return DFB_OK; +} + +static DFBResult +sh7722TestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfigFlags fail = 0; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + if (config->options & ~SH7722_MULTI_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + switch (config->format) { + case DSPF_ARGB: + case DSPF_RGB32: + case DSPF_RGB24: + case DSPF_RGB16: + break; + +#if FIXME_MAKE_CONFIGURABLE_ + case DSPF_NV12: + case DSPF_NV16: + break; +#endif + + default: + fail |= CLRCF_FORMAT; + } + + if (config->width < 32 || config->width > 1280) + fail |= CLRCF_WIDTH; + + if (config->height < 32 || config->height > 1024) + fail |= CLRCF_HEIGHT; + + + if (failed) + *failed = fail; + + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +sh7722AddRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config ) +{ + int n; + SH7722MultiRegionData *sreg = region_data; + SH7722MultiLayerData *slay = layer_data; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + if (slay->added == 0xF) + return DFB_LIMITEXCEEDED; + + for (n=0; n<4; n++) + if (! (slay->added & (1 << n))) + break; + + D_ASSERT( n < 4 ); + + sreg->config = *config; + + + slay->added |= 1 << n; + + D_MAGIC_SET( sreg, SH7722MultiRegionData ); + + return DFB_OK; +} + +static DFBResult +sh7722SetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + int n; + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = sdrv->dev; + SH7722MultiRegionData *sreg = region_data; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( sreg, SH7722MultiRegionData ); + + fusion_skirmish_prevail( &sdev->beu_lock ); + + /* Wait for idle BEU. */ + BEU_Wait( sdrv, sdev ); + + n = sreg->index; + + D_ASSERT( n >= 0 ); + D_ASSERT( n <= 3 ); + + /* Update position? */ + if (updated & CLRCF_DEST) { + /* Set horizontal and vertical offset. */ + SH7722_SETREG32( sdrv, BMLOCR(n), (config->dest.y << 16) | config->dest.x ); + } + + /* Update size? */ + if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT)) { + /* Set width and height. */ + SH7722_SETREG32( sdrv, BMSSZR(n), (config->height << 16) | config->width ); + } + + /* Update surface? */ + if (updated & CLRCF_SURFACE) { + CoreSurfaceBuffer *buffer; + + D_ASSERT( surface != NULL ); + + buffer = lock->buffer; + + D_ASSERT( buffer != NULL ); + + /* Set buffer pitch. */ + SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch ); + + /* Set buffer offset (Y plane or RGB packed). */ + SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys ); + + /* Set buffer offset (UV plane). */ + if (DFB_PLANAR_PIXELFORMAT(buffer->format)) { + D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 ); + + SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h ); + } + } + + /* Update format? */ + if (updated & CLRCF_FORMAT) { + unsigned long tBMSIFR = 0; + + /* Set pixel format. */ + switch (config->format) { + case DSPF_NV12: + tBMSIFR |= CHRR_YCBCR_420; + break; + + case DSPF_NV16: + tBMSIFR |= CHRR_YCBCR_422; + break; + + case DSPF_ARGB: + tBMSIFR |= RPKF_ARGB; + break; + + case DSPF_RGB32: + tBMSIFR |= RPKF_RGB32; + break; + + case DSPF_RGB24: + tBMSIFR |= RPKF_RGB24; + break; + + case DSPF_RGB16: + tBMSIFR |= RPKF_RGB16; + break; + + default: + break; + } + + /* FIXME: all regions need to have the same format! */ + SH7722_SETREG32( sdrv, BMSIFR, tBMSIFR ); + } + + SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) | (1 << n) ); + + fusion_skirmish_dismiss( &sdev->beu_lock ); + + return DFB_OK; +} + +static DFBResult +sh7722RemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + int n; + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = sdrv->dev; + SH7722MultiRegionData *sreg = region_data; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + D_MAGIC_ASSERT( sreg, SH7722MultiRegionData ); + + n = sreg->index; + + D_ASSERT( n >= 0 ); + D_ASSERT( n <= 3 ); + + fusion_skirmish_prevail( &sdev->beu_lock ); + + /* Wait for idle BEU. */ + BEU_Wait( sdrv, sdev ); + + /* Disable multi window. */ + SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~(1 << n) ); + + /* Start operation! */ + BEU_Start( sdrv, sdev ); + + fusion_skirmish_dismiss( &sdev->beu_lock ); + + return DFB_OK; +} + +static DFBResult +sh7722FlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + int n; + CoreSurfaceBuffer *buffer; + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = sdrv->dev; + SH7722MultiRegionData *sreg = region_data; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + D_ASSERT( surface != NULL ); + D_ASSERT( sdrv != NULL ); + D_ASSERT( sdev != NULL ); + D_MAGIC_ASSERT( sreg, SH7722MultiRegionData ); + + n = sreg->index; + + D_ASSERT( n >= 0 ); + D_ASSERT( n <= 3 ); + + buffer = lock->buffer; + D_ASSERT( buffer != NULL ); + + fusion_skirmish_prevail( &sdev->beu_lock ); + + /* Wait for idle BEU. */ + BEU_Wait( sdrv, sdev ); + + /* Set buffer pitch. */ + SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch ); + + /* Set buffer offset (Y plane or RGB packed). */ + SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys ); + + /* Set buffer offset (UV plane). */ + if (DFB_PLANAR_PIXELFORMAT(buffer->format)) { + D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 ); + + SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h ); + } + + /* Start operation! */ + BEU_Start( sdrv, sdev ); + + fusion_skirmish_dismiss( &sdev->beu_lock ); + + /* Wait for idle BEU? */ + if (flags & DSFLIP_WAIT) + BEU_Wait( sdrv, sdev ); + + dfb_surface_flip( surface, false ); + + return DFB_OK; +} + +static DFBResult +sh7722UpdateRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + const DFBRegion *update, + CoreSurfaceBufferLock *lock ) +{ + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = sdrv->dev; + + D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ ); + + D_ASSERT( surface != NULL ); + D_ASSERT( sdrv != NULL ); + D_ASSERT( sdev != NULL ); + + /* Start operation! */ + BEU_Start( sdrv, sdev ); + + return DFB_OK; +} + +DisplayLayerFuncs sh7722MultiLayerFuncs = { + .LayerDataSize = sh7722LayerDataSize, + .RegionDataSize = sh7722RegionDataSize, + .InitLayer = sh7722InitLayer, + + .TestRegion = sh7722TestRegion, + .AddRegion = sh7722AddRegion, + .SetRegion = sh7722SetRegion, + .RemoveRegion = sh7722RemoveRegion, + .FlipRegion = sh7722FlipRegion, + .UpdateRegion = sh7722UpdateRegion, +}; + |