#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#if defined(CONFIG_PPC_PMAC)
#include <linux/nvram.h>
#include "macmodes.h"
#endif
#ifndef __powerpc__
#define eieio() …
#endif
enum { … };
enum { … };
enum { … };
enum { … };
enum { … };
struct initvalues { … };
static struct initvalues ibm_initregs[] = …;
static struct initvalues tvp_initregs[] = …;
struct imstt_regvals { … };
struct imstt_par { … };
enum { … };
#define INIT_BPP …
#define INIT_XRES …
#define INIT_YRES …
static int inverse = …;
static char fontname[40] __initdata = …;
#if defined(CONFIG_PPC_PMAC)
static signed char init_vmode = -1, init_cmode = -1;
#endif
static struct imstt_regvals tvp_reg_init_2 = …;
static struct imstt_regvals tvp_reg_init_6 = …;
static struct imstt_regvals tvp_reg_init_12 = …;
static struct imstt_regvals tvp_reg_init_13 = …;
static struct imstt_regvals tvp_reg_init_17 = …;
static struct imstt_regvals tvp_reg_init_18 = …;
static struct imstt_regvals tvp_reg_init_19 = …;
static struct imstt_regvals tvp_reg_init_20 = …;
static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void imsttfb_remove(struct pci_dev *pdev);
static inline u32 read_reg_le32(volatile u32 __iomem *base, int regindex)
{ … }
static inline void write_reg_le32(volatile u32 __iomem *base, int regindex, u32 val)
{ … }
static __u32
getclkMHz(struct imstt_par *par)
{ … }
static void
setclkMHz(struct imstt_par *par, __u32 MHz)
{ … }
static struct imstt_regvals *
compute_imstt_regvals_ibm(struct imstt_par *par, int xres, int yres)
{ … }
static struct imstt_regvals *
compute_imstt_regvals_tvp(struct imstt_par *par, int xres, int yres)
{ … }
static struct imstt_regvals *
compute_imstt_regvals (struct imstt_par *par, u_int xres, u_int yres)
{ … }
static void
set_imstt_regvals_ibm (struct imstt_par *par, u_int bpp)
{ … }
static void
set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp)
{ … }
static void
set_imstt_regvals (struct fb_info *info, u_int bpp)
{ … }
static inline void
set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
{ … }
static inline void
set_555 (struct imstt_par *par)
{ … }
static inline void
set_565 (struct imstt_par *par)
{ … }
static int
imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{ … }
static int
imsttfb_set_par(struct fb_info *info)
{ … }
static int
imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{ … }
static int
imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{ … }
static int
imsttfb_blank(int blank, struct fb_info *info)
{ … }
static void
imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{ … }
static void
imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{ … }
#if 0
static int
imsttfb_load_cursor_image(struct imstt_par *par, int width, int height, __u8 fgc)
{
u_int x, y;
if (width > 32 || height > 32)
return -EINVAL;
if (par->ramdac == IBM) {
par->cmap_regs[PIDXHI] = 1; eieio();
for (x = 0; x < 0x100; x++) {
par->cmap_regs[PIDXLO] = x; eieio();
par->cmap_regs[PIDXDATA] = 0x00; eieio();
}
par->cmap_regs[PIDXHI] = 1; eieio();
for (y = 0; y < height; y++)
for (x = 0; x < width >> 2; x++) {
par->cmap_regs[PIDXLO] = x + y * 8; eieio();
par->cmap_regs[PIDXDATA] = 0xff; eieio();
}
par->cmap_regs[PIDXHI] = 0; eieio();
par->cmap_regs[PIDXLO] = CURS1R; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS1G; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS1B; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS2R; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS2G; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS2B; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS3R; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS3G; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
par->cmap_regs[PIDXLO] = CURS3B; eieio();
par->cmap_regs[PIDXDATA] = fgc; eieio();
} else {
par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
par->cmap_regs[TVPIDATA] &= 0x03; eieio();
par->cmap_regs[TVPADDRW] = 0; eieio();
for (x = 0; x < 0x200; x++) {
par->cmap_regs[TVPCRDAT] = 0x00; eieio();
}
for (x = 0; x < 0x200; x++) {
par->cmap_regs[TVPCRDAT] = 0xff; eieio();
}
par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
par->cmap_regs[TVPIDATA] &= 0x03; eieio();
for (y = 0; y < height; y++)
for (x = 0; x < width >> 3; x++) {
par->cmap_regs[TVPADDRW] = x + y * 8; eieio();
par->cmap_regs[TVPCRDAT] = 0xff; eieio();
}
par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
par->cmap_regs[TVPIDATA] |= 0x08; eieio();
for (y = 0; y < height; y++)
for (x = 0; x < width >> 3; x++) {
par->cmap_regs[TVPADDRW] = x + y * 8; eieio();
par->cmap_regs[TVPCRDAT] = 0xff; eieio();
}
par->cmap_regs[TVPCADRW] = 0x00; eieio();
for (x = 0; x < 12; x++) {
par->cmap_regs[TVPCDATA] = fgc;
eieio();
}
}
return 1;
}
static void
imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on)
{
if (par->ramdac == IBM) {
par->cmap_regs[PIDXHI] = 0; eieio();
if (!on) {
par->cmap_regs[PIDXLO] = CURSCTL; eieio();
par->cmap_regs[PIDXDATA] = 0x00; eieio();
} else {
par->cmap_regs[PIDXLO] = CURSXHI; eieio();
par->cmap_regs[PIDXDATA] = d->dx >> 8; eieio();
par->cmap_regs[PIDXLO] = CURSXLO; eieio();
par->cmap_regs[PIDXDATA] = d->dx & 0xff;eieio();
par->cmap_regs[PIDXLO] = CURSYHI; eieio();
par->cmap_regs[PIDXDATA] = d->dy >> 8; eieio();
par->cmap_regs[PIDXLO] = CURSYLO; eieio();
par->cmap_regs[PIDXDATA] = d->dy & 0xff;eieio();
par->cmap_regs[PIDXLO] = CURSCTL; eieio();
par->cmap_regs[PIDXDATA] = 0x02; eieio();
}
} else {
if (!on) {
par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
par->cmap_regs[TVPIDATA] = 0x00; eieio();
} else {
__u16 x = d->dx + 0x40, y = d->dy + 0x40;
par->cmap_regs[TVPCXPOH] = x >> 8; eieio();
par->cmap_regs[TVPCXPOL] = x & 0xff; eieio();
par->cmap_regs[TVPCYPOH] = y >> 8; eieio();
par->cmap_regs[TVPCYPOL] = y & 0xff; eieio();
par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
par->cmap_regs[TVPIDATA] = 0x02; eieio();
}
}
}
static int
imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct imstt_par *par = info->par;
u32 flags = cursor->set, fg, bg, xx, yy;
if (cursor->dest == NULL && cursor->rop == ROP_XOR)
return 1;
imstt_set_cursor(info, cursor, 0);
if (flags & FB_CUR_SETPOS) {
xx = cursor->image.dx - info->var.xoffset;
yy = cursor->image.dy - info->var.yoffset;
}
if (flags & FB_CUR_SETSIZE) {
}
if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
int fg_idx = cursor->image.fg_color;
int width = (cursor->image.width+7)/8;
u8 *dat = (u8 *) cursor->image.data;
u8 *dst = (u8 *) cursor->dest;
u8 *msk = (u8 *) cursor->mask;
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < cursor->image.height; i++) {
for (j = 0; j < width; j++) {
d_idx = i * MAX_CURS/8 + j;
data[d_idx] = byte_rev[dat[s_idx] ^
dst[s_idx]];
mask[d_idx] = byte_rev[msk[s_idx]];
s_idx++;
}
}
break;
case ROP_COPY:
default:
for (i = 0; i < cursor->image.height; i++) {
for (j = 0; j < width; j++) {
d_idx = i * MAX_CURS/8 + j;
data[d_idx] = byte_rev[dat[s_idx]];
mask[d_idx] = byte_rev[msk[s_idx]];
s_idx++;
}
}
break;
}
fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
((info->cmap.green[fg_idx] & 0xf8) << 2) |
((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
imsttfb_load_cursor_image(par, xx, yy, fgc);
}
if (cursor->enable)
imstt_set_cursor(info, cursor, 1);
return 0;
}
#endif
#define FBIMSTT_SETREG …
#define FBIMSTT_GETREG …
#define FBIMSTT_SETCMAPREG …
#define FBIMSTT_GETCMAPREG …
#define FBIMSTT_SETIDXREG …
#define FBIMSTT_GETIDXREG …
static int
imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{ … }
static const struct pci_device_id imsttfb_pci_tbl[] = …;
MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl);
static struct pci_driver imsttfb_pci_driver = …;
static const struct fb_ops imsttfb_ops = …;
static int init_imstt(struct fb_info *info)
{ … }
static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{ … }
static void imsttfb_remove(struct pci_dev *pdev)
{ … }
#ifndef MODULE
static int __init
imsttfb_setup(char *options)
{ … }
#endif
static int __init imsttfb_init(void)
{ … }
static void __exit imsttfb_exit(void)
{ … }
MODULE_LICENSE(…) …;
module_init(…) …;
module_exit(imsttfb_exit);