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 --- Source/DirectFB/gfxdrivers/sh772x/sh7722.c | 490 +++++++++++++++++++++++++++++ 1 file changed, 490 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/sh772x/sh7722.c (limited to 'Source/DirectFB/gfxdrivers/sh772x/sh7722.c') diff --git a/Source/DirectFB/gfxdrivers/sh772x/sh7722.c b/Source/DirectFB/gfxdrivers/sh772x/sh7722.c new file mode 100755 index 0000000..4d09928 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/sh772x/sh7722.c @@ -0,0 +1,490 @@ +#ifdef SH7722_DEBUG_DRIVER +#define DIRECT_ENABLE_DEBUG +#endif + +#include +#include + +#undef HAVE_STDLIB_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +DFB_GRAPHICS_DRIVER( sh7722 ) + + +#include "sh7722.h" +#include "sh7722_blt.h" +#include "sh7722_jpeglib.h" +#include "sh7722_layer.h" +#include "sh7722_lcd.h" +#include "sh7722_multi.h" +#include "sh7722_screen.h" + +#include "sh7723_blt.h" + +#ifdef SH772X_FBDEV_SUPPORT +#include +#include +#endif + + +D_DEBUG_DOMAIN( SH7722_Driver, "SH7722/Driver", "Renesas SH7722 Driver" ); + +/**********************************************************************************************************************/ + +static int +driver_probe( CoreGraphicsDevice *device ) +{ + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + return dfb_gfxcard_get_accelerator( device ) == 0x2D47; +} + +static void +driver_get_info( CoreGraphicsDevice *device, + GraphicsDriverInfo *info ) +{ + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + /* fill driver info structure */ + snprintf( info->name, + DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, + "Renesas SH772x Driver" ); + + snprintf( info->vendor, + DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, + "Denis & Janine Kropp" ); + + info->version.major = 0; + info->version.minor = 9; + + info->driver_data_size = sizeof(SH7722DriverData); + info->device_data_size = sizeof(SH7722DeviceData); +} + +static DFBResult +driver_init_driver( CoreGraphicsDevice *device, + GraphicsDeviceFuncs *funcs, + void *driver_data, + void *device_data, + CoreDFB *core ) +{ + DFBResult ret; + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = device_data; + + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + /* Keep pointer to shared device data. */ + sdrv->dev = device_data; + + /* Keep core and device pointer. */ + sdrv->core = core; + sdrv->device = device; + + /* Open the drawing engine device. */ + sdrv->gfx_fd = direct_try_open( "/dev/sh772x_gfx", "/dev/misc/sh772x_gfx", O_RDWR, true ); + if (sdrv->gfx_fd < 0) + return DFB_INIT; + + /* Map its shared data. */ + sdrv->gfx_shared = mmap( NULL, direct_page_align( sizeof(SH772xGfxSharedArea) ), + PROT_READ | PROT_WRITE, + MAP_SHARED, sdrv->gfx_fd, 0 ); + if (sdrv->gfx_shared == MAP_FAILED) { + D_PERROR( "SH7722/Driver: Could not map shared area!\n" ); + close( sdrv->gfx_fd ); + return DFB_INIT; + } + + sdrv->mmio_base = dfb_gfxcard_map_mmio( device, 0, -1 ); + if (!sdrv->mmio_base) { + D_PERROR( "SH7722/Driver: Could not map MMIO area!\n" ); + munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) ); + close( sdrv->gfx_fd ); + return DFB_INIT; + } + + /* Check the magic value. */ + switch (sdrv->gfx_shared->magic) { + case SH7722GFX_SHARED_MAGIC: + sdev->sh772x = 7722; + + /* Initialize function table. */ + funcs->EngineReset = sh7722EngineReset; + funcs->EngineSync = sh7722EngineSync; + funcs->EmitCommands = sh7722EmitCommands; + funcs->CheckState = sh7722CheckState; + funcs->SetState = sh7722SetState; + funcs->FillTriangle = sh7722FillTriangle; + funcs->Blit = sh7722Blit; + funcs->StretchBlit = sh7722StretchBlit; + funcs->FlushTextureCache = sh7722FlushTextureCache; + + /* Initialize JPEG library. */ + ret = SH7722_JPEG_Initialize(); + if (ret) { + D_DERROR( ret, "SH7722/Driver: JPEG initialization failed!\n" ); + dfb_gfxcard_unmap_mmio( device, sdrv->mmio_base, -1 ); + munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) ); + close( sdrv->gfx_fd ); + return DFB_INIT; + } + break; + + case SH7723GFX_SHARED_MAGIC: + sdev->sh772x = 7723; + + /* Initialize function table. */ + funcs->EngineReset = sh7723EngineReset; + funcs->EngineSync = sh7723EngineSync; + funcs->EmitCommands = sh7723EmitCommands; + funcs->CheckState = sh7723CheckState; + funcs->SetState = sh7723SetState; + funcs->FillRectangle = sh7723FillRectangle; + funcs->FillTriangle = sh7723FillTriangle; + funcs->DrawRectangle = sh7723DrawRectangle; + funcs->DrawLine = sh7723DrawLine; + funcs->Blit = sh7723Blit; + break; + + default: + D_ERROR( "SH772x/Driver: Magic value 0x%08x doesn't match 0x%08x or 0x%08x!\n", + sdrv->gfx_shared->magic, SH7722GFX_SHARED_MAGIC, SH7723GFX_SHARED_MAGIC ); + dfb_gfxcard_unmap_mmio( device, sdrv->mmio_base, -1 ); + munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) ); + close( sdrv->gfx_fd ); + return DFB_INIT; + } + + + /* Get virtual address for the LCD buffer in slaves here, + master does it in driver_init_device(). */ +#ifndef SH772X_FBDEV_SUPPORT + if (!dfb_core_is_master( core )) + sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset ); +#endif + + + /* Register primary screen. */ + sdrv->screen = dfb_screens_register( device, driver_data, &sh7722ScreenFuncs ); + + /* Register three input system layers. */ + sdrv->input1 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs ); + sdrv->input2 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs ); + sdrv->input3 = dfb_layers_register( sdrv->screen, driver_data, &sh7722LayerFuncs ); + + /* Register multi window layer. */ + sdrv->multi = dfb_layers_register( sdrv->screen, driver_data, &sh7722MultiLayerFuncs ); + + return DFB_OK; +} + +static DFBResult +driver_init_device( CoreGraphicsDevice *device, + GraphicsDeviceInfo *device_info, + void *driver_data, + void *device_data ) +{ + SH7722DriverData *sdrv = driver_data; + SH7722DeviceData *sdev = device_data; + + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + /* FIXME: Add a runtime option / config file. */ + sdev->lcd_format = DSPF_RGB16; + + /* Check format of LCD buffer. */ + switch (sdev->lcd_format) { + case DSPF_RGB16: + case DSPF_NV16: + break; + + default: + return DFB_UNSUPPORTED; + } + + if (sdev->sh772x == 7723) + memset( dfb_gfxcard_memory_virtual(device,0), 0, dfb_gfxcard_memory_length() ); + + /* + * Setup LCD buffer. + */ +#ifdef SH772X_FBDEV_SUPPORT + { + struct fb_fix_screeninfo fsi; + struct fb_var_screeninfo vsi; + int fbdev; + + if ((fbdev = open("/dev/fb", O_RDONLY)) < 0) { + D_ERROR( "SH7722/Driver: Can't open fbdev to get LCDC info!\n" ); + return DFB_FAILURE; + } + + if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fsi) < 0) { + D_ERROR( "SH7722/Driver: FBIOGET_FSCREEINFO failed.\n" ); + close(fbdev); + return DFB_FAILURE; + } + + if (ioctl(fbdev, FBIOGET_VSCREENINFO, &vsi) < 0) { + D_ERROR( "SH7722/Driver: FBIOGET_VSCREEINFO failed.\n" ); + close(fbdev); + return DFB_FAILURE; + } + + sdev->lcd_width = vsi.xres; + sdev->lcd_height = vsi.yres; + sdev->lcd_pitch = fsi.line_length; + sdev->lcd_size = fsi.smem_len; + sdev->lcd_offset = 0; + sdev->lcd_phys = fsi.smem_start; +#if 0 + sdrv->lcd_virt = mmap(NULL, fsi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, + fbdev, 0); + if (sdrv->lcd_virt == MAP_FAILED) { + D_PERROR( "SH7722/Driver: mapping fbdev failed.\n" ); + close(fbdev); + return DFB_FAILURE; + } + + /* Clear LCD buffer. */ + switch (sdev->lcd_format) { + case DSPF_RGB16: + memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch ); + break; + + case DSPF_NV16: + memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch ); + memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch ); + break; + + default: + D_BUG( "unsupported format" ); + return DFB_BUG; + } +#endif + + close(fbdev); + } +#else + sdev->lcd_width = SH7722_LCD_WIDTH; + sdev->lcd_height = SH7722_LCD_HEIGHT; + sdev->lcd_pitch = (DFB_BYTES_PER_LINE( sdev->lcd_format, sdev->lcd_width ) + 0xf) & ~0xf; + sdev->lcd_size = DFB_PLANE_MULTIPLY( sdev->lcd_format, sdev->lcd_height ) * sdev->lcd_pitch; + sdev->lcd_offset = dfb_gfxcard_reserve_memory( device, sdev->lcd_size ); + + if (sdev->lcd_offset < 0) { + D_ERROR( "SH7722/Driver: Allocating %d bytes for the LCD buffer failed!\n", sdev->lcd_size ); + return DFB_FAILURE; + } + + sdev->lcd_phys = dfb_gfxcard_memory_physical( device, sdev->lcd_offset ); + + /* Get virtual addresses for LCD buffer in master here, + slaves do it in driver_init_driver(). */ + sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset ); +#endif + + D_INFO( "SH7722/LCD: Allocated %dx%d %s Buffer (%d bytes) at 0x%08lx (%p)\n", + sdev->lcd_width, sdev->lcd_height, dfb_pixelformat_name(sdev->lcd_format), + sdev->lcd_size, sdev->lcd_phys, sdrv->lcd_virt ); + + D_ASSERT( ! (sdev->lcd_pitch & 0xf) ); + D_ASSERT( ! (sdev->lcd_phys & 0xf) ); + + /* + * Initialize hardware. + */ + + switch (sdev->sh772x) { + case 7722: + /* Reset the drawing engine. */ + sh7722EngineReset( sdrv, sdev ); + + /* Fill in the device info. */ + snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "SH7722" ); + snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" ); + + /* Set device limitations. */ + device_info->limits.surface_byteoffset_alignment = 16; + device_info->limits.surface_bytepitch_alignment = 8; + + /* Set device capabilities. */ + device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS; + device_info->caps.accel = SH7722_SUPPORTED_DRAWINGFUNCTIONS | + SH7722_SUPPORTED_BLITTINGFUNCTIONS; + device_info->caps.drawing = SH7722_SUPPORTED_DRAWINGFLAGS; + device_info->caps.blitting = SH7722_SUPPORTED_BLITTINGFLAGS; + + /* Change font format for acceleration. */ + if (!dfb_config->software_only) { + dfb_config->font_format = DSPF_ARGB; + dfb_config->font_premult = false; + } + break; + + case 7723: + /* Reset the drawing engine. */ + sh7723EngineReset( sdrv, sdev ); + + /* Fill in the device info. */ + snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "SH7723" ); + snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" ); + + /* Set device limitations. */ + device_info->limits.surface_byteoffset_alignment = 512; + device_info->limits.surface_bytepitch_alignment = 64; + + /* Set device capabilities. */ + device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS; + device_info->caps.accel = SH7723_SUPPORTED_DRAWINGFUNCTIONS | \ + SH7723_SUPPORTED_BLITTINGFUNCTIONS; + device_info->caps.drawing = SH7723_SUPPORTED_DRAWINGFLAGS; + device_info->caps.blitting = SH7723_SUPPORTED_BLITTINGFLAGS; + + break; + + default: + D_BUG( "unexpected device" ); + return DFB_BUG; + } + + + /* Wait for idle BEU. */ + while (SH7722_GETREG32( sdrv, BSTAR ) & 1); + + /* Disable all inputs. */ + SH7722_SETREG32( sdrv, BESTR, 0 ); + + /* Disable all multi windows. */ + SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~0xf ); + +#ifndef SH772X_FBDEV_SUPPORT + /* Clear LCD buffer. */ + switch (sdev->lcd_format) { + case DSPF_RGB16: + memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch ); + break; + + case DSPF_NV16: + memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch ); + memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch ); + break; + + default: + D_BUG( "unsupported format" ); + return DFB_BUG; + } +#endif + + /* + * TODO: Make LCD Buffer format and primary BEU format runtime configurable. + */ + + /* Set output pixel format of the BEU. */ + switch (sdev->lcd_format) { + case DSPF_RGB16: + SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | WPCK_RGB16 ); + break; + + case DSPF_NV16: + SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | BPKFR_TE_ENABLED | CHDS_YCBCR422 ); + SH7722_SETREG32( sdrv, BDACR, sdev->lcd_phys + sdev->lcd_height * sdev->lcd_pitch ); + break; + + default: + D_BUG( "unsupported format" ); + return DFB_BUG; + } + + SH7722_SETREG32( sdrv, BPROCR, 0x00000000 ); + + /* Have BEU render into LCD buffer. */ + SH7722_SETREG32( sdrv, BBLCR1, MT_MEMORY ); + SH7722_SETREG32( sdrv, BDAYR, sdev->lcd_phys & 0xfffffffc ); + SH7722_SETREG32( sdrv, BDMWR, sdev->lcd_pitch & 0x0003fffc ); + +#ifndef SH772X_FBDEV_SUPPORT + /* Setup LCD controller to show the buffer. */ + sh7722_lcd_setup( sdrv, sdev->lcd_width, sdev->lcd_height, + sdev->lcd_phys, sdev->lcd_pitch, sdev->lcd_format, false ); +#endif + + /* Initialize BEU lock. */ + fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) ); + + return DFB_OK; +} + +static void +driver_close_device( CoreGraphicsDevice *device, + void *driver_data, + void *device_data ) +{ + SH7722DeviceData *sdev = device_data; + + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + /* Destroy BEU lock. */ + fusion_skirmish_destroy( &sdev->beu_lock ); +} + +static void +driver_close_driver( CoreGraphicsDevice *device, + void *driver_data ) +{ + SH7722DriverData *sdrv = driver_data; + SH772xGfxSharedArea *shared = sdrv->gfx_shared; + + (void) shared; + + D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); + + D_INFO( "SH7722/BLT: %u starts, %u done, %u interrupts, %u wait_idle, %u wait_next, %u idle\n", + shared->num_starts, shared->num_done, shared->num_interrupts, + shared->num_wait_idle, shared->num_wait_next, shared->num_idle ); + + D_INFO( "SH7722/BLT: %u words, %u words/start, %u words/idle, %u starts/idle\n", + shared->num_words, + shared->num_words / shared->num_starts, + shared->num_words / shared->num_idle, + shared->num_starts / shared->num_idle ); + + /* Shutdown JPEG library. */ + SH7722_JPEG_Shutdown(); + + /* Unmap shared area. */ + munmap( (void*) sdrv->gfx_shared, direct_page_align( sizeof(SH772xGfxSharedArea) ) ); + + /* Close Drawing Engine device. */ + close( sdrv->gfx_fd ); +} + -- cgit