@ -491,6 +491,95 @@ static void image_copy_rect(struct tridentfb_par *par,
0x80000000 | 1 < < 22 | 1 < < 10 | 1 < < 7 | direction ) ;
}
/*
* TGUI 9440 / 96 XX acceleration
*/
static void tgui_init_accel ( struct tridentfb_par * par , int pitch , int bpp )
{
unsigned char x = 0 ;
/* disable clipping */
writemmr ( par , 0x2148 , 0 ) ;
writemmr ( par , 0x214C , point ( 4095 , 2047 ) ) ;
switch ( bpp ) {
case 8 :
x = 0 ;
break ;
case 16 :
x = 1 ;
break ;
case 24 :
x = 3 ;
break ;
case 32 :
x = 2 ;
break ;
}
switch ( ( pitch * bpp ) / 8 ) {
case 8192 :
case 512 :
x | = 0x00 ;
break ;
case 1024 :
x | = 0x04 ;
break ;
case 2048 :
x | = 0x08 ;
break ;
case 4096 :
x | = 0x0C ;
break ;
}
fb_writew ( x , par - > io_virt + 0x2122 ) ;
}
static void tgui_fill_rect ( struct tridentfb_par * par ,
u32 x , u32 y , u32 w , u32 h , u32 c , u32 rop )
{
t_outb ( par , ROP_P , 0x2127 ) ;
writemmr ( par , 0x212c , c ) ;
writemmr ( par , 0x2128 , 0x4020 ) ;
writemmr ( par , 0x2140 , point ( w - 1 , h - 1 ) ) ;
writemmr ( par , 0x2138 , point ( x , y ) ) ;
t_outb ( par , 1 , 0x2124 ) ;
}
static void tgui_copy_rect ( struct tridentfb_par * par ,
u32 x1 , u32 y1 , u32 x2 , u32 y2 , u32 w , u32 h )
{
int flags = 0 ;
u16 x1_tmp , x2_tmp , y1_tmp , y2_tmp ;
if ( ( x1 < x2 ) & & ( y1 = = y2 ) ) {
flags | = 0x0200 ;
x1_tmp = x1 + w - 1 ;
x2_tmp = x2 + w - 1 ;
} else {
x1_tmp = x1 ;
x2_tmp = x2 ;
}
if ( y1 < y2 ) {
flags | = 0x0100 ;
y1_tmp = y1 + h - 1 ;
y2_tmp = y2 + h - 1 ;
} else {
y1_tmp = y1 ;
y2_tmp = y2 ;
}
writemmr ( par , 0x2128 , 0x4 | flags ) ;
t_outb ( par , ROP_S , 0x2127 ) ;
writemmr ( par , 0x213C , point ( x1_tmp , y1_tmp ) ) ;
writemmr ( par , 0x2138 , point ( x2_tmp , y2_tmp ) ) ;
writemmr ( par , 0x2140 , point ( w - 1 , h - 1 ) ) ;
t_outb ( par , 1 , 0x2124 ) ;
}
/*
* Accel functions called by the upper layers
*/
@ -530,12 +619,8 @@ static void tridentfb_copyarea(struct fb_info *info,
ca - > width , ca - > height ) ;
par - > wait_engine ( par ) ;
}
# else /* !CONFIG_FB_TRIDENT_ACCEL */
# define tridentfb_fillrect cfb_fillrect
# define tridentfb_copyarea cfb_copyarea
# endif /* CONFIG_FB_TRIDENT_ACCEL */
/*
* Hardware access functions
*/
@ -829,6 +914,7 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var,
{
struct tridentfb_par * par = info - > par ;
int bpp = var - > bits_per_pixel ;
int line_length ;
int ramdac = 230000 ; /* 230MHz for most 3D chips */
debug ( " enter \n " ) ;
@ -844,9 +930,27 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var,
var - > xres = ( var - > xres + 7 ) & ~ 0x7 ;
if ( var - > xres ! = var - > xres_virtual )
var - > xres_virtual = var - > xres ;
line_length = var - > xres_virtual * bpp / 8 ;
# ifdef CONFIG_FB_TRIDENT_ACCEL
if ( ! is3Dchip ( par - > chip_id ) ) {
/* acceleration requires line length to be power of 2 */
if ( line_length < = 512 )
var - > xres_virtual = 512 * 8 / bpp ;
else if ( line_length < = 1024 )
var - > xres_virtual = 1024 * 8 / bpp ;
else if ( line_length < = 2048 )
var - > xres_virtual = 2048 * 8 / bpp ;
else if ( line_length < = 4096 )
var - > xres_virtual = 4096 * 8 / bpp ;
else if ( line_length < = 8192 )
var - > xres_virtual = 8192 * 8 / bpp ;
line_length = var - > xres_virtual * bpp / 8 ;
}
# endif
if ( var - > yres > var - > yres_virtual )
var - > yres_virtual = var - > yres ;
if ( var - > xres * var - > yres_virtual * bpp / 8 > info - > fix . smem_len )
if ( line_length * var - > yres_virtual > info - > fix . smem_len )
return - EINVAL ;
switch ( bpp ) {
@ -918,7 +1022,7 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
unsigned int offset ;
debug ( " enter \n " ) ;
offset = ( var - > xoffset + ( var - > yoffset * var - > xres ) )
offset = ( var - > xoffset + ( var - > yoffset * var - > xres_virtual ) )
* var - > bits_per_pixel / 32 ;
info - > var . xoffset = var - > xoffset ;
info - > var . yoffset = var - > yoffset ;
@ -1049,7 +1153,7 @@ static int tridentfb_set_par(struct fb_info *info)
write3X4 ( par , GraphEngReg , 0x80 ) ;
# ifdef CONFIG_FB_TRIDENT_ACCEL
par - > init_accel ( par , info - > var . xres , bpp ) ;
par - > init_accel ( par , info - > var . xres_virtual , bpp ) ;
# endif
switch ( bpp ) {
@ -1147,9 +1251,9 @@ static int tridentfb_set_par(struct fb_info *info)
if ( par - > flatpanel )
set_number_of_lines ( par , info - > var . yres ) ;
set_lwidth ( par , info - > var . xres * bpp / ( 4 * 16 ) ) ;
info - > fix . line_length = info - > var . xres_virtual * bpp / 8 ;
set_lwidth ( par , info - > fix . line_length / 8 ) ;
info - > fix . visual = ( bpp = = 8 ) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR ;
info - > fix . line_length = info - > var . xres * ( bpp > > 3 ) ;
info - > cmap . len = ( bpp = = 8 ) ? 256 : 16 ;
debug ( " exit \n " ) ;
return 0 ;
@ -1248,9 +1352,11 @@ static struct fb_ops tridentfb_ops = {
. fb_blank = tridentfb_blank ,
. fb_check_var = tridentfb_check_var ,
. fb_set_par = tridentfb_set_par ,
# ifdef CONFIG_FB_TRIDENT_ACCEL
. fb_fillrect = tridentfb_fillrect ,
. fb_copyarea = tridentfb_copyarea ,
. fb_imageblit = cfb_imageblit ,
# endif
} ;
static int __devinit trident_pci_probe ( struct pci_dev * dev ,
@ -1328,11 +1434,16 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
default_par - > wait_engine = blade_wait_engine ;
default_par - > fill_rect = blade_fill_rect ;
default_par - > copy_rect = blade_copy_rect ;
} else {
} else if ( chip3D ) { /* 3DImage family left */
default_par - > init_accel = image_init_accel ;
default_par - > wait_engine = image_wait_engine ;
default_par - > fill_rect = image_fill_rect ;
default_par - > copy_rect = image_copy_rect ;
} else { /* TGUI 9440/96XX family */
default_par - > init_accel = tgui_init_accel ;
default_par - > wait_engine = xp_wait_engine ;
default_par - > fill_rect = tgui_fill_rect ;
default_par - > copy_rect = tgui_copy_rect ;
}
default_par - > chip_id = chip_id ;
@ -1359,12 +1470,12 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
goto out_unmap1 ;
}
enable_mmio ( ) ;
/* setup framebuffer memory */
tridentfb_fix . smem_start = pci_resource_start ( dev , 0 ) ;
tridentfb_fix . smem_len = get_memsize ( default_par ) ;
enable_mmio ( ) ;
if ( ! request_mem_region ( tridentfb_fix . smem_start , tridentfb_fix . smem_len , " tridentfb " ) ) {
debug ( " request_mem_region failed! \n " ) ;
disable_mmio ( info - > par ) ;