/*
* controlfb.c -- frame buffer device for the PowerMac 'control' display
*
* Created 12 July 1998 by Dan Jacobowitz <dan@debian.org>
* Copyright (C) 1998 Dan Jacobowitz
* Copyright (C) 2001 Takashi Oe
*
* Mmap code by Michel Lanners <mlan@cpu.lu>
*
* Frame buffer structure from:
* drivers/video/chipsfb.c -- frame buffer device for
* Chips & Technologies 65550 chip.
*
* Copyright (C) 1998 Paul Mackerras
*
* This file is derived from the Powermac "chips" driver:
* Copyright (C) 1997 Fabio Riccardi.
* And from the frame buffer device for Open Firmware-initialized devices:
* Copyright (C) 1997 Geert Uytterhoeven.
*
* Hardware information from:
* control.c: Console support for PowerMac "control" display adaptor.
* Copyright (C) 1996 Paul Mackerras
*
* Updated to 2.5 framebuffer API by Ben Herrenschmidt
* <benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>,
* and James Simmons <jsimmons@infradead.org>.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.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 <linux/nvram.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pgtable.h>
#include <asm/btext.h>
#include "macmodes.h"
#include "controlfb.h"
struct fb_par_control {
int vmode, cmode;
int xres, yres;
int vxres, vyres;
int xoffset, yoffset;
int pitch;
struct control_regvals regvals;
unsigned long sync;
unsigned char ctrl;
};
#define DIRTY(z) ((x)->z != (y)->z)
#define DIRTY_CMAP(z) (memcmp(&((x)->z), &((y)->z), sizeof((y)->z)))
static inline int PAR_EQUAL(struct fb_par_control *x, struct fb_par_control *y)
{
int i, results;
results = 1;
for (i = 0; i < 3; i++)
results &= !DIRTY(regvals.clock_params[i]);
if (!results)
return 0;
for (i = 0; i < 16; i++)
results &= !DIRTY(regvals.regs[i]);
if (!results)
return 0;
return (!DIRTY(cmode) && !DIRTY(xres) && !DIRTY(yres)
&& !DIRTY(vxres) && !DIRTY(vyres));
}
static inline int VAR_MATCH(struct fb_var_screeninfo *x, struct fb_var_screeninfo *y)
{
return (!DIRTY(bits_per_pixel) && !DIRTY(xres)
&& !DIRTY(yres) && !DIRTY(xres_virtual)
&& !DIRTY(yres_virtual)
&& !DIRTY_CMAP(red) && !DIRTY_CMAP(green) && !DIRTY_CMAP(blue));
}
struct fb_info_control {
struct fb_info info;
struct fb_par_control par;
u32 pseudo_palette[16];
struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
struct control_regs __iomem *control_regs;
unsigned long control_regs_phys;
unsigned long control_regs_size;
__u8 __iomem *frame_buffer;
unsigned long frame_buffer_phys;
unsigned long fb_orig_base;
unsigned long fb_orig_size;
int control_use_bank2;
unsigned long total_vram;
unsigned char vram_attr;
};
/* control register access macro */
#define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r))
/******************** Prototypes for exported functions ********************/
/*
* struct fb_ops
*/
static int controlfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int controlfb_blank(int blank_mode, struct fb_info *info);
static int controlfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
static int controlfb_set_par (struct fb_info *info);
static int controlfb_check_var (struct fb_var_screeninfo