*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
/*
* Driver data
*/
-static char *mode __initdata = NULL;
+static char *mode __devinitdata = NULL;
/*
* The XFree GLINT driver will (I think to implement hardware cursor
* these flags allow the user to specify that requests for +ve sync
* should be silently turned in -ve sync.
*/
-static int lowhsync __initdata = 0;
-static int lowvsync __initdata = 0;
+static int lowhsync;
+static int lowvsync;
/*
* The hardware state of the graphics card that isn't part of the
u32 mem_config; /* MemConfig reg at probe */
u32 mem_control; /* MemControl reg at probe */
u32 boot_address; /* BootAddress reg at probe */
+ u32 palette[16];
};
/*
* Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
* if we don't use modedb.
*/
-static struct fb_fix_screeninfo pm2fb_fix __initdata = {
+static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
.id = "",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
/*
* Default video mode. In case the modedb doesn't work.
*/
-static struct fb_var_screeninfo pm2fb_var __initdata = {
+static struct fb_var_screeninfo pm2fb_var __devinitdata = {
/* "640x480, 8 bpp @ 60 Hz */
.xres = 640,
.yres = 480,
* Utility functions
*/
-inline static u32 RD32(unsigned char __iomem *base, s32 off)
+static inline u32 RD32(unsigned char __iomem *base, s32 off)
{
return fb_readl(base + off);
}
-inline static void WR32(unsigned char __iomem *base, s32 off, u32 v)
+static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
{
fb_writel(v, base + off);
}
-inline static u32 pm2_RD(struct pm2fb_par* p, s32 off)
+static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
{
return RD32(p->v_regs, off);
}
-inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
+static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
{
WR32(p->v_regs, off, v);
}
-inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
+static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
{
int index = PM2R_RD_INDEXED_DATA;
switch (p->type) {
return pm2_RD(p, index);
}
-inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
int index = PM2R_RD_INDEXED_DATA;
switch (p->type) {
pm2_WR(p, index, v);
}
-inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
mb();
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
#define WAIT_FIFO(p,a)
#else
-inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a)
+static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
{
while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
mb();
*/
static int pm2fb_set_par(struct fb_info *info)
{
- struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+ struct pm2fb_par *par = info->par;
u32 pixclock;
u32 width, height, depth;
u32 hsstart, hsend, hbend, htotal;
}
if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
video |= PM2F_LINE_DOUBLE;
- if (info->var.activate==FB_ACTIVATE_NOW)
+ if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW)
video |= PM2F_VIDEO_ENABLE;
par->video = video;
unsigned blue, unsigned transp,
struct fb_info *info)
{
- struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+ struct pm2fb_par *par = info->par;
if (regno >= info->cmap.len) /* no. of hw registers */
return 1;
case 16:
case 24:
case 32:
- ((u32*)(info->pseudo_palette))[regno] = v;
+ par->palette[regno] = v;
break;
}
return 0;
static int pm2fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- struct pm2fb_par *p = (struct pm2fb_par *) info->par;
+ struct pm2fb_par *p = info->par;
u32 base;
u32 depth;
u32 xres;
*/
static int pm2fb_blank(int blank_mode, struct fb_info *info)
{
- struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+ struct pm2fb_par *par = info->par;
u32 video = par->video;
DPRINTK("blank_mode %d\n", blank_mode);
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
{
struct pm2fb_par *default_par;
struct fb_info *info;
- int size, err;
- int err_retval = -ENXIO;
+ int err, err_retval = -ENXIO;
err = pci_enable_device(pdev);
if ( err ) {
return err;
}
- size = sizeof(struct pm2fb_par) + 256 * sizeof(u32);
- info = framebuffer_alloc(size, &pdev->dev);
+ info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
if ( !info )
return -ENOMEM;
- default_par = (struct pm2fb_par *) info->par;
+ default_par = info->par;
switch (pdev->device) {
case PCI_DEVICE_ID_TI_TVP4020:
default_par->mem_control, default_par->boot_address,
default_par->mem_config);
+ if(default_par->mem_control == 0 &&
+ default_par->boot_address == 0x31 &&
+ default_par->mem_config == 0x259fffff &&
+ pdev->subsystem_vendor == 0x1048 &&
+ pdev->subsystem_device == 0x0a31) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an Elsa Winner 2000 Office\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->mem_control=0;
+ default_par->boot_address=0x20;
+ default_par->mem_config=0xe6002021;
+ default_par->memclock=100000;
+ }
+
/* Now work out how big lfb is going to be. */
switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
case PM2F_MEM_BANKS_1:
info->fbops = &pm2fb_ops;
info->fix = pm2fb_fix;
- info->pseudo_palette = (void *)(default_par + 1);
+ info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_YPAN;
MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
-/*
- * Initialization
- */
-
-int __init pm2fb_setup(char *options);
-
-int __init pm2fb_init(void)
-{
-#ifndef MODULE
- char *option = NULL;
-
- if (fb_get_options("pm2fb", &option))
- return -ENODEV;
- pm2fb_setup(option);
-#endif
-
- return pci_module_init(&pm2fb_driver);
-}
-
-#ifdef MODULE
-/*
- * Cleanup
- */
-
-static void __exit pm2fb_exit(void)
-{
- pci_unregister_driver(&pm2fb_driver);
-}
-#endif
-
-/*
- * Setup
- */
-
#ifndef MODULE
/**
* Parse user speficied options.
*
* This is, comma-separated options following `video=pm2fb:'.
*/
-int __init pm2fb_setup(char *options)
+static int __init pm2fb_setup(char *options)
{
char* this_opt;
#endif
-/* ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
+static int __init pm2fb_init(void)
+{
+#ifndef MODULE
+ char *option = NULL;
+ if (fb_get_options("pm2fb", &option))
+ return -ENODEV;
+ pm2fb_setup(option);
+#endif
+ return pci_register_driver(&pm2fb_driver);
+}
module_init(pm2fb_init);
+#ifdef MODULE
+/*
+ * Cleanup
+ */
+
+static void __exit pm2fb_exit(void)
+{
+ pci_unregister_driver(&pm2fb_driver);
+}
+#endif
+
#ifdef MODULE
module_exit(pm2fb_exit);