2005-04-17 02:20:36 +04:00
/*
* linux / drivers / video / maxinefb . c
*
* DECstation 5000 / xx onboard framebuffer support . . . derived from :
* " HP300 Topcat framebuffer support (derived from macfb of all things)
* Phil Blundell < philb @ gnu . org > 1998 " , the original code can be
* found in the file hpfb . c in the same directory .
*
* DECstation related code Copyright ( C ) 1999 , 2000 , 2001 by
* Michael Engel < engel @ unix - ag . org > and
* Karsten Merker < merker @ linuxtag . org > .
* This file is subject to the terms and conditions of the GNU General
* Public License . See the file COPYING in the main directory of this
* archive for more details .
*
*/
/*
* Changes :
* 2001 / 01 / 27 removed debugging and testing code , fixed fb_ops
* initialization which had caused a crash before ,
* general cleanup , first official release ( KM )
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/mm.h>
# include <linux/slab.h>
# include <linux/delay.h>
# include <linux/init.h>
# include <linux/fb.h>
# include <video/maxinefb.h>
/* bootinfo.h defines the machine type values, needed when checking */
/* whether are really running on a maxine, KM */
# include <asm/bootinfo.h>
static struct fb_info fb_info ;
static struct fb_var_screeninfo maxinefb_defined = {
. xres = 1024 ,
. yres = 768 ,
. xres_virtual = 1024 ,
. yres_virtual = 768 ,
. bits_per_pixel = 8 ,
. activate = FB_ACTIVATE_NOW ,
. height = - 1 ,
. width = - 1 ,
. vmode = FB_VMODE_NONINTERLACED ,
} ;
static struct fb_fix_screeninfo maxinefb_fix = {
2006-05-31 08:27:02 +04:00
. id = " Maxine " ,
2005-04-17 02:20:36 +04:00
. smem_len = ( 1024 * 768 ) ,
. type = FB_TYPE_PACKED_PIXELS ,
. visual = FB_VISUAL_PSEUDOCOLOR ,
. line_length = 1024 ,
} ;
/* Handle the funny Inmos RamDAC/video controller ... */
void maxinefb_ims332_write_register ( int regno , register unsigned int val )
{
register unsigned char * regs = ( char * ) MAXINEFB_IMS332_ADDRESS ;
unsigned char * wptr ;
wptr = regs + 0xa0000 + ( regno < < 4 ) ;
* ( ( volatile unsigned int * ) ( regs ) ) = ( val > > 8 ) & 0xff00 ;
* ( ( volatile unsigned short * ) ( wptr ) ) = val ;
}
unsigned int maxinefb_ims332_read_register ( int regno )
{
register unsigned char * regs = ( char * ) MAXINEFB_IMS332_ADDRESS ;
unsigned char * rptr ;
register unsigned int j , k ;
rptr = regs + 0x80000 + ( regno < < 4 ) ;
j = * ( ( volatile unsigned short * ) rptr ) ;
k = * ( ( volatile unsigned short * ) regs ) ;
return ( j & 0xffff ) | ( ( k & 0xff00 ) < < 8 ) ;
}
/* Set the palette */
static int maxinefb_setcolreg ( unsigned regno , unsigned red , unsigned green ,
unsigned blue , unsigned transp , struct fb_info * info )
{
/* value to be written into the palette reg. */
unsigned long hw_colorvalue = 0 ;
red > > = 8 ; /* The cmap fields are 16 bits */
green > > = 8 ; /* wide, but the harware colormap */
blue > > = 8 ; /* registers are only 8 bits wide */
hw_colorvalue = ( blue < < 16 ) + ( green < < 8 ) + ( red ) ;
maxinefb_ims332_write_register ( IMS332_REG_COLOR_PALETTE + regno ,
hw_colorvalue ) ;
return 0 ;
}
static struct fb_ops maxinefb_ops = {
. owner = THIS_MODULE ,
. fb_setcolreg = maxinefb_setcolreg ,
. fb_fillrect = cfb_fillrect ,
. fb_copyarea = cfb_copyarea ,
. fb_imageblit = cfb_imageblit ,
} ;
int __init maxinefb_init ( void )
{
unsigned long fboff ;
unsigned long fb_start ;
int i ;
if ( fb_get_options ( " maxinefb " , NULL ) )
return - ENODEV ;
/* Validate we're on the proper machine type */
if ( mips_machtype ! = MACH_DS5000_XX ) {
return - EINVAL ;
}
printk ( KERN_INFO " Maxinefb: Personal DECstation detected \n " ) ;
printk ( KERN_INFO " Maxinefb: initializing onboard framebuffer \n " ) ;
/* Framebuffer display memory base address */
fb_start = DS5000_xx_ONBOARD_FBMEM_START ;
/* Clear screen */
for ( fboff = fb_start ; fboff < fb_start + 0x1ffff ; fboff + + )
* ( volatile unsigned char * ) fboff = 0x0 ;
maxinefb_fix . smem_start = fb_start ;
/* erase hardware cursor */
for ( i = 0 ; i < 512 ; i + + ) {
maxinefb_ims332_write_register ( IMS332_REG_CURSOR_RAM + i ,
0 ) ;
/*
if ( i & 0x8 = = 0 )
maxinefb_ims332_write_register ( IMS332_REG_CURSOR_RAM + i , 0x0f ) ;
else
maxinefb_ims332_write_register ( IMS332_REG_CURSOR_RAM + i , 0xf0 ) ;
*/
}
fb_info . fbops = & maxinefb_ops ;
fb_info . screen_base = ( char * ) maxinefb_fix . smem_start ;
fb_info . var = maxinefb_defined ;
fb_info . fix = maxinefb_fix ;
fb_info . flags = FBINFO_DEFAULT ;
fb_alloc_cmap ( & fb_info . cmap , 256 , 0 ) ;
if ( register_framebuffer ( & fb_info ) < 0 )
return 1 ;
return 0 ;
}
static void __exit maxinefb_exit ( void )
{
unregister_framebuffer ( & fb_info ) ;
}
# ifdef MODULE
MODULE_LICENSE ( " GPL " ) ;
# endif
module_init ( maxinefb_init ) ;
module_exit ( maxinefb_exit ) ;