summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/sh772x/sh7722_multi.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/sh772x/sh7722_multi.c412
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,
+};
+