patch-2.4.21 linux-2.4.21/drivers/video/S3triofb.c
Next file: linux-2.4.21/drivers/video/amifb.c
Previous file: linux-2.4.21/drivers/video/Makefile
Back to the patch index
Back to the overall index
- Lines: 285
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/drivers/video/S3triofb.c
- Orig date:
2001-09-13 16:04:43.000000000 -0700
diff -urN linux-2.4.20/drivers/video/S3triofb.c linux-2.4.21/drivers/video/S3triofb.c
@@ -17,8 +17,7 @@
*/
/*
- Bugs : + OF dependencies should be removed.
- + This driver should be merged with the CyberVision driver. The
+ Bugs : + This driver should be merged with the CyberVision driver. The
CyberVision is a Zorro III implementation of the S3Trio64 chip.
*/
@@ -37,9 +36,6 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
#include <linux/pci.h>
#ifdef CONFIG_FB_COMPAT_XPMAC
#include <asm/vc_ioctl.h>
@@ -60,7 +56,9 @@
#define IO_OUT16VAL(v, r) (((v) << 8) | (r))
+
static int currcon = 0;
+static int disabled;
static struct display disp;
static struct fb_info fb_info;
static struct { u_char red, green, blue, pad; } palette[256];
@@ -68,14 +66,20 @@
static char *s3trio_base;
static struct fb_fix_screeninfo fb_fix;
-static struct fb_var_screeninfo fb_var = { 0, };
-
+static struct fb_var_screeninfo S3triofb_default_var = {
+ 640, 480, 640, 480, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
+ FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED
+};
+static struct fb_var_screeninfo fb_var = { 0,};
/*
* Interface used by the world
*/
-static void __init s3triofb_of_init(struct device_node *dp);
+static void __init s3triofb_pci_init(struct pci_dev *dp);
static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
@@ -259,15 +263,42 @@
return 0;
}
+int __init s3triofb_setup(char *options) {
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+
+ if (!strcmp(this_opt, "disabled"))
+ disabled = 1;
+ }
+ return 0;
+}
int __init s3triofb_init(void)
{
- struct device_node *dp;
+ struct pci_dev *dp = NULL;
- dp = find_devices("S3Trio");
- if (dp != 0)
- s3triofb_of_init(dp);
- return 0;
+ if (disabled)
+ return -ENXIO;
+
+ dp = pci_find_device(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_TRIO, dp);
+ if ((dp != 0) && ((dp->class >> 16) == PCI_BASE_CLASS_DISPLAY)) {
+ s3triofb_pci_init(dp);
+ return 0;
+ } else
+ return -ENODEV;
+}
+
+static void __exit s3triofb_exit(void)
+{
+ unregister_framebuffer(&fb_info);
+ iounmap(s3trio_base);
+ /* XXX unshare VGA regions */
}
void __init s3trio_resetaccel(void){
@@ -313,111 +344,69 @@
outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX, 0xbee8);
}
-int __init s3trio_init(struct device_node *dp){
-
- u_char bus, dev;
- unsigned int t32;
- unsigned short cmd;
-
- pci_device_loc(dp,&bus,&dev);
- pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
- if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_1, &t32);
- pcibios_read_config_word(bus, dev, PCI_COMMAND,&cmd);
-
- pcibios_write_config_word(bus, dev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-
- pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,0xffffffff);
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
-
-/* This is a gross hack as OF only maps enough memory for the framebuffer and
- we want to use MMIO too. We should find out which chunk of address space
- we can use here */
- pcibios_write_config_dword(bus,dev,PCI_BASE_ADDRESS_0,0xc6000000);
-
- /* unlock s3 */
-
- outb(0x01, 0x3C3);
-
- outb(inb(0x03CC) | 1, 0x3c2);
-
- outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
- outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
- outb(0x33,0x3d4);
- outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 | 0x40)) |
- 0x20, 0x33), 0x3d4);
-
- outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
-
- /* switch to MMIO only mode */
-
- outb(0x58, 0x3d4);
- outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
- outw(IO_OUT16VAL(8, 0x53), 0x3d4);
-
- /* switch off I/O accesses */
-
-#if 0
- pcibios_write_config_word(bus, dev, PCI_COMMAND,
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-#endif
- return 1;
- }
+int __init s3trio_init(struct pci_dev *dp)
+{
+ /* unlock s3 */
+ outb(0x01, 0x3C3);
+ outb(inb(0x03CC) | 1, 0x3c2);
+ outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
+ outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
+ outb(0x33,0x3d4);
+ outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 | 0x40)) |
+ 0x20, 0x33), 0x3d4);
+
+ outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
+ printk("S3trio: unlocked s3\n");
+
+ /* switch to MMIO only mode */
+ outb(0x58, 0x3d4);
+ outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
+ outw(IO_OUT16VAL(8, 0x53), 0x3d4);
+ printk("S3trio: switched to mmio only mode\n");
- return 0;
+ return 1;
}
/*
* Initialisation
- * We heavily rely on OF for the moment. This needs fixing.
*/
-static void __init s3triofb_of_init(struct device_node *dp)
+static void __init s3triofb_pci_init(struct pci_dev *dp)
{
- int i, *pp, len;
+ int i;
unsigned long address, size;
u_long *CursorBase;
+ u16 cmd;
- strncat(s3trio_name, dp->name, sizeof(s3trio_name));
- s3trio_name[sizeof(s3trio_name)-1] = '\0';
strcpy(fb_fix.id, s3trio_name);
- if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL
- && *pp!=PCI_VENDOR_ID_S3) {
- printk("%s: can't find S3 Trio board\n", dp->full_name);
- return;
- }
+ fb_var = S3triofb_default_var;
+ fb_fix.line_length = fb_var.xres_virtual;
+ fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
- if((pp = (int *)get_property(dp, "device-id", &len)) != NULL
- && *pp!=PCI_DEVICE_ID_S3_TRIO) {
- printk("%s: can't find S3 Trio board\n", dp->full_name);
- return;
+ /* This driver cannot cope if the firmware has not initialised the
+ * device. So, if the device isn't enabled we simply return
+ */
+ pci_read_config_word(dp, PCI_COMMAND, &cmd);
+ if (!(cmd & PCI_COMMAND_MEMORY)) {
+ printk(KERN_NOTICE "S3trio: card was not initialised by firmware\n");
+ return;
}
- if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
- && len == sizeof(int) && *pp != 8) {
- printk("%s: can't use depth = %d\n", dp->full_name, *pp);
- return;
+ /* Enable it anyway */
+ if (pci_enable_device(dp)) {
+ printk(KERN_ERR "S3trio: failed to enable PCI device\n");
+ return;
}
- if ((pp = (int *)get_property(dp, "width", &len)) != NULL
- && len == sizeof(int))
- fb_var.xres = fb_var.xres_virtual = *pp;
- if ((pp = (int *)get_property(dp, "height", &len)) != NULL
- && len == sizeof(int))
- fb_var.yres = fb_var.yres_virtual = *pp;
- if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
- && len == sizeof(int))
- fb_fix.line_length = *pp;
- else
- fb_fix.line_length = fb_var.xres_virtual;
- fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
- address = 0xc6000000;
- size = 64*1024*1024;
- if (!request_mem_region(address, size, "S3triofb"))
+ /* There is only one memory region and it covers the mmio and fb areas */
+ address = pci_resource_start(dp, 0);
+ size = pci_resource_len(dp, 0); /* size = 64*1024*1024; */
+ if (!request_mem_region(address, size, "S3triofb")) {
+ printk("S3trio: failed to allocate memory region\n");
return;
+ }
s3trio_init(dp);
s3trio_base = ioremap(address, size);
@@ -552,8 +541,7 @@
#endif
disp.scrollmode = fb_var.accel_flags & FB_ACCELF_TEXT ? 0 : SCROLL_YREDRAW;
- strcpy(fb_info.modename, "Trio64 ");
- strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
+ strcpy(fb_info.modename, "Trio64");
fb_info.node = -1;
fb_info.fbops = &s3trio_ops;
#if 0
@@ -591,7 +579,7 @@
return;
printk("fb%d: S3 Trio frame buffer device on %s\n",
- GET_FB_IDX(fb_info.node), dp->full_name);
+ GET_FB_IDX(fb_info.node), dp->name);
}
@@ -859,4 +847,8 @@
};
#endif
+#ifdef MODULE
+module_init(s3triofb_init);
MODULE_LICENSE("GPL");
+#endif
+module_exit(s3triofb_exit);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)