* TGUI acceleration
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/init.h>
struct tridentfb_par {
int vclk; //in MHz
- unsigned long io_virt; //iospace virtual memory address
+ void __iomem * io_virt; //iospace virtual memory address
};
-unsigned char eng_oper; //engine operation...
+static unsigned char eng_oper; //engine operation...
static struct fb_ops tridentfb_ops;
static struct tridentfb_par default_par;
/* FIXME:kmalloc these 3 instead */
static struct fb_info fb_info;
-static int pseudo_pal[16];
+static u32 pseudo_pal[16];
static struct fb_var_screeninfo default_var;
static int nativex;
-MODULE_PARM(mode,"s");
-MODULE_PARM(bpp,"i");
-MODULE_PARM(center,"i");
-MODULE_PARM(stretch,"i");
-MODULE_PARM(noaccel,"i");
-MODULE_PARM(memsize,"i");
-MODULE_PARM(memdiff,"i");
-MODULE_PARM(nativex,"i");
-MODULE_PARM(fp,"i");
-MODULE_PARM(crt,"i");
+module_param(mode, charp, 0);
+module_param(bpp, int, 0);
+module_param(center, int, 0);
+module_param(stretch, int, 0);
+module_param(noaccel, int, 0);
+module_param(memsize, int, 0);
+module_param(memdiff, int, 0);
+module_param(nativex, int, 0);
+module_param(fp, int, 0);
+module_param(crt, int, 0);
static int chip3D;
static int chipcyber;
-int is3Dchip(int id)
+static int is3Dchip(int id)
{
return ((id == BLADE3D) || (id == CYBERBLADEE4) ||
(id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
(id == CYBERBLADEXPAi1));
}
-int iscyber(int id)
+static int iscyber(int id)
{
switch (id) {
case CYBER9388:
static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
{
int bpp = info->var.bits_per_pixel;
- int col;
+ int col = 0;
switch (bpp) {
default:
- case 8: col = fr->color;
+ case 8: col |= fr->color;
+ col |= col << 8;
+ col |= col << 16;
break;
- case 16: col = ((u16 *)(info->pseudo_palette))[fr->color];
+ case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
+
break;
case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
break;
t_outb(val, 0x3C0);
}
-static inline unsigned char readAttr(int reg)
-{
- readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); //flip-flop to index
- t_outb(reg, 0x3C0);
- return t_inb(0x3C1);
-}
-
static inline void write3CE(int reg, unsigned char val)
{
t_outb(reg, 0x3CE);
#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
/* Return flat panel's maximum x resolution */
-static int __init get_nativex(void)
+static int __devinit get_nativex(void)
{
int x,y,tmp;
* If we see that FP is active we assume we have one.
* Otherwise we have a CRT display.User can override.
*/
-static unsigned int __init get_displaytype(void)
+static unsigned int __devinit get_displaytype(void)
{
if (fp)
return DISPLAY_FP;
}
/* Try detecting the video memory size */
-static unsigned int __init get_memsize(void)
+static unsigned int __devinit get_memsize(void)
{
unsigned char tmp, tmp2;
unsigned int k;
write3X4(GraphEngReg, 0x80); //enable GE for text acceleration
-// if (info->var.accel_flags & FB_ACCELF_TEXT)
-//FIXME acc->init_accel(info->var.xres,bpp);
+#ifdef CONFIG_FB_TRIDENT_ACCEL
+ acc->init_accel(info->var.xres,bpp);
+#endif
switch (bpp) {
case 8: tmp = 0x00; break;
write3X4(DRAMControl, tmp); //both IO,linear enable
write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
- write3X4(Performance,0x20);
+ write3X4(Performance,0x92);
write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable
/* convert from picoseconds to MHz */
t_outb(green>>10,0x3C9);
t_outb(blue>>10,0x3C9);
- } else
- if (bpp == 16) /* RGB 565 */
- ((u16*)info->pseudo_palette)[regno] = (red & 0xF800) |
- ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
- else
- if (bpp == 32) /* ARGB 8888 */
+ } else if (bpp == 16) { /* RGB 565 */
+ u32 col;
+
+ col = (red & 0xF800) | ((green & 0xFC00) >> 5) |
+ ((blue & 0xF800) >> 11);
+ col |= col << 16;
+ ((u32 *)(info->pseudo_palette))[regno] = col;
+ } else if (bpp == 32) /* ARGB 8888 */
((u32*)info->pseudo_palette)[regno] =
((transp & 0xFF00) <<16) |
((red & 0xFF00) << 8) |
DPMSCont = read3CE(PowerStatus) & 0xFC;
switch (blank_mode)
{
- case VESA_NO_BLANKING:
+ case FB_BLANK_UNBLANK:
/* Screen: On, HSync: On, VSync: On */
+ case FB_BLANK_NORMAL:
+ /* Screen: Off, HSync: On, VSync: On */
PMCont |= 0x03;
DPMSCont |= 0x00;
break;
- case VESA_HSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
/* Screen: Off, HSync: Off, VSync: On */
PMCont |= 0x02;
DPMSCont |= 0x01;
break;
- case VESA_VSYNC_SUSPEND:
+ case FB_BLANK_VSYNC_SUSPEND:
/* Screen: Off, HSync: On, VSync: Off */
PMCont |= 0x02;
DPMSCont |= 0x02;
break;
- case VESA_POWERDOWN:
+ case FB_BLANK_POWERDOWN:
/* Screen: Off, HSync: Off, VSync: Off */
PMCont |= 0x00;
DPMSCont |= 0x03;
t_outb(PMCont,0x83C6);
debug("exit\n");
- return 0;
+
+ /* let fbcon do a softblank for us */
+ return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
}
static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id)
chip_id = id->device;
+ if(chip_id == CYBERBLADEi1)
+ output("*** Please do use cyblafb, Cyberblade/i1 support "
+ "will soon be removed from tridentfb!\n");
+
+
/* If PCI id is 0x9660 then further detect chip type */
if (chip_id == TGUI9660) {
return -1;
}
- default_par.io_virt = (unsigned long)ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
+ default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
if (!default_par.io_virt) {
release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
debug("request_mem_region failed!\n");
- return -1;
+ err = -1;
+ goto out_unmap;
}
fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
if (!fb_info.screen_base) {
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
debug("ioremap failed\n");
- return -1;
+ err = -1;
+ goto out_unmap;
}
output("%s board found\n", pci_name(dev));
fb_info.fbops = &tridentfb_ops;
- fb_info.flags = FBINFO_FLAG_DEFAULT;
+ fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+#ifdef CONFIG_FB_TRIDENT_ACCEL
+ fb_info.flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
+#endif
fb_info.pseudo_palette = pseudo_pal;
- if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp))
- return -EINVAL;
+ if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) {
+ err = -EINVAL;
+ goto out_unmap;
+ }
fb_alloc_cmap(&fb_info.cmap,256,0);
if (defaultaccel && acc)
default_var.accel_flags |= FB_ACCELF_TEXT;
default_var.accel_flags &= ~FB_ACCELF_TEXT;
default_var.activate |= FB_ACTIVATE_NOW;
fb_info.var = default_var;
+ fb_info.device = &dev->dev;
if (register_framebuffer(&fb_info) < 0) {
- output("Could not register Trident framebuffer\n");
- return -EINVAL;
+ printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
+ err = -EINVAL;
+ goto out_unmap;
}
output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
fb_info.node, fb_info.fix.id,default_var.xres,
default_var.yres,default_var.bits_per_pixel);
return 0;
+
+out_unmap:
+ if (default_par.io_virt)
+ iounmap(default_par.io_virt);
+ if (fb_info.screen_base)
+ iounmap(fb_info.screen_base);
+ return err;
}
static void __devexit trident_pci_remove(struct pci_dev * dev)
{
struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;
unregister_framebuffer(&fb_info);
- iounmap((void *)par->io_virt);
- iounmap((void*)fb_info.screen_base);
+ iounmap(par->io_virt);
+ iounmap(fb_info.screen_base);
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
}
.remove = __devexit_p(trident_pci_remove)
};
-int __init tridentfb_init(void)
-{
- output("Trident framebuffer %s initializing\n", VERSION);
- return pci_module_init(&tridentfb_pci_driver);
-}
-
-void __exit tridentfb_exit(void)
-{
- pci_unregister_driver(&tridentfb_pci_driver);
-}
-
-
/*
* Parse user specified options (`video=trident:')
* example:
* video=trident:800x600,bpp=16,noaccel
*/
-int tridentfb_setup(char *options)
+#ifndef MODULE
+static int tridentfb_setup(char *options)
{
char * opt;
if (!options || !*options)
}
return 0;
}
+#endif
+
+static int __init tridentfb_init(void)
+{
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("tridentfb", &option))
+ return -ENODEV;
+ tridentfb_setup(option);
+#endif
+ output("Trident framebuffer %s initializing\n", VERSION);
+ return pci_register_driver(&tridentfb_pci_driver);
+}
+
+static void __exit tridentfb_exit(void)
+{
+ pci_unregister_driver(&tridentfb_pci_driver);
+}
static struct fb_ops tridentfb_ops = {
.owner = THIS_MODULE,
.fb_fillrect = tridentfb_fillrect,
.fb_copyarea= tridentfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
-#ifdef MODULE
module_init(tridentfb_init);
-#endif
module_exit(tridentfb_exit);
MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");