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; }
void sh7722_lcd_setup( void *drv, int width, int height, ulong phys, int pitch, DFBSurfacePixelFormat format, bool swap ) { u32 MLDDFR = 0; u32 LDDDSR = 0; D_DEBUG_AT( SH7722_LCD, "%s( %dx%d @%lu:%d )\n", __FUNCTION__, width, height, phys, pitch ); D_ASSERT( width > 7 ); D_ASSERT( height > 0 ); D_ASSERT( (phys & 7) == 0 ); D_ASSERT( pitch > 0 ); D_ASSERT( pitch < 0x10000 ); D_ASSERT( (pitch & 3) == 0 ); /* Choose input format. */ switch (format) { case DSPF_RGB32: case DSPF_ARGB: MLDDFR = 0; break; case DSPF_RGB16: MLDDFR = 3; break; case DSPF_RGB444: case DSPF_ARGB4444: MLDDFR = 8; break; case DSPF_RGB24: MLDDFR = 11; break; case DSPF_NV12: MLDDFR = 0x10000; break; case DSPF_NV16: MLDDFR = 0x10100; break; default: D_BUG( "invalid format" ); return; } /* Setup swapping. */ switch (format) { case DSPF_NV12: /* 1 byte */ case DSPF_NV16: case DSPF_RGB24: LDDDSR = 7; break; case DSPF_RGB16: /* 2 byte */ case DSPF_RGB444: case DSPF_ARGB4444: LDDDSR = 6; break; case DSPF_RGB32: /* 4 byte */ case DSPF_ARGB: LDDDSR = 4; break; default: D_BUG( "invalid format" ); return; } SH7722_SETREG32( drv, LCDC_MLDDCKPAT1R, 0x05555555 ); SH7722_SETREG32( drv, LCDC_MLDDCKPAT2R, 0x55555555 ); SH7722_SETREG32( drv, LCDC_LDDCKR, 0x0000003c ); SH7722_SETREG32( drv, LCDC_MLDMT2R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDMT3R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDDFR, MLDDFR ); SH7722_SETREG32( drv, LCDC_MLDSM1R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDSM2R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDSA1R, phys ); SH7722_SETREG32( drv, LCDC_MLDSA2R, DFB_PLANAR_PIXELFORMAT( format ) ? (phys + pitch * height) : 0 ); SH7722_SETREG32( drv, LCDC_MLDMLSR, pitch ); SH7722_SETREG32( drv, LCDC_MLDWBCNTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDWBAR, 0x00000000 ); #if 0 SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x18000006 ); SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1056 / 8) ); SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((128 / 8) << 16) | (840 / 8) ); SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 525 ); SH7722_SETREG32( drv, LCDC_MLDVSYNR, (2 << 16) | 490 ); SH7722_SETREG32( drv, LCDC_MLDPMR, 0xf6000f00 ); #elif 0 SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060); SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052); SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e00200); SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0); SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel #elif defined(SH7722_ALGO_PANEL) SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060); SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052); SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e0020e); SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0); SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel #elif defined(ALGO_AP325) SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1800000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1000 / 8) ); SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((8 / 8) << 16) | (960 / 8) ); SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 624 ); SH7722_SETREG32( drv, LCDC_MLDVSYNR, (1 << 16) | 560 ); SH7722_SETREG32( drv, LCDC_MLDPMR, 0xf6000f00 ); #endif SH7722_SETREG32( drv, LCDC_LDINTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDRCNTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDDDSR, swap ? LDDDSR : 0 ); SH7722_SETREG32( drv, LCDC_LDRCR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDPALCR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDCNT1R, 0x00000001 ); SH7722_SETREG32( drv, LCDC_LDCNT2R, 0x00000003 ); }
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; } /* * Setup LCD buffer. */ 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 JPEG reload buffers in master here, slaves do it in driver_init_driver(). */ sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset ); 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) ); /* * Setup JPEG reload buffers. */ sdev->jpeg_size = SH7722GFX_JPEG_RELOAD_SIZE * 2 + SH7722GFX_JPEG_LINEBUFFER_SIZE * 2; sdev->jpeg_offset = dfb_gfxcard_reserve_memory( device, sdev->jpeg_size ); if (sdev->jpeg_offset < 0) { D_ERROR( "SH7722/Driver: Allocating %d bytes for the JPEG reload and line buffers failed!\n", sdev->jpeg_size ); return DFB_FAILURE; } sdev->jpeg_phys = dfb_gfxcard_memory_physical( device, sdev->jpeg_offset ); sdev->jpeg_lb1 = sdev->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE * 2; sdev->jpeg_lb2 = sdev->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE; /* Get virtual addresses for JPEG reload buffers in master here, slaves do it in driver_init_driver(). */ sdrv->jpeg_virt = dfb_gfxcard_memory_virtual( device, sdev->jpeg_offset ); D_INFO( "SH7722/JPEG: Allocated reload and line buffers (%d bytes) at 0x%08lx (%p)\n", sdev->jpeg_size, sdev->jpeg_phys, sdrv->jpeg_virt ); D_ASSERT( ! (sdev->jpeg_size & 0xff) ); D_ASSERT( ! (sdev->jpeg_phys & 0xf) ); /* 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; } /* * Initialize hardware. */ /* Reset the drawing engine. */ sh7722EngineReset( sdrv, sdev ); /* 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 ); /* 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; } /* * 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 ); /* 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 ); /* Initialize BEU lock. */ fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) ); /* Initialize JPEG lock. */ fusion_skirmish_init( &sdev->jpeg_lock, "JPEG", dfb_core_world(sdrv->core) ); return DFB_OK; }
void sh7722_lcd_setup( void *drv, int width, int height, ulong phys, int pitch, DFBSurfacePixelFormat format, bool swap ) { u32 MLDDFR = 0; u32 LDDDSR = 0; u32 reg; D_DEBUG_AT( SH7722_LCD, "%s( %dx%d @%lu:%d )\n", __FUNCTION__, width, height, phys, pitch ); D_ASSERT( width > 7 ); D_ASSERT( height > 0 ); D_ASSERT( (phys & 7) == 0 ); D_ASSERT( pitch > 0 ); D_ASSERT( pitch < 0x10000 ); D_ASSERT( (pitch & 3) == 0 ); /* Choose input format. */ switch (format) { case DSPF_RGB32: case DSPF_ARGB: MLDDFR = 0; break; case DSPF_RGB16: MLDDFR = 3; break; case DSPF_RGB444: case DSPF_ARGB4444: MLDDFR = 8; break; case DSPF_RGB24: MLDDFR = 11; break; case DSPF_NV12: MLDDFR = 0x10000; break; case DSPF_NV16: MLDDFR = 0x10100; break; default: D_BUG( "invalid format" ); return; } /* Setup swapping. */ switch (format) { case DSPF_NV12: /* 1 byte */ case DSPF_NV16: case DSPF_RGB24: LDDDSR = 7; break; case DSPF_RGB16: /* 2 byte */ case DSPF_RGB444: case DSPF_ARGB4444: LDDDSR = 6; break; case DSPF_RGB32: /* 4 byte */ case DSPF_ARGB: LDDDSR = 4; break; default: D_BUG( "invalid format" ); return; } /* software reset of the LCD device */ reg = SH7722_GETREG32( drv, LCDC_LDCNT2R ); SH7722_SETREG32( drv, LCDC_LDCNT2R, reg | 0x100 ); while( SH7722_GETREG32( drv, LCDC_LDCNT2R ) & 0x100 ); /* stop the LCD while configuring */ SH7722_SETREG32( drv, LCDC_LDCNT2R, 0 ); SH7722_SETREG32( drv, LCDC_LDDCKSTPR, 1 ); SH7722_SETREG32( drv, LCDC_MLDDCKPAT1R, 0x05555555 ); SH7722_SETREG32( drv, LCDC_MLDDCKPAT2R, 0x55555555 ); SH7722_SETREG32( drv, LCDC_LDDCKR, 0x0000003c ); SH7722_SETREG32( drv, LCDC_MLDMT2R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDMT3R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDDFR, MLDDFR ); SH7722_SETREG32( drv, LCDC_MLDSM1R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDSM2R, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDSA1R, phys ); SH7722_SETREG32( drv, LCDC_MLDSA2R, DFB_PLANAR_PIXELFORMAT( format ) ? (phys + pitch * height) : 0 ); SH7722_SETREG32( drv, LCDC_MLDMLSR, pitch ); SH7722_SETREG32( drv, LCDC_MLDWBCNTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_MLDWBAR, 0x00000000 ); #if 0 SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x18000006 ); SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1056 / 8) ); SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((128 / 8) << 16) | (840 / 8) ); SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 525 ); SH7722_SETREG32( drv, LCDC_MLDVSYNR, (2 << 16) | 490 ); SH7722_SETREG32( drv, LCDC_MLDPMR, 0xf6000f00 ); #elif 0 SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060); SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052); SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e00200); SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0); SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel #elif defined(SH7722_ALGO_PANEL) SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1c00000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, 0x00500060); SH7722_SETREG32( drv, LCDC_MLDHSYNR, 0x00010052); SH7722_SETREG32( drv, LCDC_MLDVLNR, 0x01e0020e); SH7722_SETREG32( drv, LCDC_MLDVSYNR, 0x000301f0); SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); //igel #elif defined(ALGO_AP325) SH7722_SETREG32( drv, LCDC_MLDMT1R, 0x1800000a ); SH7722_SETREG32( drv, LCDC_MLDHCNR, ((width / 8) << 16) | (1000 / 8) ); SH7722_SETREG32( drv, LCDC_MLDHSYNR, ((8 / 8) << 16) | (960 / 8) ); SH7722_SETREG32( drv, LCDC_MLDVLNR, (height << 16) | 624 ); SH7722_SETREG32( drv, LCDC_MLDVSYNR, (1 << 16) | 560 ); SH7722_SETREG32( drv, LCDC_MLDPMR, 0x00000000 ); #endif SH7722_SETREG32( drv, LCDC_LDINTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDRCNTR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDDDSR, swap ? LDDDSR : 0 ); SH7722_SETREG32( drv, LCDC_LDRCR, 0x00000000 ); SH7722_SETREG32( drv, LCDC_LDPALCR, 0x00000000 ); /* enable and start displaying */ SH7722_SETREG32( drv, LCDC_LDCNT1R, 0x00000001 ); SH7722_SETREG32( drv, LCDC_LDCNT2R, 0x00000003 ); SH7722_SETREG32( drv, LCDC_LDDCKSTPR, 0 ); while( SH7722_GETREG32( drv, LCDC_LDDCKSTPR ) & 0x10000 ); /* finally, turn the display on */ { SH7722DriverData *sdrv = drv; if (ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_POWER_DISPLAY ) < 0) D_PERROR( "SH772xGFX_IOCTL_POWER_DISPLAY\n" ); } }
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 DFBResult sh7722FlipRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreSurface *surface, DFBSurfaceFlipFlags flags, CoreSurfaceBufferLock *left_lock, CoreSurfaceBufferLock *right_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 = left_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), left_lock->pitch ); /* Set buffer offset (Y plane or RGB packed). */ SH7722_SETREG32( sdrv, BMSAYR(n), left_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), left_lock->phys + left_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 sh7722SetRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags updated, CoreSurface *surface, CorePalette *palette, CoreSurfaceBufferLock *left_lock, CoreSurfaceBufferLock *right_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 = left_lock->buffer; D_ASSERT( buffer != NULL ); /* Set buffer pitch. */ SH7722_SETREG32( sdrv, BMSMWR(n), left_lock->pitch ); /* Set buffer offset (Y plane or RGB packed). */ SH7722_SETREG32( sdrv, BMSAYR(n), left_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), left_lock->phys + left_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; }