File Index
Files and directories
Sign in
FILE

cyber2000fb.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/cyber2000fb.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  linux/drivers/video/cyber2000fb.c
   4 *
   5 *  Copyright (C) 1998-2002 Russell King
   6 *
   7 *  MIPS and 50xx clock support
   8 *  Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
   9 *
  10 *  32 bit support, text color and panning fixes for modes != 8 bit
  11 *  Copyright (C) 2002 Denis Oliver Kropp <dok@directfb.org>
  12 *
  13 * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
  14 *
  15 * Based on cyberfb.c.
  16 *
  17 * Note that we now use the new fbcon fix, var and cmap scheme.  We do
  18 * still have to check which console is the currently displayed one
  19 * however, especially for the colourmap stuff.
  20 *
  21 * We also use the new hotplug PCI subsystem.  I'm not sure if there
  22 * are any such cards, but I'm erring on the side of caution.  We don't
  23 * want to go pop just because someone does have one.
  24 *
  25 * Note that this doesn't work fully in the case of multiple CyberPro
  26 * cards with grabbers.  We currently can only attach to the first
  27 * CyberPro card found.
  28 *
  29 * When we're in truecolour mode, we power down the LUT RAM as a power
  30 * saving feature.  Also, when we enter any of the powersaving modes
  31 * (except soft blanking) we power down the RAMDACs.  This saves about
  32 * 1W, which is roughly 8% of the power consumption of a NetWinder
  33 * (which, incidentally, is about the same saving as a 2.5in hard disk
  34 * entering standby mode.)
  35 */
  36#include <linux/aperture.h>
  37#include <linux/module.h>
  38#include <linux/kernel.h>
  39#include <linux/errno.h>
  40#include <linux/string.h>
  41#include <linux/mm.h>
  42#include <linux/slab.h>
  43#include <linux/delay.h>
  44#include <linux/fb.h>
  45#include <linux/pci.h>
  46#include <linux/init.h>
  47#include <linux/io.h>
  48#include <linux/i2c.h>
  49#include <linux/i2c-algo-bit.h>
  50
  51#ifdef __arm__
  52#include <asm/mach-types.h>
  53#endif
  54
  55#include "cyber2000fb.h"
  56
  57struct cfb_info {
  58	struct fb_info		fb;
  59	struct display_switch	*dispsw;
  60	unsigned char		__iomem *region;
  61	unsigned char		__iomem *regs;
  62	u_int			id;
  63	u_int			irq;
  64	int			func_use_count;
  65	u_long			ref_ps;
  66
  67	/*
  68	 * Clock divisors
  69	 */
  70	u_int			divisors[4];
  71
  72	struct {
  73		u8 red, green, blue;
  74	} palette[NR_PALETTE];
  75
  76	u_char			mem_ctl1;
  77	u_char			mem_ctl2;
  78	u_char			mclk_mult;
  79	u_char			mclk_div;
  80	/*
  81	 * RAMDAC control register is both of these or'ed together
  82	 */
  83	u_char			ramdac_ctrl;
  84	u_char			ramdac_powerdown;
  85
  86	u32			pseudo_palette[16];
  87
  88	spinlock_t		reg_b0_lock;
  89
  90#ifdef CONFIG_FB_CYBER2000_DDC
  91	bool			ddc_registered;
  92	struct i2c_adapter	ddc_adapter;
  93	struct i2c_algo_bit_data	ddc_algo;
  94#endif
  95
  96#ifdef CONFIG_FB_CYBER2000_I2C
  97	struct i2c_adapter	i2c_adapter;
  98	struct i2c_algo_bit_data i2c_algo;
  99#endif
 100};
 101
 102static char *default_font = "Acorn8x8";
 103module_param(default_font, charp, 0);
 104MODULE_PARM_DESC(default_font, "Default font name");
 105
 106/*
 107 * Our access methods.
 108 */
 109#define cyber2000fb_writel(val, reg, cfb)	writel(val, (cfb)->regs + (reg))
 110#define cyber2000fb_writew(val, reg, cfb)	writew(val, (cfb)->regs + (reg))
 111#define cyber2000fb_writeb(val, reg, cfb)	writeb(val, (cfb)->regs + (reg))
 112
 113#define cyber2000fb_readb(reg, cfb)		readb((cfb)->regs + (reg))
 114
 115static inline void
 116cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 117{
 118	cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);
 119}
 120
 121static inline void
 122cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 123{
 124	cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
 125}
 126
 127static inline unsigned int
 128cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
 129{
 130	cyber2000fb_writeb(reg, 0x3ce, cfb);
 131	return cyber2000fb_readb(0x3cf, cfb);
 132}
 133
 134static inline void
 135cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 136{
 137	cyber2000fb_readb(0x3da, cfb);
 138	cyber2000fb_writeb(reg, 0x3c0, cfb);
 139	cyber2000fb_readb(0x3c1, cfb);
 140	cyber2000fb_writeb(val, 0x3c0, cfb);
 141}
 142
 143static inline void
 144cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 145{
 146	cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
 147}
 148
 149/* -------------------- Hardware specific routines ------------------------- */
 150
 151/*
 152 * Hardware Cyber2000 Acceleration
 153 */
 154static void
 155cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 156{
 157	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 158	unsigned long dst, col;
 159
 160	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
 161		cfb_fillrect(info, rect);
 162		return;
 163	}
 164
 165	cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 166	cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb);
 167	cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
 168
 169	col = rect->color;
 170	if (cfb->fb.var.bits_per_pixel > 8)
 171		col = ((u32 *)cfb->fb.pseudo_palette)[col];
 172	cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
 173
 174	dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
 175	if (cfb->fb.var.bits_per_pixel == 24) {
 176		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 177		dst *= 3;
 178	}
 179
 180	cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
 181	cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
 182	cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
 183	cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
 184}
 185
 186static void
 187cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 188{
 189	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 190	unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
 191	unsigned long src, dst;
 192
 193	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
 194		cfb_copyarea(info, region);
 195		return;
 196	}
 197
 198	cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 199	cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
 200	cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
 201
 202	src = region->sx + region->sy * cfb->fb.var.xres_virtual;
 203	dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
 204
 205	if (region->sx < region->dx) {
 206		src += region->width - 1;
 207		dst += region->width - 1;
 208		cmd |= CO_CMD_L_INC_LEFT;
 209	}
 210
 211	if (region->sy < region->dy) {
 212		src += (region->height - 1) * cfb->fb.var.xres_virtual;
 213		dst += (region->height - 1) * cfb->fb.var.xres_virtual;
 214		cmd |= CO_CMD_L_INC_UP;
 215	}
 216
 217	if (cfb->fb.var.bits_per_pixel == 24) {
 218		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 219		src *= 3;
 220		dst *= 3;
 221	}
 222	cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
 223	cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
 224	cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
 225	cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
 226	cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER,
 227			   CO_REG_CMD_H, cfb);
 228}
 229
 230static int cyber2000fb_sync(struct fb_info *info)
 231{
 232	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 233	int count = 100000;
 234
 235	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
 236		return 0;
 237
 238	while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
 239		if (!count--) {
 240			debug_printf("accel_wait timed out\n");
 241			cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 242			break;
 243		}
 244		udelay(1);
 245	}
 246	return 0;
 247}
 248
 249/*
 250 * ===========================================================================
 251 */
 252
 253static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
 254{
 255	u_int mask = (1 << bf->length) - 1;
 256
 257	return (val >> (16 - bf->length) & mask) << bf->offset;
 258}
 259
 260/*
 261 *    Set a single color register. Return != 0 for invalid regno.
 262 */
 263static int
 264cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 265		      u_int transp, struct fb_info *info)
 266{
 267	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 268	struct fb_var_screeninfo *var = &cfb->fb.var;
 269	u32 pseudo_val;
 270	int ret = 1;
 271
 272	switch (cfb->fb.fix.visual) {
 273	default:
 274		return 1;
 275
 276	/*
 277	 * Pseudocolour:
 278	 *	   8     8
 279	 * pixel --/--+--/-->  red lut  --> red dac
 280	 *	      |  8
 281	 *	      +--/--> green lut --> green dac
 282	 *	      |  8
 283	 *	      +--/-->  blue lut --> blue dac
 284	 */
 285	case FB_VISUAL_PSEUDOCOLOR:
 286		if (regno >= NR_PALETTE)
 287			return 1;
 288
 289		red >>= 8;
 290		green >>= 8;
 291		blue >>= 8;
 292
 293		cfb->palette[regno].red = red;
 294		cfb->palette[regno].green = green;
 295		cfb->palette[regno].blue = blue;
 296
 297		cyber2000fb_writeb(regno, 0x3c8, cfb);
 298		cyber2000fb_writeb(red, 0x3c9, cfb);
 299		cyber2000fb_writeb(green, 0x3c9, cfb);
 300		cyber2000fb_writeb(blue, 0x3c9, cfb);
 301		return 0;
 302
 303	/*
 304	 * Direct colour:
 305	 *	   n     rl
 306	 * pixel --/--+--/-->  red lut  --> red dac
 307	 *	      |  gl
 308	 *	      +--/--> green lut --> green dac
 309	 *	      |  bl
 310	 *	      +--/-->  blue lut --> blue dac
 311	 * n = bpp, rl = red length, gl = green length, bl = blue length
 312	 */
 313	case FB_VISUAL_DIRECTCOLOR:
 314		red >>= 8;
 315		green >>= 8;
 316		blue >>= 8;
 317
 318		if (var->green.length == 6 && regno < 64) {
 319			cfb->palette[regno << 2].green = green;
 320
 321			/*
 322			 * The 6 bits of the green component are applied
 323			 * to the high 6 bits of the LUT.
 324			 */
 325			cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
 326			cyber2000fb_writeb(cfb->palette[regno >> 1].red,
 327					   0x3c9, cfb);
 328			cyber2000fb_writeb(green, 0x3c9, cfb);
 329			cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
 330					   0x3c9, cfb);
 331
 332			green = cfb->palette[regno << 3].green;
 333
 334			ret = 0;
 335		}
 336
 337		if (var->green.length >= 5 && regno < 32) {
 338			cfb->palette[regno << 3].red = red;
 339			cfb->palette[regno << 3].green = green;
 340			cfb->palette[regno << 3].blue = blue;
 341
 342			/*
 343			 * The 5 bits of each colour component are
 344			 * applied to the high 5 bits of the LUT.
 345			 */
 346			cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
 347			cyber2000fb_writeb(red, 0x3c9, cfb);
 348			cyber2000fb_writeb(green, 0x3c9, cfb);
 349			cyber2000fb_writeb(blue, 0x3c9, cfb);
 350			ret = 0;
 351		}
 352
 353		if (var->green.length == 4 && regno < 16) {
 354			cfb->palette[regno << 4].red = red;
 355			cfb->palette[regno << 4].green = green;
 356			cfb->palette[regno << 4].blue = blue;
 357
 358			/*
 359			 * The 5 bits of each colour component are
 360			 * applied to the high 5 bits of the LUT.
 361			 */
 362			cyber2000fb_writeb(regno << 4, 0x3c8, cfb);
 363			cyber2000fb_writeb(red, 0x3c9, cfb);
 364			cyber2000fb_writeb(green, 0x3c9, cfb);
 365			cyber2000fb_writeb(blue, 0x3c9, cfb);
 366			ret = 0;
 367		}
 368
 369		/*
 370		 * Since this is only used for the first 16 colours, we
 371		 * don't have to care about overflowing for regno >= 32
 372		 */
 373		pseudo_val = regno << var->red.offset |
 374			     regno << var->green.offset |
 375			     regno << var->blue.offset;
 376		break;
 377
 378	/*
 379	 * True colour:
 380	 *	   n     rl
 381	 * pixel --/--+--/--> red dac
 382	 *	      |  gl
 383	 *	      +--/--> green dac
 384	 *	      |  bl
 385	 *	      +--/--> blue dac
 386	 * n = bpp, rl = red length, gl = green length, bl = blue length
 387	 */
 388	case FB_VISUAL_TRUECOLOR:
 389		pseudo_val = convert_bitfield(transp ^ 0xffff, &var->transp);
 390		pseudo_val |= convert_bitfield(red, &var->red);
 391		pseudo_val |= convert_bitfield(green, &var->green);
 392		pseudo_val |= convert_bitfield(blue, &var->blue);
 393		ret = 0;
 394		break;
 395	}
 396
 397	/*
 398	 * Now set our pseudo palette for the CFB16/24/32 drivers.
 399	 */
 400	if (regno < 16)
 401		((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
 402
 403	return ret;
 404}
 405
 406struct par_info {
 407	/*
 408	 * Hardware
 409	 */
 410	u_char	clock_mult;
 411	u_char	clock_div;
 412	u_char	extseqmisc;
 413	u_char	co_pixfmt;
 414	u_char	crtc_ofl;
 415	u_char	crtc[19];
 416	u_int	width;
 417	u_int	pitch;
 418	u_int	fetch;
 419
 420	/*
 421	 * Other
 422	 */
 423	u_char	ramdac;
 424};
 425
 426static const u_char crtc_idx[] = {
 427	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 428	0x08, 0x09,
 429	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
 430};
 431
 432static void cyber2000fb_write_ramdac_ctrl(struct cfb_info *cfb)
 433{
 434	unsigned int i;
 435	unsigned int val = cfb->ramdac_ctrl | cfb->ramdac_powerdown;
 436
 437	cyber2000fb_writeb(0x56, 0x3ce, cfb);
 438	i = cyber2000fb_readb(0x3cf, cfb);
 439	cyber2000fb_writeb(i | 4, 0x3cf, cfb);
 440	cyber2000fb_writeb(val, 0x3c6, cfb);
 441	cyber2000fb_writeb(i, 0x3cf, cfb);
 442	/* prevent card lock-up observed on x86 with CyberPro 2000 */
 443	cyber2000fb_readb(0x3cf, cfb);
 444}
 445
 446static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
 447{
 448	u_int i;
 449
 450	/*
 451	 * Blank palette
 452	 */
 453	for (i = 0; i < NR_PALETTE; i++) {
 454		cyber2000fb_writeb(i, 0x3c8, cfb);
 455		cyber2000fb_writeb(0, 0x3c9, cfb);
 456		cyber2000fb_writeb(0, 0x3c9, cfb);
 457		cyber2000fb_writeb(0, 0x3c9, cfb);
 458	}
 459
 460	cyber2000fb_writeb(0xef, 0x3c2, cfb);
 461	cyber2000_crtcw(0x11, 0x0b, cfb);
 462	cyber2000_attrw(0x11, 0x00, cfb);
 463
 464	cyber2000_seqw(0x00, 0x01, cfb);
 465	cyber2000_seqw(0x01, 0x01, cfb);
 466	cyber2000_seqw(0x02, 0x0f, cfb);
 467	cyber2000_seqw(0x03, 0x00, cfb);
 468	cyber2000_seqw(0x04, 0x0e, cfb);
 469	cyber2000_seqw(0x00, 0x03, cfb);
 470
 471	for (i = 0; i < sizeof(crtc_idx); i++)
 472		cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
 473
 474	for (i = 0x0a; i < 0x10; i++)
 475		cyber2000_crtcw(i, 0, cfb);
 476
 477	cyber2000_grphw(EXT_CRT_VRTOFL, hw->crtc_ofl, cfb);
 478	cyber2000_grphw(0x00, 0x00, cfb);
 479	cyber2000_grphw(0x01, 0x00, cfb);
 480	cyber2000_grphw(0x02, 0x00, cfb);
 481	cyber2000_grphw(0x03, 0x00, cfb);
 482	cyber2000_grphw(0x04, 0x00, cfb);
 483	cyber2000_grphw(0x05, 0x60, cfb);
 484	cyber2000_grphw(0x06, 0x05, cfb);
 485	cyber2000_grphw(0x07, 0x0f, cfb);
 486	cyber2000_grphw(0x08, 0xff, cfb);
 487
 488	/* Attribute controller registers */
 489	for (i = 0; i < 16; i++)
 490		cyber2000_attrw(i, i, cfb);
 491
 492	cyber2000_attrw(0x10, 0x01, cfb);
 493	cyber2000_attrw(0x11, 0x00, cfb);
 494	cyber2000_attrw(0x12, 0x0f, cfb);
 495	cyber2000_attrw(0x13, 0x00, cfb);
 496	cyber2000_attrw(0x14, 0x00, cfb);
 497
 498	/* PLL registers */
 499	spin_lock(&cfb->reg_b0_lock);
 500	cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
 501	cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
 502	cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
 503	cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
 504	cyber2000_grphw(0x90, 0x01, cfb);
 505	cyber2000_grphw(0xb9, 0x80, cfb);
 506	cyber2000_grphw(0xb9, 0x00, cfb);
 507	spin_unlock(&cfb->reg_b0_lock);
 508
 509	cfb->ramdac_ctrl = hw->ramdac;
 510	cyber2000fb_write_ramdac_ctrl(cfb);
 511
 512	cyber2000fb_writeb(0x20, 0x3c0, cfb);
 513	cyber2000fb_writeb(0xff, 0x3c6, cfb);
 514
 515	cyber2000_grphw(0x14, hw->fetch, cfb);
 516	cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
 517			      ((hw->pitch >> 4) & 0x30), cfb);
 518	cyber2000_grphw(EXT_SEQ_MISC, hw->extseqmisc, cfb);
 519
 520	/*
 521	 * Set up accelerator registers
 522	 */
 523	cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
 524	cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
 525	cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
 526}
 527
 528static inline int
 529cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
 530{
 531	u_int base = var->yoffset * var->xres_virtual + var->xoffset;
 532
 533	base *= var->bits_per_pixel;
 534
 535	/*
 536	 * Convert to bytes and shift two extra bits because DAC
 537	 * can only start on 4 byte aligned data.
 538	 */
 539	base >>= 5;
 540
 541	if (base >= 1 << 20)
 542		return -EINVAL;
 543
 544	cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
 545	cyber2000_crtcw(0x0c, base >> 8, cfb);
 546	cyber2000_crtcw(0x0d, base, cfb);
 547
 548	return 0;
 549}
 550
 551static int
 552cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
 553			struct fb_var_screeninfo *var)
 554{
 555	u_int Htotal, Hblankend, Hsyncend;
 556	u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
 557#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
 558
 559	hw->crtc[13] = hw->pitch;
 560	hw->crtc[17] = 0xe3;
 561	hw->crtc[14] = 0;
 562	hw->crtc[8]  = 0;
 563
 564	Htotal     = var->xres + var->right_margin +
 565		     var->hsync_len + var->left_margin;
 566
 567	if (Htotal > 2080)
 568		return -EINVAL;
 569
 570	hw->crtc[0] = (Htotal >> 3) - 5;
 571	hw->crtc[1] = (var->xres >> 3) - 1;
 572	hw->crtc[2] = var->xres >> 3;
 573	hw->crtc[4] = (var->xres + var->right_margin) >> 3;
 574
 575	Hblankend   = (Htotal - 4 * 8) >> 3;
 576
 577	hw->crtc[3] = ENCODE_BIT(Hblankend,  0, 0x1f,  0) |
 578		      ENCODE_BIT(1,          0, 0x01,  7);
 579
 580	Hsyncend    = (var->xres + var->right_margin + var->hsync_len) >> 3;
 581
 582	hw->crtc[5] = ENCODE_BIT(Hsyncend,   0, 0x1f,  0) |
 583		      ENCODE_BIT(Hblankend,  5, 0x01,  7);
 584
 585	Vdispend    = var->yres - 1;
 586	Vsyncstart  = var->yres + var->lower_margin;
 587	Vsyncend    = var->yres + var->lower_margin + var->vsync_len;
 588	Vtotal      = var->yres + var->lower_margin + var->vsync_len +
 589		      var->upper_margin - 2;
 590
 591	if (Vtotal > 2047)
 592		return -EINVAL;
 593
 594	Vblankstart = var->yres + 6;
 595	Vblankend   = Vtotal - 10;
 596
 597	hw->crtc[6]  = Vtotal;
 598	hw->crtc[7]  = ENCODE_BIT(Vtotal,     8, 0x01,  0) |
 599			ENCODE_BIT(Vdispend,   8, 0x01,  1) |
 600			ENCODE_BIT(Vsyncstart, 8, 0x01,  2) |
 601			ENCODE_BIT(Vblankstart, 8, 0x01,  3) |
 602			ENCODE_BIT(1,          0, 0x01,  4) |
 603			ENCODE_BIT(Vtotal,     9, 0x01,  5) |
 604			ENCODE_BIT(Vdispend,   9, 0x01,  6) |
 605			ENCODE_BIT(Vsyncstart, 9, 0x01,  7);
 606	hw->crtc[9]  = ENCODE_BIT(0,          0, 0x1f,  0) |
 607			ENCODE_BIT(Vblankstart, 9, 0x01,  5) |
 608			ENCODE_BIT(1,          0, 0x01,  6);
 609	hw->crtc[10] = Vsyncstart;
 610	hw->crtc[11] = ENCODE_BIT(Vsyncend,   0, 0x0f,  0) |
 611		       ENCODE_BIT(1,          0, 0x01,  7);
 612	hw->crtc[12] = Vdispend;
 613	hw->crtc[15] = Vblankstart;
 614	hw->crtc[16] = Vblankend;
 615	hw->crtc[18] = 0xff;
 616
 617	/*
 618	 * overflow - graphics reg 0x11
 619	 * 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
 620	 * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
 621	 */
 622	hw->crtc_ofl =
 623		ENCODE_BIT(Vtotal, 10, 0x01, 0) |
 624		ENCODE_BIT(Vdispend, 10, 0x01, 1) |
 625		ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
 626		ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
 627		EXT_CRT_VRTOFL_LINECOMP10;
 628
 629	/* woody: set the interlaced bit... */
 630	/* FIXME: what about doublescan? */
 631	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
 632		hw->crtc_ofl |= EXT_CRT_VRTOFL_INTERLACE;
 633
 634	return 0;
 635}
 636
 637/*
 638 * The following was discovered by a good monitor, bit twiddling, theorising
 639 * and but mostly luck.  Strangely, it looks like everyone elses' PLL!
 640 *
 641 * Clock registers:
 642 *   fclock = fpll / div2
 643 *   fpll   = fref * mult / div1
 644 * where:
 645 *   fref = 14.318MHz (69842ps)
 646 *   mult = reg0xb0.7:0
 647 *   div1 = (reg0xb1.5:0 + 1)
 648 *   div2 =  2^(reg0xb1.7:6)
 649 *   fpll should be between 115 and 260 MHz
 650 *  (8696ps and 3846ps)
 651 */
 652static int
 653cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
 654			 struct fb_var_screeninfo *var)
 655{
 656	u_long pll_ps = var->pixclock;
 657	const u_long ref_ps = cfb->ref_ps;
 658	u_int div2, t_div1, best_div1, best_mult;
 659	int best_diff;
 660	int vco;
 661
 662	/*
 663	 * Step 1:
 664	 *   find div2 such that 115MHz < fpll < 260MHz
 665	 *   and 0 <= div2 < 4
 666	 */
 667	for (div2 = 0; div2 < 4; div2++) {
 668		u_long new_pll;
 669
 670		new_pll = pll_ps / cfb->divisors[div2];
 671		if (8696 > new_pll && new_pll > 3846) {
 672			pll_ps = new_pll;
 673			break;
 674		}
 675	}
 676
 677	if (div2 == 4)
 678		return -EINVAL;
 679
 680	/*
 681	 * Step 2:
 682	 *  Given pll_ps and ref_ps, find:
 683	 *    pll_ps * 0.995 < pll_ps_calc < pll_ps * 1.005
 684	 *  where { 1 < best_div1 < 32, 1 < best_mult < 256 }
 685	 *    pll_ps_calc = best_div1 / (ref_ps * best_mult)
 686	 */
 687	best_diff = 0x7fffffff;
 688	best_mult = 2;
 689	best_div1 = 32;
 690	for (t_div1 = 2; t_div1 < 32; t_div1 += 1) {
 691		u_int rr, t_mult, t_pll_ps;
 692		int diff;
 693
 694		/*
 695		 * Find the multiplier for this divisor
 696		 */
 697		rr = ref_ps * t_div1;
 698		t_mult = (rr + pll_ps / 2) / pll_ps;
 699
 700		/*
 701		 * Is the multiplier within the correct range?
 702		 */
 703		if (t_mult > 256 || t_mult < 2)
 704			continue;
 705
 706		/*
 707		 * Calculate the actual clock period from this multiplier
 708		 * and divisor, and estimate the error.
 709		 */
 710		t_pll_ps = (rr + t_mult / 2) / t_mult;
 711		diff = pll_ps - t_pll_ps;
 712		if (diff < 0)
 713			diff = -diff;
 714
 715		if (diff < best_diff) {
 716			best_diff = diff;
 717			best_mult = t_mult;
 718			best_div1 = t_div1;
 719		}
 720
 721		/*
 722		 * If we hit an exact value, there is no point in continuing.
 723		 */
 724		if (diff == 0)
 725			break;
 726	}
 727
 728	/*
 729	 * Step 3:
 730	 *  combine values
 731	 */
 732	hw->clock_mult = best_mult - 1;
 733	hw->clock_div  = div2 << 6 | (best_div1 - 1);
 734
 735	vco = ref_ps * best_div1 / best_mult;
 736	if ((ref_ps == 40690) && (vco < 5556))
 737		/* Set VFSEL when VCO > 180MHz (5.556 ps). */
 738		hw->clock_div |= EXT_DCLK_DIV_VFSEL;
 739
 740	return 0;
 741}
 742
 743/*
 744 *    Set the User Defined Part of the Display
 745 */
 746static int
 747cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 748{
 749	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 750	struct par_info hw;
 751	unsigned int mem;
 752	int err;
 753
 754	var->transp.msb_right	= 0;
 755	var->red.msb_right	= 0;
 756	var->green.msb_right	= 0;
 757	var->blue.msb_right	= 0;
 758	var->transp.offset	= 0;
 759	var->transp.length	= 0;
 760
 761	switch (var->bits_per_pixel) {
 762	case 8:	/* PSEUDOCOLOUR, 256 */
 763		var->red.offset		= 0;
 764		var->red.length		= 8;
 765		var->green.offset	= 0;
 766		var->green.length	= 8;
 767		var->blue.offset	= 0;
 768		var->blue.length	= 8;
 769		break;
 770
 771	case 16:/* DIRECTCOLOUR, 64k or 32k */
 772		switch (var->green.length) {
 773		case 6: /* RGB565, 64k */
 774			var->red.offset		= 11;
 775			var->red.length		= 5;
 776			var->green.offset	= 5;
 777			var->green.length	= 6;
 778			var->blue.offset	= 0;
 779			var->blue.length	= 5;
 780			break;
 781
 782		default:
 783		case 5: /* RGB555, 32k */
 784			var->red.offset		= 10;
 785			var->red.length		= 5;
 786			var->green.offset	= 5;
 787			var->green.length	= 5;
 788			var->blue.offset	= 0;
 789			var->blue.length	= 5;
 790			break;
 791
 792		case 4: /* RGB444, 4k + transparency? */
 793			var->transp.offset	= 12;
 794			var->transp.length	= 4;
 795			var->red.offset		= 8;
 796			var->red.length		= 4;
 797			var->green.offset	= 4;
 798			var->green.length	= 4;
 799			var->blue.offset	= 0;
 800			var->blue.length	= 4;
 801			break;
 802		}
 803		break;
 804
 805	case 24:/* TRUECOLOUR, 16m */
 806		var->red.offset		= 16;
 807		var->red.length		= 8;
 808		var->green.offset	= 8;
 809		var->green.length	= 8;
 810		var->blue.offset	= 0;
 811		var->blue.length	= 8;
 812		break;
 813
 814	case 32:/* TRUECOLOUR, 16m */
 815		var->transp.offset	= 24;
 816		var->transp.length	= 8;
 817		var->red.offset		= 16;
 818		var->red.length		= 8;
 819		var->green.offset	= 8;
 820		var->green.length	= 8;
 821		var->blue.offset	= 0;
 822		var->blue.length	= 8;
 823		break;
 824
 825	default:
 826		return -EINVAL;
 827	}
 828
 829	mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
 830	if (mem > cfb->fb.fix.smem_len)
 831		var->yres_virtual = cfb->fb.fix.smem_len * 8 /
 832				    (var->bits_per_pixel * var->xres_virtual);
 833
 834	if (var->yres > var->yres_virtual)
 835		var->yres = var->yres_virtual;
 836	if (var->xres > var->xres_virtual)
 837		var->xres = var->xres_virtual;
 838
 839	err = cyber2000fb_decode_clock(&hw, cfb, var);
 840	if (err)
 841		return err;
 842
 843	err = cyber2000fb_decode_crtc(&hw, cfb, var);
 844	if (err)
 845		return err;
 846
 847	return 0;
 848}
 849
 850static int cyber2000fb_set_par(struct fb_info *info)
 851{
 852	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 853	struct fb_var_screeninfo *var = &cfb->fb.var;
 854	struct par_info hw;
 855	unsigned int mem;
 856
 857	hw.width = var->xres_virtual;
 858	hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
 859
 860	switch (var->bits_per_pixel) {
 861	case 8:
 862		hw.co_pixfmt		= CO_PIXFMT_8BPP;
 863		hw.pitch		= hw.width >> 3;
 864		hw.extseqmisc		= EXT_SEQ_MISC_8;
 865		break;
 866
 867	case 16:
 868		hw.co_pixfmt		= CO_PIXFMT_16BPP;
 869		hw.pitch		= hw.width >> 2;
 870
 871		switch (var->green.length) {
 872		case 6: /* RGB565, 64k */
 873			hw.extseqmisc	= EXT_SEQ_MISC_16_RGB565;
 874			break;
 875		case 5: /* RGB555, 32k */
 876			hw.extseqmisc	= EXT_SEQ_MISC_16_RGB555;
 877			break;
 878		case 4: /* RGB444, 4k + transparency? */
 879			hw.extseqmisc	= EXT_SEQ_MISC_16_RGB444;
 880			break;
 881		default:
 882			BUG();
 883		}
 884		break;
 885
 886	case 24:/* TRUECOLOUR, 16m */
 887		hw.co_pixfmt		= CO_PIXFMT_24BPP;
 888		hw.width		*= 3;
 889		hw.pitch		= hw.width >> 3;
 890		hw.ramdac		|= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
 891		hw.extseqmisc		= EXT_SEQ_MISC_24_RGB888;
 892		break;
 893
 894	case 32:/* TRUECOLOUR, 16m */
 895		hw.co_pixfmt		= CO_PIXFMT_32BPP;
 896		hw.pitch		= hw.width >> 1;
 897		hw.ramdac		|= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
 898		hw.extseqmisc		= EXT_SEQ_MISC_32;
 899		break;
 900
 901	default:
 902		BUG();
 903	}
 904
 905	/*
 906	 * Sigh, this is absolutely disgusting, but caused by
 907	 * the way the fbcon developers want to separate out
 908	 * the "checking" and the "setting" of the video mode.
 909	 *
 910	 * If the mode is not suitable for the hardware here,
 911	 * we can't prevent it being set by returning an error.
 912	 *
 913	 * In theory, since NetWinders contain just one VGA card,
 914	 * we should never end up hitting this problem.
 915	 */
 916	BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0);
 917	BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0);
 918
 919	hw.width -= 1;
 920	hw.fetch = hw.pitch;
 921	if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
 922		hw.fetch <<= 1;
 923	hw.fetch += 1;
 924
 925	cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 926
 927	/*
 928	 * Same here - if the size of the video mode exceeds the
 929	 * available RAM, we can't prevent this mode being set.
 930	 *
 931	 * In theory, since NetWinders contain just one VGA card,
 932	 * we should never end up hitting this problem.
 933	 */
 934	mem = cfb->fb.fix.line_length * var->yres_virtual;
 935	BUG_ON(mem > cfb->fb.fix.smem_len);
 936
 937	/*
 938	 * 8bpp displays are always pseudo colour.  16bpp and above
 939	 * are direct colour or true colour, depending on whether
 940	 * the RAMDAC palettes are bypassed.  (Direct colour has
 941	 * palettes, true colour does not.)
 942	 */
 943	if (var->bits_per_pixel == 8)
 944		cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
 945	else if (hw.ramdac & RAMDAC_BYPASS)
 946		cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
 947	else
 948		cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
 949
 950	cyber2000fb_set_timing(cfb, &hw);
 951	cyber2000fb_update_start(cfb, var);
 952
 953	return 0;
 954}
 955
 956/*
 957 *    Pan or Wrap the Display
 958 */
 959static int
 960cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 961{
 962	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 963
 964	if (cyber2000fb_update_start(cfb, var))
 965		return -EINVAL;
 966
 967	cfb->fb.var.xoffset = var->xoffset;
 968	cfb->fb.var.yoffset = var->yoffset;
 969
 970	if (var->vmode & FB_VMODE_YWRAP) {
 971		cfb->fb.var.vmode |= FB_VMODE_YWRAP;
 972	} else {
 973		cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
 974	}
 975
 976	return 0;
 977}
 978
 979/*
 980 *    (Un)Blank the display.
 981 *
 982 *  Blank the screen if blank_mode != 0, else unblank. If
 983 *  blank == NULL then the caller blanks by setting the CLUT
 984 *  (Color Look Up Table) to all black. Return 0 if blanking
 985 *  succeeded, != 0 if un-/blanking failed due to e.g. a
 986 *  video mode which doesn't support it. Implements VESA
 987 *  suspend and powerdown modes on hardware that supports
 988 *  disabling hsync/vsync:
 989 *    blank_mode == 2: suspend vsync
 990 *    blank_mode == 3: suspend hsync
 991 *    blank_mode == 4: powerdown
 992 *
 993 *  wms...Enable VESA DMPS compatible powerdown mode
 994 *  run "setterm -powersave powerdown" to take advantage
 995 */
 996static int cyber2000fb_blank(int blank, struct fb_info *info)
 997{
 998	struct cfb_info *cfb = container_of(info, struct cfb_info, fb);
 999	unsigned int sync = 0;
1000	int i;
1001
1002	switch (blank) {
1003	case FB_BLANK_POWERDOWN:	/* powerdown - both sync lines down */
1004		sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
1005		break;
1006	case FB_BLANK_HSYNC_SUSPEND:	/* hsync off */
1007		sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
1008		break;
1009	case FB_BLANK_VSYNC_SUSPEND:	/* vsync off */
1010		sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
1011		break;
1012	case FB_BLANK_NORMAL:		/* soft blank */
1013	default:			/* unblank */
1014		break;
1015	}
1016
1017	cyber2000_grphw(EXT_SYNC_CTL, sync, cfb);
1018
1019	if (blank <= 1) {
1020		/* turn on ramdacs */
1021		cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1022					   RAMDAC_RAMPWRDN);
1023		cyber2000fb_write_ramdac_ctrl(cfb);
1024	}
1025
1026	/*
1027	 * Soft blank/unblank the display.
1028	 */
1029	if (blank) {	/* soft blank */
1030		for (i = 0; i < NR_PALETTE; i++) {
1031			cyber2000fb_writeb(i, 0x3c8, cfb);
1032			cyber2000fb_writeb(0, 0x3c9, cfb);
1033			cyber2000fb_writeb(0, 0x3c9, cfb);
1034			cyber2000fb_writeb(0, 0x3c9, cfb);
1035		}
1036	} else {	/* unblank */
1037		for (i = 0; i < NR_PALETTE; i++) {
1038			cyber2000fb_writeb(i, 0x3c8, cfb);
1039			cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
1040			cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
1041			cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
1042		}
1043	}
1044
1045	if (blank >= 2) {
1046		/* turn off ramdacs */
1047		cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1048					 RAMDAC_RAMPWRDN;
1049		cyber2000fb_write_ramdac_ctrl(cfb);
1050	}
1051
1052	return 0;
1053}
1054
1055static const struct fb_ops cyber2000fb_ops = {
1056	.owner		= THIS_MODULE,
1057	__FB_DEFAULT_IOMEM_OPS_RDWR,
1058	.fb_check_var	= cyber2000fb_check_var,
1059	.fb_set_par	= cyber2000fb_set_par,
1060	.fb_setcolreg	= cyber2000fb_setcolreg,
1061	.fb_blank	= cyber2000fb_blank,
1062	.fb_pan_display	= cyber2000fb_pan_display,
1063	.fb_fillrect	= cyber2000fb_fillrect,
1064	.fb_copyarea	= cyber2000fb_copyarea,
1065	.fb_imageblit	= cfb_imageblit,
1066	.fb_sync	= cyber2000fb_sync,
1067	__FB_DEFAULT_IOMEM_OPS_MMAP,
1068};
1069
1070/*
1071 * This is the only "static" reference to the internal data structures
1072 * of this driver.  It is here solely at the moment to support the other
1073 * CyberPro modules external to this driver.
1074 */
1075static struct cfb_info *int_cfb_info;
1076
1077/*
1078 * Enable access to the extended registers
1079 */
1080void cyber2000fb_enable_extregs(struct cfb_info *cfb)
1081{
1082	cfb->func_use_count += 1;
1083
1084	if (cfb->func_use_count == 1) {
1085		int old;
1086
1087		old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1088		old |= EXT_FUNC_CTL_EXTREGENBL;
1089		cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1090	}
1091}
1092
1093/*
1094 * Disable access to the extended registers
1095 */
1096void cyber2000fb_disable_extregs(struct cfb_info *cfb)
1097{
1098	if (cfb->func_use_count == 1) {
1099		int old;
1100
1101		old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1102		old &= ~EXT_FUNC_CTL_EXTREGENBL;
1103		cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1104	}
1105
1106	if (cfb->func_use_count == 0)
1107		printk(KERN_ERR "disable_extregs: count = 0\n");
1108	else
1109		cfb->func_use_count -= 1;
1110}
1111
1112#ifdef CONFIG_FB_CYBER2000_DDC
1113
1114#define DDC_REG		0xb0
1115#define DDC_SCL_OUT	(1 << 0)
1116#define DDC_SDA_OUT	(1 << 4)
1117#define DDC_SCL_IN	(1 << 2)
1118#define DDC_SDA_IN	(1 << 6)
1119
1120static void cyber2000fb_enable_ddc(struct cfb_info *cfb)
1121	__acquires(&cfb->reg_b0_lock)
1122{
1123	spin_lock(&cfb->reg_b0_lock);
1124	cyber2000fb_writew(0x1bf, 0x3ce, cfb);
1125}
1126
1127static void cyber2000fb_disable_ddc(struct cfb_info *cfb)
1128	__releases(&cfb->reg_b0_lock)
1129{
1130	cyber2000fb_writew(0x0bf, 0x3ce, cfb);
1131	spin_unlock(&cfb->reg_b0_lock);
1132}
1133
1134
1135static void cyber2000fb_ddc_setscl(void *data, int val)
1136{
1137	struct cfb_info *cfb = data;
1138	unsigned char reg;
1139
1140	cyber2000fb_enable_ddc(cfb);
1141	reg = cyber2000_grphr(DDC_REG, cfb);
1142	if (!val)	/* bit is inverted */
1143		reg |= DDC_SCL_OUT;
1144	else
1145		reg &= ~DDC_SCL_OUT;
1146	cyber2000_grphw(DDC_REG, reg, cfb);
1147	cyber2000fb_disable_ddc(cfb);
1148}
1149
1150static void cyber2000fb_ddc_setsda(void *data, int val)
1151{
1152	struct cfb_info *cfb = data;
1153	unsigned char reg;
1154
1155	cyber2000fb_enable_ddc(cfb);
1156	reg = cyber2000_grphr(DDC_REG, cfb);
1157	if (!val)	/* bit is inverted */
1158		reg |= DDC_SDA_OUT;
1159	else
1160		reg &= ~DDC_SDA_OUT;
1161	cyber2000_grphw(DDC_REG, reg, cfb);
1162	cyber2000fb_disable_ddc(cfb);
1163}
1164
1165static int cyber2000fb_ddc_getscl(void *data)
1166{
1167	struct cfb_info *cfb = data;
1168	int retval;
1169
1170	cyber2000fb_enable_ddc(cfb);
1171	retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SCL_IN);
1172	cyber2000fb_disable_ddc(cfb);
1173
1174	return retval;
1175}
1176
1177static int cyber2000fb_ddc_getsda(void *data)
1178{
1179	struct cfb_info *cfb = data;
1180	int retval;
1181
1182	cyber2000fb_enable_ddc(cfb);
1183	retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SDA_IN);
1184	cyber2000fb_disable_ddc(cfb);
1185
1186	return retval;
1187}
1188
1189static int cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
1190{
1191	strscpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
1192		sizeof(cfb->ddc_adapter.name));
1193	cfb->ddc_adapter.owner		= THIS_MODULE;
1194	cfb->ddc_adapter.algo_data	= &cfb->ddc_algo;
1195	cfb->ddc_adapter.dev.parent	= cfb->fb.device;
1196	cfb->ddc_algo.setsda		= cyber2000fb_ddc_setsda;
1197	cfb->ddc_algo.setscl		= cyber2000fb_ddc_setscl;
1198	cfb->ddc_algo.getsda		= cyber2000fb_ddc_getsda;
1199	cfb->ddc_algo.getscl		= cyber2000fb_ddc_getscl;
1200	cfb->ddc_algo.udelay		= 10;
1201	cfb->ddc_algo.timeout		= 20;
1202	cfb->ddc_algo.data		= cfb;
1203
1204	i2c_set_adapdata(&cfb->ddc_adapter, cfb);
1205
1206	return i2c_bit_add_bus(&cfb->ddc_adapter);
1207}
1208#endif /* CONFIG_FB_CYBER2000_DDC */
1209
1210#ifdef CONFIG_FB_CYBER2000_I2C
1211static void cyber2000fb_i2c_setsda(void *data, int state)
1212{
1213	struct cfb_info *cfb = data;
1214	unsigned int latch2;
1215
1216	spin_lock(&cfb->reg_b0_lock);
1217	latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1218	latch2 &= EXT_LATCH2_I2C_CLKEN;
1219	if (state)
1220		latch2 |= EXT_LATCH2_I2C_DATEN;
1221	cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1222	spin_unlock(&cfb->reg_b0_lock);
1223}
1224
1225static void cyber2000fb_i2c_setscl(void *data, int state)
1226{
1227	struct cfb_info *cfb = data;
1228	unsigned int latch2;
1229
1230	spin_lock(&cfb->reg_b0_lock);
1231	latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1232	latch2 &= EXT_LATCH2_I2C_DATEN;
1233	if (state)
1234		latch2 |= EXT_LATCH2_I2C_CLKEN;
1235	cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1236	spin_unlock(&cfb->reg_b0_lock);
1237}
1238
1239static int cyber2000fb_i2c_getsda(void *data)
1240{
1241	struct cfb_info *cfb = data;
1242	int ret;
1243
1244	spin_lock(&cfb->reg_b0_lock);
1245	ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT);
1246	spin_unlock(&cfb->reg_b0_lock);
1247
1248	return ret;
1249}
1250
1251static int cyber2000fb_i2c_getscl(void *data)
1252{
1253	struct cfb_info *cfb = data;
1254	int ret;
1255
1256	spin_lock(&cfb->reg_b0_lock);
1257	ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK);
1258	spin_unlock(&cfb->reg_b0_lock);
1259
1260	return ret;
1261}
1262
1263static int cyber2000fb_i2c_register(struct cfb_info *cfb)
1264{
1265	strscpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
1266		sizeof(cfb->i2c_adapter.name));
1267	cfb->i2c_adapter.owner = THIS_MODULE;
1268	cfb->i2c_adapter.algo_data = &cfb->i2c_algo;
1269	cfb->i2c_adapter.dev.parent = cfb->fb.device;
1270	cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda;
1271	cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl;
1272	cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda;
1273	cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl;
1274	cfb->i2c_algo.udelay = 5;
1275	cfb->i2c_algo.timeout = msecs_to_jiffies(100);
1276	cfb->i2c_algo.data = cfb;
1277
1278	return i2c_bit_add_bus(&cfb->i2c_adapter);
1279}
1280
1281static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
1282{
1283	i2c_del_adapter(&cfb->i2c_adapter);
1284}
1285#else
1286#define cyber2000fb_i2c_register(cfb)	(0)
1287#define cyber2000fb_i2c_unregister(cfb)	do { } while (0)
1288#endif
1289
1290/*
1291 * These parameters give
1292 * 640x480, hsync 31.5kHz, vsync 60Hz
1293 */
1294static const struct fb_videomode cyber2000fb_default_mode = {
1295	.refresh	= 60,
1296	.xres		= 640,
1297	.yres		= 480,
1298	.pixclock	= 39722,
1299	.left_margin	= 56,
1300	.right_margin	= 16,
1301	.upper_margin	= 34,
1302	.lower_margin	= 9,
1303	.hsync_len	= 88,
1304	.vsync_len	= 2,
1305	.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
1306	.vmode		= FB_VMODE_NONINTERLACED
1307};
1308
1309static char igs_regs[] = {
1310	EXT_CRT_IRQ,		0,
1311	EXT_CRT_TEST,		0,
1312	EXT_SYNC_CTL,		0,
1313	EXT_SEG_WRITE_PTR,	0,
1314	EXT_SEG_READ_PTR,	0,
1315	EXT_BIU_MISC,		EXT_BIU_MISC_LIN_ENABLE |
1316				EXT_BIU_MISC_COP_ENABLE |
1317				EXT_BIU_MISC_COP_BFC,
1318	EXT_FUNC_CTL,		0,
1319	CURS_H_START,		0,
1320	CURS_H_START + 1,	0,
1321	CURS_H_PRESET,		0,
1322	CURS_V_START,		0,
1323	CURS_V_START + 1,	0,
1324	CURS_V_PRESET,		0,
1325	CURS_CTL,		0,
1326	EXT_ATTRIB_CTL,		EXT_ATTRIB_CTL_EXT,
1327	EXT_OVERSCAN_RED,	0,
1328	EXT_OVERSCAN_GREEN,	0,
1329	EXT_OVERSCAN_BLUE,	0,
1330
1331	/* some of these are questionable when we have a BIOS */
1332	EXT_MEM_CTL0,		EXT_MEM_CTL0_7CLK |
1333				EXT_MEM_CTL0_RAS_1 |
1334				EXT_MEM_CTL0_MULTCAS,
1335	EXT_HIDDEN_CTL1,	0x30,
1336	EXT_FIFO_CTL,		0x0b,
1337	EXT_FIFO_CTL + 1,	0x17,
1338	0x76,			0x00,
1339	EXT_HIDDEN_CTL4,	0xc8
1340};
1341
1342/*
1343 * Initialise the CyberPro hardware.  On the CyberPro5XXXX,
1344 * ensure that we're using the correct PLL (5XXX's may be
1345 * programmed to use an additional set of PLLs.)
1346 */
1347static void cyberpro_init_hw(struct cfb_info *cfb)
1348{
1349	int i;
1350
1351	for (i = 0; i < sizeof(igs_regs); i += 2)
1352		cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
1353
1354	if (cfb->id == ID_CYBERPRO_5000) {
1355		unsigned char val;
1356		cyber2000fb_writeb(0xba, 0x3ce, cfb);
1357		val = cyber2000fb_readb(0x3cf, cfb) & 0x80;
1358		cyber2000fb_writeb(val, 0x3cf, cfb);
1359	}
1360}
1361
1362static struct cfb_info *cyberpro_alloc_fb_info(unsigned int id, char *name)
1363{
1364	struct cfb_info *cfb;
1365
1366	cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL);
1367	if (!cfb)
1368		return NULL;
1369
1370
1371	cfb->id			= id;
1372
1373	if (id == ID_CYBERPRO_5000)
1374		cfb->ref_ps	= 40690; /* 24.576 MHz */
1375	else
1376		cfb->ref_ps	= 69842; /* 14.31818 MHz (69841?) */
1377
1378	cfb->divisors[0]	= 1;
1379	cfb->divisors[1]	= 2;
1380	cfb->divisors[2]	= 4;
1381
1382	if (id == ID_CYBERPRO_2000)
1383		cfb->divisors[3] = 8;
1384	else
1385		cfb->divisors[3] = 6;
1386
1387	strcpy(cfb->fb.fix.id, name);
1388
1389	cfb->fb.fix.type	= FB_TYPE_PACKED_PIXELS;
1390	cfb->fb.fix.type_aux	= 0;
1391	cfb->fb.fix.xpanstep	= 0;
1392	cfb->fb.fix.ypanstep	= 1;
1393	cfb->fb.fix.ywrapstep	= 0;
1394
1395	switch (id) {
1396	case ID_IGA_1682:
1397		cfb->fb.fix.accel = 0;
1398		break;
1399
1400	case ID_CYBERPRO_2000:
1401		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;
1402		break;
1403
1404	case ID_CYBERPRO_2010:
1405		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;
1406		break;
1407
1408	case ID_CYBERPRO_5000:
1409		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;
1410		break;
1411	}
1412
1413	cfb->fb.var.nonstd	= 0;
1414	cfb->fb.var.activate	= FB_ACTIVATE_NOW;
1415	cfb->fb.var.height	= -1;
1416	cfb->fb.var.width	= -1;
1417	cfb->fb.var.accel_flags	= FB_ACCELF_TEXT;
1418
1419	cfb->fb.fbops		= &cyber2000fb_ops;
1420	cfb->fb.flags		= FBINFO_HWACCEL_YPAN;
1421	cfb->fb.pseudo_palette	= cfb->pseudo_palette;
1422
1423	spin_lock_init(&cfb->reg_b0_lock);
1424
1425	fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
1426
1427	return cfb;
1428}
1429
1430static void cyberpro_free_fb_info(struct cfb_info *cfb)
1431{
1432	if (cfb) {
1433		/*
1434		 * Free the colourmap
1435		 */
1436		fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
1437
1438		kfree(cfb);
1439	}
1440}
1441
1442/*
1443 * Parse Cyber2000fb options.  Usage:
1444 *  video=cyber2000:font:fontname
1445 */
1446#ifndef MODULE
1447static int cyber2000fb_setup(char *options)
1448{
1449	char *opt;
1450
1451	if (!options || !*options)
1452		return 0;
1453
1454	while ((opt = strsep(&options, ",")) != NULL) {
1455		if (!*opt)
1456			continue;
1457
1458		if (strncmp(opt, "font:", 5) == 0) {
1459			static char default_font_storage[40];
1460
1461			strscpy(default_font_storage, opt + 5,
1462				sizeof(default_font_storage));
1463			default_font = default_font_storage;
1464			continue;
1465		}
1466
1467		printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
1468	}
1469	return 0;
1470}
1471#endif  /*  MODULE  */
1472
1473/*
1474 * The CyberPro chips can be placed on many different bus types.
1475 * This probe function is common to all bus types.  The bus-specific
1476 * probe function is expected to have:
1477 *  - enabled access to the linear memory region
1478 *  - memory mapped access to the registers
1479 *  - initialised mem_ctl1 and mem_ctl2 appropriately.
1480 */
1481static int cyberpro_common_probe(struct cfb_info *cfb)
1482{
1483	u_long smem_size;
1484	u_int h_sync, v_sync;
1485	int err;
1486
1487	cyberpro_init_hw(cfb);
1488
1489	/*
1490	 * Get the video RAM size and width from the VGA register.
1491	 * This should have been already initialised by the BIOS,
1492	 * but if it's garbage, claim default 1MB VRAM (woody)
1493	 */
1494	cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb);
1495	cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb);
1496
1497	/*
1498	 * Determine the size of the memory.
1499	 */
1500	switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
1501	case MEM_CTL2_SIZE_4MB:
1502		smem_size = 0x00400000;
1503		break;
1504	case MEM_CTL2_SIZE_2MB:
1505		smem_size = 0x00200000;
1506		break;
1507	case MEM_CTL2_SIZE_1MB:
1508		smem_size = 0x00100000;
1509		break;
1510	default:
1511		smem_size = 0x00100000;
1512		break;
1513	}
1514
1515	cfb->fb.fix.smem_len   = smem_size;
1516	cfb->fb.fix.mmio_len   = MMIO_SIZE;
1517	cfb->fb.screen_base    = cfb->region;
1518
1519#ifdef CONFIG_FB_CYBER2000_DDC
1520	if (cyber2000fb_setup_ddc_bus(cfb) == 0)
1521		cfb->ddc_registered = true;
1522#endif
1523
1524	err = -EINVAL;
1525	if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
1526			  &cyber2000fb_default_mode, 8)) {
1527		printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
1528		goto failed;
1529	}
1530
1531	cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /
1532			(cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);
1533
1534	if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
1535		cfb->fb.var.yres_virtual = cfb->fb.var.yres;
1536
1537/*	fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
1538
1539	/*
1540	 * Calculate the hsync and vsync frequencies.  Note that
1541	 * we split the 1e12 constant up so that we can preserve
1542	 * the precision and fit the results into 32-bit registers.
1543	 *  (1953125000 * 512 = 1e12)
1544	 */
1545	h_sync = 1953125000 / cfb->fb.var.pixclock;
1546	h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +
1547		 cfb->fb.var.right_margin + cfb->fb.var.hsync_len);
1548	v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
1549		 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
1550
1551	printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
1552		cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
1553		cfb->fb.var.xres, cfb->fb.var.yres,
1554		h_sync / 1000, h_sync % 1000, v_sync);
1555
1556	err = cyber2000fb_i2c_register(cfb);
1557	if (err)
1558		goto failed;
1559
1560	err = register_framebuffer(&cfb->fb);
1561	if (err)
1562		cyber2000fb_i2c_unregister(cfb);
1563
1564failed:
1565#ifdef CONFIG_FB_CYBER2000_DDC
1566	if (err && cfb->ddc_registered)
1567		i2c_del_adapter(&cfb->ddc_adapter);
1568#endif
1569	return err;
1570}
1571
1572static void cyberpro_common_remove(struct cfb_info *cfb)
1573{
1574	unregister_framebuffer(&cfb->fb);
1575#ifdef CONFIG_FB_CYBER2000_DDC
1576	if (cfb->ddc_registered)
1577		i2c_del_adapter(&cfb->ddc_adapter);
1578#endif
1579	cyber2000fb_i2c_unregister(cfb);
1580}
1581
1582static void cyberpro_common_resume(struct cfb_info *cfb)
1583{
1584	cyberpro_init_hw(cfb);
1585
1586	/*
1587	 * Reprogram the MEM_CTL1 and MEM_CTL2 registers
1588	 */
1589	cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb);
1590	cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb);
1591
1592	/*
1593	 * Restore the old video mode and the palette.
1594	 * We also need to tell fbcon to redraw the console.
1595	 */
1596	cyber2000fb_set_par(&cfb->fb);
1597}
1598
1599/*
1600 * We need to wake up the CyberPro, and make sure its in linear memory
1601 * mode.  Unfortunately, this is specific to the platform and card that
1602 * we are running on.
1603 *
1604 * On x86 and ARM, should we be initialising the CyberPro first via the
1605 * IO registers, and then the MMIO registers to catch all cases?  Can we
1606 * end up in the situation where the chip is in MMIO mode, but not awake
1607 * on an x86 system?
1608 */
1609static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
1610{
1611	unsigned char val;
1612
1613#if defined(__sparc_v9__)
1614#error "You lose, consult DaveM."
1615#elif defined(__sparc__)
1616	/*
1617	 * SPARC does not have an "outb" instruction, so we generate
1618	 * I/O cycles storing into a reserved memory space at
1619	 * physical address 0x3000000
1620	 */
1621	unsigned char __iomem *iop;
1622
1623	iop = ioremap(0x3000000, 0x5000);
1624	if (iop == NULL) {
1625		printk(KERN_ERR "iga5000: cannot map I/O\n");
1626		return -ENOMEM;
1627	}
1628
1629	writeb(0x18, iop + 0x46e8);
1630	writeb(0x01, iop + 0x102);
1631	writeb(0x08, iop + 0x46e8);
1632	writeb(EXT_BIU_MISC, iop + 0x3ce);
1633	writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
1634
1635	iounmap(iop);
1636#else
1637	/*
1638	 * Most other machine types are "normal", so
1639	 * we use the standard IO-based wakeup.
1640	 */
1641	outb(0x18, 0x46e8);
1642	outb(0x01, 0x102);
1643	outb(0x08, 0x46e8);
1644	outb(EXT_BIU_MISC, 0x3ce);
1645	outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf);
1646#endif
1647
1648	/*
1649	 * Allow the CyberPro to accept PCI burst accesses
1650	 */
1651	if (cfb->id == ID_CYBERPRO_2010) {
1652		printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
1653		       cfb->fb.fix.id);
1654	} else {
1655		val = cyber2000_grphr(EXT_BUS_CTL, cfb);
1656		if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
1657			printk(KERN_INFO "%s: enabling PCI bursts\n",
1658				cfb->fb.fix.id);
1659
1660			val |= EXT_BUS_CTL_PCIBURST_WRITE;
1661
1662			if (cfb->id == ID_CYBERPRO_5000)
1663				val |= EXT_BUS_CTL_PCIBURST_READ;
1664
1665			cyber2000_grphw(EXT_BUS_CTL, val, cfb);
1666		}
1667	}
1668
1669	return 0;
1670}
1671
1672static int cyberpro_pci_probe(struct pci_dev *dev,
1673			      const struct pci_device_id *id)
1674{
1675	struct cfb_info *cfb;
1676	char name[16];
1677	int err;
1678
1679	sprintf(name, "CyberPro%4X", id->device);
1680
1681	err = aperture_remove_conflicting_pci_devices(dev, name);
1682	if (err)
1683		return err;
1684
1685	err = pci_enable_device(dev);
1686	if (err)
1687		return err;
1688
1689	err = -ENOMEM;
1690	cfb = cyberpro_alloc_fb_info(id->driver_data, name);
1691	if (!cfb)
1692		goto failed_release;
1693
1694	err = pci_request_regions(dev, cfb->fb.fix.id);
1695	if (err)
1696		goto failed_regions;
1697
1698	cfb->irq = dev->irq;
1699	cfb->region = pci_ioremap_bar(dev, 0);
1700	if (!cfb->region) {
1701		err = -ENOMEM;
1702		goto failed_ioremap;
1703	}
1704
1705	cfb->regs = cfb->region + MMIO_OFFSET;
1706	cfb->fb.device = &dev->dev;
1707	cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
1708	cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
1709
1710	/*
1711	 * Bring up the hardware.  This is expected to enable access
1712	 * to the linear memory region, and allow access to the memory
1713	 * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be
1714	 * initialised.
1715	 */
1716	err = cyberpro_pci_enable_mmio(cfb);
1717	if (err)
1718		goto failed;
1719
1720	/*
1721	 * Use MCLK from BIOS. FIXME: what about hotplug?
1722	 */
1723	cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);
1724	cfb->mclk_div  = cyber2000_grphr(EXT_MCLK_DIV, cfb);
1725
1726#ifdef __arm__
1727	/*
1728	 * MCLK on the NetWinder and the Shark is fixed at 75MHz
1729	 */
1730	if (machine_is_netwinder()) {
1731		cfb->mclk_mult = 0xdb;
1732		cfb->mclk_div  = 0x54;
1733	}
1734#endif
1735
1736	err = cyberpro_common_probe(cfb);
1737	if (err)
1738		goto failed;
1739
1740	/*
1741	 * Our driver data
1742	 */
1743	pci_set_drvdata(dev, cfb);
1744	if (int_cfb_info == NULL)
1745		int_cfb_info = cfb;
1746
1747	return 0;
1748
1749failed:
1750	iounmap(cfb->region);
1751failed_ioremap:
1752	pci_release_regions(dev);
1753failed_regions:
1754	cyberpro_free_fb_info(cfb);
1755failed_release:
1756	pci_disable_device(dev);
1757	return err;
1758}
1759
1760static void cyberpro_pci_remove(struct pci_dev *dev)
1761{
1762	struct cfb_info *cfb = pci_get_drvdata(dev);
1763
1764	if (cfb) {
1765		cyberpro_common_remove(cfb);
1766		iounmap(cfb->region);
1767		cyberpro_free_fb_info(cfb);
1768
1769		if (cfb == int_cfb_info)
1770			int_cfb_info = NULL;
1771
1772		pci_release_regions(dev);
1773		pci_disable_device(dev);
1774	}
1775}
1776
1777static int __maybe_unused cyberpro_pci_suspend(struct device *dev)
1778{
1779	return 0;
1780}
1781
1782/*
1783 * Re-initialise the CyberPro hardware
1784 */
1785static int __maybe_unused cyberpro_pci_resume(struct device *dev)
1786{
1787	struct cfb_info *cfb = dev_get_drvdata(dev);
1788
1789	if (cfb) {
1790		cyberpro_pci_enable_mmio(cfb);
1791		cyberpro_common_resume(cfb);
1792	}
1793
1794	return 0;
1795}
1796
1797static struct pci_device_id cyberpro_pci_table[] = {
1798/*	Not yet
1799 *	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
1800 *		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
1801 */
1802	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
1803		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
1804	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
1805		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },
1806	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
1807		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },
1808	{ 0, }
1809};
1810
1811MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
1812
1813static SIMPLE_DEV_PM_OPS(cyberpro_pci_pm_ops,
1814			 cyberpro_pci_suspend,
1815			 cyberpro_pci_resume);
1816
1817static struct pci_driver cyberpro_driver = {
1818	.name		= "CyberPro",
1819	.probe		= cyberpro_pci_probe,
1820	.remove		= cyberpro_pci_remove,
1821	.driver.pm	= &cyberpro_pci_pm_ops,
1822	.id_table	= cyberpro_pci_table
1823};
1824
1825/*
1826 * I don't think we can use the "module_init" stuff here because
1827 * the fbcon stuff may not be initialised yet.  Hence the #ifdef
1828 * around module_init.
1829 *
1830 * Tony: "module_init" is now required
1831 */
1832static int __init cyber2000fb_init(void)
1833{
1834	int ret = -1, err;
1835
1836#ifndef MODULE
1837	char *option = NULL;
1838#endif
1839
1840	if (fb_modesetting_disabled("CyberPro"))
1841		return -ENODEV;
1842
1843#ifndef MODULE
1844	if (fb_get_options("cyber2000fb", &option))
1845		return -ENODEV;
1846	cyber2000fb_setup(option);
1847#endif
1848
1849	err = pci_register_driver(&cyberpro_driver);
1850	if (!err)
1851		ret = 0;
1852
1853	return ret ? err : 0;
1854}
1855module_init(cyber2000fb_init);
1856
1857static void __exit cyberpro_exit(void)
1858{
1859	pci_unregister_driver(&cyberpro_driver);
1860}
1861module_exit(cyberpro_exit);
1862
1863MODULE_AUTHOR("Russell King");
1864MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
1865MODULE_LICENSE("GPL");
~/ Read-only file preview.