2010-11-09 02:42:39 +03:00
/*
* linux / drivers / video / wmt_ge_rops . c
*
* Accelerators for raster operations using WonderMedia Graphics Engine
*
* Copyright ( C ) 2010 Alexey Charkov < alchark @ gmail . com >
*
* This software is licensed under the terms of the GNU General Public
* License version 2 , as published by the Free Software Foundation , and
* may be copied , distributed , and modified under those terms .
*
* This program 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 General Public License for more details .
*/
# include <linux/module.h>
# include <linux/fb.h>
# include <linux/platform_device.h>
# include "fb_draw.h"
# define GE_COMMAND_OFF 0x00
# define GE_DEPTH_OFF 0x04
# define GE_HIGHCOLOR_OFF 0x08
# define GE_ROPCODE_OFF 0x14
# define GE_FIRE_OFF 0x18
# define GE_SRCBASE_OFF 0x20
# define GE_SRCDISPW_OFF 0x24
# define GE_SRCDISPH_OFF 0x28
# define GE_SRCAREAX_OFF 0x2c
# define GE_SRCAREAY_OFF 0x30
# define GE_SRCAREAW_OFF 0x34
# define GE_SRCAREAH_OFF 0x38
# define GE_DESTBASE_OFF 0x3c
# define GE_DESTDISPW_OFF 0x40
# define GE_DESTDISPH_OFF 0x44
# define GE_DESTAREAX_OFF 0x48
# define GE_DESTAREAY_OFF 0x4c
# define GE_DESTAREAW_OFF 0x50
# define GE_DESTAREAH_OFF 0x54
# define GE_PAT0C_OFF 0x88 /* Pattern 0 color */
# define GE_ENABLE_OFF 0xec
# define GE_INTEN_OFF 0xf0
# define GE_STATUS_OFF 0xf8
static void __iomem * regbase ;
void wmt_ge_fillrect ( struct fb_info * p , const struct fb_fillrect * rect )
{
unsigned long fg , pat ;
if ( p - > state ! = FBINFO_STATE_RUNNING )
return ;
if ( p - > fix . visual = = FB_VISUAL_TRUECOLOR | |
p - > fix . visual = = FB_VISUAL_DIRECTCOLOR )
fg = ( ( u32 * ) ( p - > pseudo_palette ) ) [ rect - > color ] ;
else
fg = rect - > color ;
pat = pixel_to_pat ( p - > var . bits_per_pixel , fg ) ;
if ( p - > fbops - > fb_sync )
p - > fbops - > fb_sync ( p ) ;
writel ( p - > var . bits_per_pixel = = 32 ? 3 :
( p - > var . bits_per_pixel = = 8 ? 0 : 1 ) , regbase + GE_DEPTH_OFF ) ;
writel ( p - > var . bits_per_pixel = = 15 ? 1 : 0 , regbase + GE_HIGHCOLOR_OFF ) ;
writel ( p - > fix . smem_start , regbase + GE_DESTBASE_OFF ) ;
writel ( p - > var . xres_virtual - 1 , regbase + GE_DESTDISPW_OFF ) ;
writel ( p - > var . yres_virtual - 1 , regbase + GE_DESTDISPH_OFF ) ;
writel ( rect - > dx , regbase + GE_DESTAREAX_OFF ) ;
writel ( rect - > dy , regbase + GE_DESTAREAY_OFF ) ;
writel ( rect - > width - 1 , regbase + GE_DESTAREAW_OFF ) ;
writel ( rect - > height - 1 , regbase + GE_DESTAREAH_OFF ) ;
writel ( pat , regbase + GE_PAT0C_OFF ) ;
writel ( 1 , regbase + GE_COMMAND_OFF ) ;
writel ( rect - > rop = = ROP_XOR ? 0x5a : 0xf0 , regbase + GE_ROPCODE_OFF ) ;
writel ( 1 , regbase + GE_FIRE_OFF ) ;
}
EXPORT_SYMBOL_GPL ( wmt_ge_fillrect ) ;
void wmt_ge_copyarea ( struct fb_info * p , const struct fb_copyarea * area )
{
if ( p - > state ! = FBINFO_STATE_RUNNING )
return ;
if ( p - > fbops - > fb_sync )
p - > fbops - > fb_sync ( p ) ;
writel ( p - > var . bits_per_pixel > 16 ? 3 :
( p - > var . bits_per_pixel > 8 ? 1 : 0 ) , regbase + GE_DEPTH_OFF ) ;
writel ( p - > fix . smem_start , regbase + GE_SRCBASE_OFF ) ;
writel ( p - > var . xres_virtual - 1 , regbase + GE_SRCDISPW_OFF ) ;
writel ( p - > var . yres_virtual - 1 , regbase + GE_SRCDISPH_OFF ) ;
writel ( area - > sx , regbase + GE_SRCAREAX_OFF ) ;
writel ( area - > sy , regbase + GE_SRCAREAY_OFF ) ;
writel ( area - > width - 1 , regbase + GE_SRCAREAW_OFF ) ;
writel ( area - > height - 1 , regbase + GE_SRCAREAH_OFF ) ;
writel ( p - > fix . smem_start , regbase + GE_DESTBASE_OFF ) ;
writel ( p - > var . xres_virtual - 1 , regbase + GE_DESTDISPW_OFF ) ;
writel ( p - > var . yres_virtual - 1 , regbase + GE_DESTDISPH_OFF ) ;
writel ( area - > dx , regbase + GE_DESTAREAX_OFF ) ;
writel ( area - > dy , regbase + GE_DESTAREAY_OFF ) ;
writel ( area - > width - 1 , regbase + GE_DESTAREAW_OFF ) ;
writel ( area - > height - 1 , regbase + GE_DESTAREAH_OFF ) ;
writel ( 0xcc , regbase + GE_ROPCODE_OFF ) ;
writel ( 1 , regbase + GE_COMMAND_OFF ) ;
writel ( 1 , regbase + GE_FIRE_OFF ) ;
}
EXPORT_SYMBOL_GPL ( wmt_ge_copyarea ) ;
int wmt_ge_sync ( struct fb_info * p )
{
int loops = 5000000 ;
while ( ( readl ( regbase + GE_STATUS_OFF ) & 4 ) & & - - loops )
cpu_relax ( ) ;
return loops > 0 ? 0 : - EBUSY ;
}
EXPORT_SYMBOL_GPL ( wmt_ge_sync ) ;
static int __devinit wmt_ge_rops_probe ( struct platform_device * pdev )
{
struct resource * res ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
if ( res = = NULL ) {
dev_err ( & pdev - > dev , " no I/O memory resource defined \n " ) ;
2010-12-20 16:03:14 +03:00
return - ENODEV ;
2010-11-09 02:42:39 +03:00
}
/* Only one ROP engine is presently supported. */
if ( unlikely ( regbase ) ) {
WARN_ON ( 1 ) ;
return - EBUSY ;
}
regbase = ioremap ( res - > start , resource_size ( res ) ) ;
if ( regbase = = NULL ) {
dev_err ( & pdev - > dev , " failed to map I/O memory \n " ) ;
2010-12-20 16:03:14 +03:00
return - EBUSY ;
2010-11-09 02:42:39 +03:00
}
writel ( 1 , regbase + GE_ENABLE_OFF ) ;
printk ( KERN_INFO " Enabled support for WMT GE raster acceleration \n " ) ;
return 0 ;
}
static int __devexit wmt_ge_rops_remove ( struct platform_device * pdev )
{
iounmap ( regbase ) ;
return 0 ;
}
2012-08-03 12:58:22 +04:00
static const struct of_device_id wmt_dt_ids [ ] = {
{ . compatible = " wm,prizm-ge-rops " , } ,
{ /* sentinel */ }
} ;
2010-11-09 02:42:39 +03:00
static struct platform_driver wmt_ge_rops_driver = {
. probe = wmt_ge_rops_probe ,
. remove = __devexit_p ( wmt_ge_rops_remove ) ,
. driver = {
. owner = THIS_MODULE ,
. name = " wmt_ge_rops " ,
2012-08-03 12:58:22 +04:00
. of_match_table = of_match_ptr ( wmt_dt_ids ) ,
2010-11-09 02:42:39 +03:00
} ,
} ;
2011-11-26 06:25:54 +04:00
module_platform_driver ( wmt_ge_rops_driver ) ;
2010-11-09 02:42:39 +03:00
MODULE_AUTHOR ( " Alexey Charkov <alchark@gmail.com " ) ;
MODULE_DESCRIPTION ( " Accelerators for raster operations using "
" WonderMedia Graphics Engine " ) ;
2012-08-03 12:58:22 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DEVICE_TABLE ( of , wmt_dt_ids ) ;