blacklight: remove redundant spi driver bus initialization
[deliverable/linux.git] / drivers / video / cirrusfb.c
CommitLineData
1da177e4
LT
1/*
2 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
3 *
4 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
5 *
6 * Contributors (thanks, all!)
7 *
8 * David Eger:
9 * Overhaul for Linux 2.6
10 *
11 * Jeff Rugen:
12 * Major contributions; Motorola PowerStack (PPC and PCI) support,
13 * GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
14 *
15 * Geert Uytterhoeven:
16 * Excellent code review.
17 *
18 * Lars Hecking:
19 * Amiga updates and testing.
20 *
21 * Original cirrusfb author: Frank Neumann
22 *
23 * Based on retz3fb.c and cirrusfb.c:
24 * Copyright (C) 1997 Jes Sorensen
25 * Copyright (C) 1996 Frank Neumann
26 *
27 ***************************************************************
28 *
29 * Format this code with GNU indent '-kr -i8 -pcs' options.
30 *
31 * This file is subject to the terms and conditions of the GNU General Public
32 * License. See the file COPYING in the main directory of this archive
33 * for more details.
34 *
35 */
36
1da177e4
LT
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>
1da177e4
LT
42#include <linux/delay.h>
43#include <linux/fb.h>
44#include <linux/init.h>
1da177e4
LT
45#include <asm/pgtable.h>
46
47#ifdef CONFIG_ZORRO
48#include <linux/zorro.h>
49#endif
50#ifdef CONFIG_PCI
51#include <linux/pci.h>
52#endif
53#ifdef CONFIG_AMIGA
54#include <asm/amigahw.h>
55#endif
56#ifdef CONFIG_PPC_PREP
e8222502 57#include <asm/machdep.h>
8503df65 58#define isPReP machine_is(prep)
1da177e4
LT
59#else
60#define isPReP 0
61#endif
62
0ff1edee
KH
63#include <video/vga.h>
64#include <video/cirrus.h>
1da177e4 65
1da177e4
LT
66/*****************************************************************
67 *
68 * debugging and utility macros
69 *
70 */
71
1da177e4
LT
72/* disable runtime assertions? */
73/* #define CIRRUSFB_NDEBUG */
74
1da177e4
LT
75/* debugging assertions */
76#ifndef CIRRUSFB_NDEBUG
77#define assert(expr) \
8503df65
KH
78 if (!(expr)) { \
79 printk("Assertion failed! %s,%s,%s,line=%d\n", \
5ae12170 80 #expr, __FILE__, __func__, __LINE__); \
8503df65 81 }
1da177e4
LT
82#else
83#define assert(expr)
84#endif
85
8503df65 86#define MB_ (1024 * 1024)
1da177e4 87
1da177e4
LT
88/*****************************************************************
89 *
90 * chipset information
91 *
92 */
93
94/* board types */
7345de32 95enum cirrus_board {
1da177e4 96 BT_NONE = 0,
7cade31c
KH
97 BT_SD64, /* GD5434 */
98 BT_PICCOLO, /* GD5426 */
99 BT_PICASSO, /* GD5426 or GD5428 */
100 BT_SPECTRUM, /* GD5426 or GD5428 */
1da177e4
LT
101 BT_PICASSO4, /* GD5446 */
102 BT_ALPINE, /* GD543x/4x */
103 BT_GD5480,
78d780e0
KH
104 BT_LAGUNA, /* GD5462/64 */
105 BT_LAGUNAB, /* GD5465 */
7345de32 106};
1da177e4 107
1da177e4
LT
108/*
109 * per-board-type information, used for enumerating and abstracting
110 * chip-specific information
7345de32 111 * NOTE: MUST be in the same order as enum cirrus_board in order to
1da177e4
LT
112 * use direct indexing on this array
113 * NOTE: '__initdata' cannot be used as some of this info
114 * is required at runtime. Maybe separate into an init-only and
115 * a run-time table?
116 */
117static const struct cirrusfb_board_info_rec {
118 char *name; /* ASCII name of chipset */
119 long maxclock[5]; /* maximum video clock */
120 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
c930faae
RK
121 bool init_sr07 : 1; /* init SR07 during init_vgachip() */
122 bool init_sr1f : 1; /* write SR1F during init_vgachip() */
8503df65
KH
123 /* construct bit 19 of screen start address */
124 bool scrn_start_bit19 : 1;
1da177e4
LT
125
126 /* initial SR07 value, then for each mode */
127 unsigned char sr07;
128 unsigned char sr07_1bpp;
129 unsigned char sr07_1bpp_mux;
130 unsigned char sr07_8bpp;
131 unsigned char sr07_8bpp_mux;
132
133 unsigned char sr1f; /* SR1F VGA initial register value */
134} cirrusfb_board_info[] = {
135 [BT_SD64] = {
136 .name = "CL SD64",
137 .maxclock = {
138 /* guess */
139 /* the SD64/P4 have a higher max. videoclock */
75ed3a17 140 135100, 135100, 85500, 85500, 0
1da177e4 141 },
c930faae
RK
142 .init_sr07 = true,
143 .init_sr1f = true,
144 .scrn_start_bit19 = true,
1da177e4
LT
145 .sr07 = 0xF0,
146 .sr07_1bpp = 0xF0,
df3aafd5 147 .sr07_1bpp_mux = 0xF6,
1da177e4 148 .sr07_8bpp = 0xF1,
df3aafd5 149 .sr07_8bpp_mux = 0xF7,
8f19e15b 150 .sr1f = 0x1E
1da177e4
LT
151 },
152 [BT_PICCOLO] = {
153 .name = "CL Piccolo",
154 .maxclock = {
155 /* guess */
156 90000, 90000, 90000, 90000, 90000
157 },
c930faae
RK
158 .init_sr07 = true,
159 .init_sr1f = true,
160 .scrn_start_bit19 = false,
1da177e4
LT
161 .sr07 = 0x80,
162 .sr07_1bpp = 0x80,
163 .sr07_8bpp = 0x81,
164 .sr1f = 0x22
165 },
166 [BT_PICASSO] = {
167 .name = "CL Picasso",
168 .maxclock = {
169 /* guess */
170 90000, 90000, 90000, 90000, 90000
171 },
c930faae
RK
172 .init_sr07 = true,
173 .init_sr1f = true,
174 .scrn_start_bit19 = false,
1da177e4
LT
175 .sr07 = 0x20,
176 .sr07_1bpp = 0x20,
177 .sr07_8bpp = 0x21,
178 .sr1f = 0x22
179 },
180 [BT_SPECTRUM] = {
181 .name = "CL Spectrum",
182 .maxclock = {
183 /* guess */
184 90000, 90000, 90000, 90000, 90000
185 },
c930faae
RK
186 .init_sr07 = true,
187 .init_sr1f = true,
188 .scrn_start_bit19 = false,
1da177e4
LT
189 .sr07 = 0x80,
190 .sr07_1bpp = 0x80,
191 .sr07_8bpp = 0x81,
192 .sr1f = 0x22
193 },
194 [BT_PICASSO4] = {
195 .name = "CL Picasso4",
196 .maxclock = {
197 135100, 135100, 85500, 85500, 0
198 },
c930faae
RK
199 .init_sr07 = true,
200 .init_sr1f = false,
201 .scrn_start_bit19 = true,
527410ff
KH
202 .sr07 = 0xA0,
203 .sr07_1bpp = 0xA0,
204 .sr07_1bpp_mux = 0xA6,
205 .sr07_8bpp = 0xA1,
206 .sr07_8bpp_mux = 0xA7,
1da177e4
LT
207 .sr1f = 0
208 },
209 [BT_ALPINE] = {
210 .name = "CL Alpine",
211 .maxclock = {
212 /* for the GD5430. GD5446 can do more... */
213 85500, 85500, 50000, 28500, 0
214 },
c930faae
RK
215 .init_sr07 = true,
216 .init_sr1f = true,
217 .scrn_start_bit19 = true,
1da177e4 218 .sr07 = 0xA0,
527410ff
KH
219 .sr07_1bpp = 0xA0,
220 .sr07_1bpp_mux = 0xA6,
1da177e4
LT
221 .sr07_8bpp = 0xA1,
222 .sr07_8bpp_mux = 0xA7,
223 .sr1f = 0x1C
224 },
225 [BT_GD5480] = {
226 .name = "CL GD5480",
227 .maxclock = {
228 135100, 200000, 200000, 135100, 135100
229 },
c930faae
RK
230 .init_sr07 = true,
231 .init_sr1f = true,
232 .scrn_start_bit19 = true,
1da177e4
LT
233 .sr07 = 0x10,
234 .sr07_1bpp = 0x11,
235 .sr07_8bpp = 0x11,
236 .sr1f = 0x1C
237 },
238 [BT_LAGUNA] = {
239 .name = "CL Laguna",
240 .maxclock = {
78d780e0
KH
241 /* taken from X11 code */
242 170000, 170000, 170000, 170000, 135100,
243 },
244 .init_sr07 = false,
245 .init_sr1f = false,
246 .scrn_start_bit19 = true,
247 },
248 [BT_LAGUNAB] = {
249 .name = "CL Laguna AGP",
250 .maxclock = {
251 /* taken from X11 code */
252 170000, 250000, 170000, 170000, 135100,
1da177e4 253 },
c930faae
RK
254 .init_sr07 = false,
255 .init_sr1f = false,
256 .scrn_start_bit19 = true,
1da177e4
LT
257 }
258};
259
1da177e4
LT
260#ifdef CONFIG_PCI
261#define CHIP(id, btype) \
4153812f 262 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
1da177e4
LT
263
264static struct pci_device_id cirrusfb_pci_table[] = {
8503df65 265 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
df3aafd5
KH
266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
267 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
8503df65
KH
268 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
269 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
270 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
271 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
272 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
273 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
274 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
78d780e0 275 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
1da177e4
LT
276 { 0, }
277};
278MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
279#undef CHIP
280#endif /* CONFIG_PCI */
281
1da177e4 282#ifdef CONFIG_ZORRO
0e0d1336
GU
283struct zorrocl {
284 enum cirrus_board type; /* Board type */
285 u32 regoffset; /* Offset of registers in first Zorro device */
286 u32 ramsize; /* Size of video RAM in first Zorro device */
287 /* If zero, use autoprobe on RAM device */
288 u32 ramoffset; /* Offset of video RAM in first Zorro device */
289 zorro_id ramid; /* Zorro ID of RAM device */
17bdf489 290 zorro_id ramid2; /* Zorro ID of optional second RAM device */
0e0d1336
GU
291};
292
293static const struct zorrocl zcl_sd64 __devinitconst = {
294 .type = BT_SD64,
295 .ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
296};
297
298static const struct zorrocl zcl_piccolo __devinitconst = {
299 .type = BT_PICCOLO,
300 .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
301};
302
303static const struct zorrocl zcl_picasso __devinitconst = {
304 .type = BT_PICASSO,
305 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
306};
307
308static const struct zorrocl zcl_spectrum __devinitconst = {
309 .type = BT_SPECTRUM,
310 .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
311};
312
313static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
314 .type = BT_PICASSO4,
315 .regoffset = 0x00600000,
316 .ramsize = 4 * MB_,
e78bb882 317 .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */
0e0d1336
GU
318};
319
17bdf489
GU
320static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
321 .type = BT_PICASSO4,
322 .regoffset = 0x10000,
323 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
324 .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
325};
326
0e0d1336
GU
327
328static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
1da177e4 329 {
0e0d1336
GU
330 .id = ZORRO_PROD_HELFRICH_SD64_REG,
331 .driver_data = (unsigned long)&zcl_sd64,
1da177e4 332 }, {
0e0d1336
GU
333 .id = ZORRO_PROD_HELFRICH_PICCOLO_REG,
334 .driver_data = (unsigned long)&zcl_piccolo,
1da177e4 335 }, {
0e0d1336
GU
336 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
337 .driver_data = (unsigned long)&zcl_picasso,
1da177e4 338 }, {
0e0d1336
GU
339 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
340 .driver_data = (unsigned long)&zcl_spectrum,
1da177e4
LT
341 }, {
342 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
0e0d1336 343 .driver_data = (unsigned long)&zcl_picasso4_z3,
17bdf489
GU
344 }, {
345 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
346 .driver_data = (unsigned long)&zcl_picasso4_z2,
1da177e4
LT
347 },
348 { 0 }
349};
bf54a2b3 350MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
1da177e4
LT
351#endif /* CONFIG_ZORRO */
352
1da177e4 353#ifdef CIRRUSFB_DEBUG
7345de32 354enum cirrusfb_dbg_reg_class {
8503df65
KH
355 CRT,
356 SEQ
7345de32 357};
8503df65 358#endif /* CIRRUSFB_DEBUG */
1da177e4
LT
359
360/* info about board */
361struct cirrusfb_info {
1da177e4 362 u8 __iomem *regbase;
6e30fc08 363 u8 __iomem *laguna_mmio;
7345de32 364 enum cirrus_board btype;
1da177e4
LT
365 unsigned char SFR; /* Shadow of special function register */
366
48c329e9 367 int multiplexing;
df3aafd5 368 int doubleVCLK;
1da177e4 369 int blank_mode;
64beab14 370 u32 pseudo_palette[16];
1da177e4 371
9199ec5c 372 void (*unmap)(struct fb_info *info);
1da177e4
LT
373};
374
90ab5ee9 375static bool noaccel __devinitdata;
a1d35a7a 376static char *mode_option __devinitdata = "640x480@60";
1da177e4
LT
377
378/****************************************************************************/
379/**** BEGIN PROTOTYPES ******************************************************/
380
1da177e4 381/*--- Interface used by the world ------------------------------------------*/
8503df65
KH
382static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
383 struct fb_info *info);
1da177e4 384
1da177e4 385/*--- Internal routines ----------------------------------------------------*/
9199ec5c 386static void init_vgachip(struct fb_info *info);
8503df65
KH
387static void switch_monitor(struct cirrusfb_info *cinfo, int on);
388static void WGen(const struct cirrusfb_info *cinfo,
389 int regnum, unsigned char val);
390static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
391static void AttrOn(const struct cirrusfb_info *cinfo);
392static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
393static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
394static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
395static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
396 unsigned char red, unsigned char green, unsigned char blue);
1da177e4 397#if 0
8503df65
KH
398static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
399 unsigned char *red, unsigned char *green,
400 unsigned char *blue);
1da177e4 401#endif
8503df65
KH
402static void cirrusfb_WaitBLT(u8 __iomem *regbase);
403static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
404 u_short curx, u_short cury,
405 u_short destx, u_short desty,
406 u_short width, u_short height,
407 u_short line_length);
408static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
409 u_short x, u_short y,
410 u_short width, u_short height,
9e848062
KH
411 u32 fg_color, u32 bg_color,
412 u_short line_length, u_char blitmode);
8503df65 413
dafa32c5 414static void bestclock(long freq, int *nom, int *den, int *div);
1da177e4
LT
415
416#ifdef CIRRUSFB_DEBUG
75ed3a17
KH
417static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
418static void cirrusfb_dbg_print_regs(struct fb_info *info,
419 caddr_t regbase,
7345de32 420 enum cirrusfb_dbg_reg_class reg_class, ...);
1da177e4
LT
421#endif /* CIRRUSFB_DEBUG */
422
423/*** END PROTOTYPES ********************************************************/
424/*****************************************************************************/
425/*** BEGIN Interface Used by the World ***************************************/
426
78d780e0
KH
427static inline int is_laguna(const struct cirrusfb_info *cinfo)
428{
429 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
430}
431
8503df65 432static int opencount;
1da177e4
LT
433
434/*--- Open /dev/fbx ---------------------------------------------------------*/
8503df65 435static int cirrusfb_open(struct fb_info *info, int user)
1da177e4
LT
436{
437 if (opencount++ == 0)
8503df65 438 switch_monitor(info->par, 1);
1da177e4
LT
439 return 0;
440}
441
442/*--- Close /dev/fbx --------------------------------------------------------*/
8503df65 443static int cirrusfb_release(struct fb_info *info, int user)
1da177e4
LT
444{
445 if (--opencount == 0)
8503df65 446 switch_monitor(info->par, 0);
1da177e4
LT
447 return 0;
448}
449
450/**** END Interface used by the World *************************************/
451/****************************************************************************/
452/**** BEGIN Hardware specific Routines **************************************/
453
486ff387 454/* Check if the MCLK is not a better clock source */
75ed3a17 455static int cirrusfb_check_mclk(struct fb_info *info, long freq)
1da177e4 456{
75ed3a17 457 struct cirrusfb_info *cinfo = info->par;
486ff387 458 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
1da177e4 459
486ff387
KH
460 /* Read MCLK value */
461 mclk = (14318 * mclk) >> 3;
75ed3a17 462 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
1da177e4
LT
463
464 /* Determine if we should use MCLK instead of VCLK, and if so, what we
486ff387
KH
465 * should divide it by to get VCLK
466 */
467
468 if (abs(freq - mclk) < 250) {
75ed3a17 469 dev_dbg(info->device, "Using VCLK = MCLK\n");
486ff387
KH
470 return 1;
471 } else if (abs(freq - (mclk / 2)) < 250) {
75ed3a17 472 dev_dbg(info->device, "Using VCLK = MCLK/2\n");
486ff387 473 return 2;
1da177e4
LT
474 }
475
486ff387 476 return 0;
1da177e4
LT
477}
478
99a45847
KH
479static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
480 struct fb_info *info)
481{
482 long freq;
483 long maxclock;
484 struct cirrusfb_info *cinfo = info->par;
485 unsigned maxclockidx = var->bits_per_pixel >> 3;
486
487 /* convert from ps to kHz */
488 freq = PICOS2KHZ(var->pixclock);
489
490 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
491
492 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
493 cinfo->multiplexing = 0;
494
495 /* If the frequency is greater than we can support, we might be able
496 * to use multiplexing for the video mode */
497 if (freq > maxclock) {
dd14f71c
KH
498 dev_err(info->device,
499 "Frequency greater than maxclock (%ld kHz)\n",
500 maxclock);
501 return -EINVAL;
502 }
503 /*
504 * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
505 * pixel clock
506 */
507 if (var->bits_per_pixel == 8) {
99a45847
KH
508 switch (cinfo->btype) {
509 case BT_ALPINE:
8f19e15b 510 case BT_SD64:
dd14f71c
KH
511 case BT_PICASSO4:
512 if (freq > 85500)
513 cinfo->multiplexing = 1;
514 break;
99a45847 515 case BT_GD5480:
dd14f71c
KH
516 if (freq > 135100)
517 cinfo->multiplexing = 1;
99a45847
KH
518 break;
519
520 default:
8f19e15b 521 break;
99a45847
KH
522 }
523 }
df3aafd5
KH
524
525 /* If we have a 1MB 5434, we need to put ourselves in a mode where
99a45847 526 * the VCLK is double the pixel clock. */
df3aafd5
KH
527 cinfo->doubleVCLK = 0;
528 if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
529 var->bits_per_pixel == 16) {
530 cinfo->doubleVCLK = 1;
99a45847 531 }
df3aafd5 532
99a45847
KH
533 return 0;
534}
535
1da177e4
LT
536static int cirrusfb_check_var(struct fb_var_screeninfo *var,
537 struct fb_info *info)
538{
09a2910e
KH
539 int yres;
540 /* memory size in pixels */
541 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
614c0dc9 542 struct cirrusfb_info *cinfo = info->par;
1da177e4 543
1da177e4
LT
544 switch (var->bits_per_pixel) {
545 case 1:
546 var->red.offset = 0;
547 var->red.length = 1;
060b6002
KH
548 var->green = var->red;
549 var->blue = var->red;
1da177e4
LT
550 break;
551
552 case 8:
553 var->red.offset = 0;
99a45847 554 var->red.length = 8;
060b6002
KH
555 var->green = var->red;
556 var->blue = var->red;
1da177e4
LT
557 break;
558
559 case 16:
8503df65 560 if (isPReP) {
1da177e4
LT
561 var->red.offset = 2;
562 var->green.offset = -3;
563 var->blue.offset = 8;
564 } else {
c4dec396 565 var->red.offset = 11;
1da177e4
LT
566 var->green.offset = 5;
567 var->blue.offset = 0;
568 }
569 var->red.length = 5;
c4dec396 570 var->green.length = 6;
1da177e4
LT
571 var->blue.length = 5;
572 break;
573
7cade31c 574 case 24:
8503df65 575 if (isPReP) {
7cade31c
KH
576 var->red.offset = 0;
577 var->green.offset = 8;
578 var->blue.offset = 16;
1da177e4
LT
579 } else {
580 var->red.offset = 16;
581 var->green.offset = 8;
582 var->blue.offset = 0;
583 }
584 var->red.length = 8;
585 var->green.length = 8;
586 var->blue.length = 8;
587 break;
588
589 default:
75ed3a17
KH
590 dev_dbg(info->device,
591 "Unsupported bpp size: %d\n", var->bits_per_pixel);
0efb2a03 592 return -EINVAL;
1da177e4
LT
593 }
594
75ed3a17
KH
595 if (var->xres_virtual < var->xres)
596 var->xres_virtual = var->xres;
597 /* use highest possible virtual resolution */
598 if (var->yres_virtual == -1) {
599 var->yres_virtual = pixels / var->xres_virtual;
600
601 dev_info(info->device,
602 "virtual resolution set to maximum of %dx%d\n",
603 var->xres_virtual, var->yres_virtual);
604 }
605 if (var->yres_virtual < var->yres)
606 var->yres_virtual = var->yres;
607
608 if (var->xres_virtual * var->yres_virtual > pixels) {
609 dev_err(info->device, "mode %dx%dx%d rejected... "
610 "virtual resolution too high to fit into video memory!\n",
611 var->xres_virtual, var->yres_virtual,
612 var->bits_per_pixel);
613 return -EINVAL;
614 }
615
75ed3a17
KH
616 if (var->xoffset < 0)
617 var->xoffset = 0;
618 if (var->yoffset < 0)
619 var->yoffset = 0;
620
621 /* truncate xoffset and yoffset to maximum if too high */
622 if (var->xoffset > var->xres_virtual - var->xres)
623 var->xoffset = var->xres_virtual - var->xres - 1;
624 if (var->yoffset > var->yres_virtual - var->yres)
625 var->yoffset = var->yres_virtual - var->yres - 1;
626
1da177e4
LT
627 var->red.msb_right =
628 var->green.msb_right =
629 var->blue.msb_right =
630 var->transp.offset =
631 var->transp.length =
632 var->transp.msb_right = 0;
633
634 yres = var->yres;
635 if (var->vmode & FB_VMODE_DOUBLE)
636 yres *= 2;
637 else if (var->vmode & FB_VMODE_INTERLACED)
638 yres = (yres + 1) / 2;
639
640 if (yres >= 1280) {
75ed3a17 641 dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
8503df65 642 "special treatment required! (TODO)\n");
1da177e4
LT
643 return -EINVAL;
644 }
645
99a45847
KH
646 if (cirrusfb_check_pixclock(var, info))
647 return -EINVAL;
1da177e4 648
614c0dc9
KH
649 if (!is_laguna(cinfo))
650 var->accel_flags = FB_ACCELF_TEXT;
651
1da177e4
LT
652 return 0;
653}
654
75ed3a17 655static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
1da177e4 656{
75ed3a17 657 struct cirrusfb_info *cinfo = info->par;
486ff387 658 unsigned char old1f, old1e;
75ed3a17 659
8503df65 660 assert(cinfo != NULL);
486ff387
KH
661 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
662
663 if (div) {
75ed3a17
KH
664 dev_dbg(info->device, "Set %s as pixclock source.\n",
665 (div == 2) ? "MCLK/2" : "MCLK");
486ff387
KH
666 old1f |= 0x40;
667 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
668 if (div == 2)
669 old1e |= 1;
1da177e4 670
486ff387 671 vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
1da177e4 672 }
486ff387 673 vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
1da177e4
LT
674}
675
676/*************************************************************************
677 cirrusfb_set_par_foo()
678
679 actually writes the values for a new video mode into the hardware,
680**************************************************************************/
8503df65 681static int cirrusfb_set_par_foo(struct fb_info *info)
1da177e4
LT
682{
683 struct cirrusfb_info *cinfo = info->par;
684 struct fb_var_screeninfo *var = &info->var;
1da177e4
LT
685 u8 __iomem *regbase = cinfo->regbase;
686 unsigned char tmp;
6683e01e 687 int pitch;
1da177e4 688 const struct cirrusfb_board_info_rec *bi;
9a85cf51
KH
689 int hdispend, hsyncstart, hsyncend, htotal;
690 int yres, vdispend, vsyncstart, vsyncend, vtotal;
dafa32c5
KH
691 long freq;
692 int nom, den, div;
1b48cb56 693 unsigned int control = 0, format = 0, threshold = 0;
1da177e4 694
75ed3a17 695 dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
1da177e4 696 var->xres, var->yres, var->bits_per_pixel);
1da177e4 697
99a45847
KH
698 switch (var->bits_per_pixel) {
699 case 1:
700 info->fix.line_length = var->xres_virtual / 8;
701 info->fix.visual = FB_VISUAL_MONO10;
702 break;
1da177e4 703
99a45847
KH
704 case 8:
705 info->fix.line_length = var->xres_virtual;
706 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
707 break;
708
709 case 16:
7cade31c 710 case 24:
99a45847
KH
711 info->fix.line_length = var->xres_virtual *
712 var->bits_per_pixel >> 3;
713 info->fix.visual = FB_VISUAL_TRUECOLOR;
714 break;
1da177e4 715 }
99a45847
KH
716 info->fix.type = FB_TYPE_PACKED_PIXELS;
717
718 init_vgachip(info);
1da177e4
LT
719
720 bi = &cirrusfb_board_info[cinfo->btype];
721
9a85cf51
KH
722 hsyncstart = var->xres + var->right_margin;
723 hsyncend = hsyncstart + var->hsync_len;
8636a924
KH
724 htotal = (hsyncend + var->left_margin) / 8;
725 hdispend = var->xres / 8;
726 hsyncstart = hsyncstart / 8;
727 hsyncend = hsyncend / 8;
9a85cf51 728
8636a924
KH
729 vdispend = var->yres;
730 vsyncstart = vdispend + var->lower_margin;
9a85cf51
KH
731 vsyncend = vsyncstart + var->vsync_len;
732 vtotal = vsyncend + var->upper_margin;
9a85cf51
KH
733
734 if (var->vmode & FB_VMODE_DOUBLE) {
8636a924 735 vdispend *= 2;
9a85cf51
KH
736 vsyncstart *= 2;
737 vsyncend *= 2;
738 vtotal *= 2;
739 } else if (var->vmode & FB_VMODE_INTERLACED) {
8636a924 740 vdispend = (vdispend + 1) / 2;
9a85cf51
KH
741 vsyncstart = (vsyncstart + 1) / 2;
742 vsyncend = (vsyncend + 1) / 2;
743 vtotal = (vtotal + 1) / 2;
744 }
8636a924 745 yres = vdispend;
9a85cf51
KH
746 if (yres >= 1024) {
747 vtotal /= 2;
748 vsyncstart /= 2;
749 vsyncend /= 2;
750 vdispend /= 2;
751 }
8636a924
KH
752
753 vdispend -= 1;
754 vsyncstart -= 1;
755 vsyncend -= 1;
756 vtotal -= 2;
757
48c329e9 758 if (cinfo->multiplexing) {
9a85cf51
KH
759 htotal /= 2;
760 hsyncstart /= 2;
761 hsyncend /= 2;
762 hdispend /= 2;
763 }
8636a924
KH
764
765 htotal -= 5;
766 hdispend -= 1;
767 hsyncstart += 1;
768 hsyncend += 1;
769
1da177e4 770 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
8503df65 771 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
1da177e4
LT
772
773 /* if debugging is enabled, all parameters get output before writing */
75ed3a17 774 dev_dbg(info->device, "CRT0: %d\n", htotal);
9a85cf51 775 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
1da177e4 776
75ed3a17 777 dev_dbg(info->device, "CRT1: %d\n", hdispend);
9a85cf51 778 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
1da177e4 779
75ed3a17 780 dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
9a85cf51 781 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
1da177e4 782
8503df65 783 /* + 128: Compatible read */
75ed3a17 784 dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
8503df65 785 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
9a85cf51 786 128 + ((htotal + 5) % 32));
1da177e4 787
75ed3a17 788 dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
9a85cf51 789 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
1da177e4 790
9a85cf51
KH
791 tmp = hsyncend % 32;
792 if ((htotal + 5) & 32)
1da177e4 793 tmp += 128;
75ed3a17 794 dev_dbg(info->device, "CRT5: %d\n", tmp);
8503df65 795 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
1da177e4 796
75ed3a17 797 dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
9a85cf51 798 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
1da177e4
LT
799
800 tmp = 16; /* LineCompare bit #9 */
9a85cf51 801 if (vtotal & 256)
1da177e4 802 tmp |= 1;
9a85cf51 803 if (vdispend & 256)
1da177e4 804 tmp |= 2;
9a85cf51 805 if (vsyncstart & 256)
1da177e4 806 tmp |= 4;
9a85cf51 807 if ((vdispend + 1) & 256)
1da177e4 808 tmp |= 8;
9a85cf51 809 if (vtotal & 512)
1da177e4 810 tmp |= 32;
9a85cf51 811 if (vdispend & 512)
1da177e4 812 tmp |= 64;
9a85cf51 813 if (vsyncstart & 512)
1da177e4 814 tmp |= 128;
75ed3a17 815 dev_dbg(info->device, "CRT7: %d\n", tmp);
8503df65 816 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
1da177e4
LT
817
818 tmp = 0x40; /* LineCompare bit #8 */
9a85cf51 819 if ((vdispend + 1) & 512)
1da177e4
LT
820 tmp |= 0x20;
821 if (var->vmode & FB_VMODE_DOUBLE)
822 tmp |= 0x80;
75ed3a17 823 dev_dbg(info->device, "CRT9: %d\n", tmp);
8503df65 824 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
1da177e4 825
75ed3a17 826 dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
9a85cf51 827 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
1da177e4 828
75ed3a17 829 dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
9a85cf51 830 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
1da177e4 831
75ed3a17 832 dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
9a85cf51 833 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
1da177e4 834
75ed3a17 835 dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
9a85cf51 836 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
1da177e4 837
75ed3a17 838 dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
9a85cf51 839 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
1da177e4 840
75ed3a17 841 dev_dbg(info->device, "CRT18: 0xff\n");
8503df65 842 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
1da177e4
LT
843
844 tmp = 0;
845 if (var->vmode & FB_VMODE_INTERLACED)
846 tmp |= 1;
9a85cf51 847 if ((htotal + 5) & 64)
1da177e4 848 tmp |= 16;
9a85cf51 849 if ((htotal + 5) & 128)
1da177e4 850 tmp |= 32;
9a85cf51 851 if (vtotal & 256)
1da177e4 852 tmp |= 64;
9a85cf51 853 if (vtotal & 512)
1da177e4
LT
854 tmp |= 128;
855
75ed3a17 856 dev_dbg(info->device, "CRT1a: %d\n", tmp);
8503df65 857 vga_wcrt(regbase, CL_CRT1A, tmp);
1da177e4 858
dafa32c5 859 freq = PICOS2KHZ(var->pixclock);
df3aafd5
KH
860 if (var->bits_per_pixel == 24)
861 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
862 freq *= 3;
dd14f71c
KH
863 if (cinfo->multiplexing)
864 freq /= 2;
df3aafd5
KH
865 if (cinfo->doubleVCLK)
866 freq *= 2;
7cade31c 867
dafa32c5
KH
868 bestclock(freq, &nom, &den, &div);
869
75ed3a17
KH
870 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
871 freq, nom, den, div);
872
1da177e4
LT
873 /* set VCLK0 */
874 /* hardware RefClock: 14.31818 MHz */
875 /* formula: VClk = (OSC * N) / (D * (1+P)) */
876 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
877
8f19e15b
KH
878 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
879 cinfo->btype == BT_SD64) {
486ff387
KH
880 /* if freq is close to mclk or mclk/2 select mclk
881 * as clock source
882 */
75ed3a17 883 int divMCLK = cirrusfb_check_mclk(info, freq);
df3aafd5 884 if (divMCLK)
486ff387 885 nom = 0;
df3aafd5 886 cirrusfb_set_mclk_as_source(info, divMCLK);
486ff387 887 }
78d780e0 888 if (is_laguna(cinfo)) {
6e30fc08
KH
889 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
890 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
891 unsigned short tile_control;
892
78d780e0
KH
893 if (cinfo->btype == BT_LAGUNAB) {
894 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
895 tile_control &= ~0x80;
896 fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
897 }
6e30fc08
KH
898
899 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
900 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
901 control = fb_readw(cinfo->laguna_mmio + 0x402);
902 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
903 control &= ~0x6800;
904 format = 0;
4242a23c 905 threshold &= 0xffc0 & 0x3fbf;
6e30fc08 906 }
486ff387 907 if (nom) {
486ff387
KH
908 tmp = den << 1;
909 if (div != 0)
910 tmp |= 1;
486ff387
KH
911 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
912 if ((cinfo->btype == BT_SD64) ||
913 (cinfo->btype == BT_ALPINE) ||
914 (cinfo->btype == BT_GD5480))
915 tmp |= 0x80;
916
55a4ea6a 917 /* Laguna chipset has reversed clock registers */
78d780e0 918 if (is_laguna(cinfo)) {
55a4ea6a
KH
919 vga_wseq(regbase, CL_SEQRE, tmp);
920 vga_wseq(regbase, CL_SEQR1E, nom);
921 } else {
df3aafd5
KH
922 vga_wseq(regbase, CL_SEQRE, nom);
923 vga_wseq(regbase, CL_SEQR1E, tmp);
55a4ea6a 924 }
486ff387 925 }
1da177e4 926
9a85cf51 927 if (yres >= 1024)
1da177e4 928 /* 1280x1024 */
8503df65 929 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
1da177e4
LT
930 else
931 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
932 * address wrap, no compat. */
8503df65 933 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
1da177e4 934
1da177e4
LT
935 /* don't know if it would hurt to also program this if no interlaced */
936 /* mode is used, but I feel better this way.. :-) */
937 if (var->vmode & FB_VMODE_INTERLACED)
9a85cf51 938 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
1da177e4 939 else
8503df65 940 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
1da177e4 941
df3aafd5 942 /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
8503df65 943 /* enable display memory & CRTC I/O address for color mode */
df3aafd5 944 tmp = 0x03 | 0xc;
1da177e4
LT
945 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
946 tmp |= 0x40;
947 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
948 tmp |= 0x80;
8503df65 949 WGen(cinfo, VGA_MIS_W, tmp);
1da177e4 950
8503df65
KH
951 /* text cursor on and start line */
952 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
953 /* text cursor end line */
954 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
1da177e4
LT
955
956 /******************************************************
957 *
958 * 1 bpp
959 *
960 */
961
962 /* programming for different color depths */
963 if (var->bits_per_pixel == 1) {
75ed3a17 964 dev_dbg(info->device, "preparing for 1 bit deep display\n");
8503df65 965 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
1da177e4
LT
966
967 /* SR07 */
968 switch (cinfo->btype) {
969 case BT_SD64:
970 case BT_PICCOLO:
971 case BT_PICASSO:
972 case BT_SPECTRUM:
973 case BT_PICASSO4:
974 case BT_ALPINE:
975 case BT_GD5480:
8503df65 976 vga_wseq(regbase, CL_SEQR7,
48c329e9 977 cinfo->multiplexing ?
1da177e4
LT
978 bi->sr07_1bpp_mux : bi->sr07_1bpp);
979 break;
980
981 case BT_LAGUNA:
78d780e0 982 case BT_LAGUNAB:
8503df65
KH
983 vga_wseq(regbase, CL_SEQR7,
984 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1da177e4
LT
985 break;
986
987 default:
75ed3a17 988 dev_warn(info->device, "unknown Board\n");
1da177e4
LT
989 break;
990 }
991
992 /* Extended Sequencer Mode */
993 switch (cinfo->btype) {
1da177e4
LT
994
995 case BT_PICCOLO:
060b6002 996 case BT_SPECTRUM:
8503df65
KH
997 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
998 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
999 break;
1000
1001 case BT_PICASSO:
8503df65
KH
1002 /* ## vorher d0 avoid FIFO underruns..? */
1003 vga_wseq(regbase, CL_SEQRF, 0xd0);
1da177e4
LT
1004 break;
1005
8f19e15b 1006 case BT_SD64:
1da177e4
LT
1007 case BT_PICASSO4:
1008 case BT_ALPINE:
1009 case BT_GD5480:
1010 case BT_LAGUNA:
78d780e0 1011 case BT_LAGUNAB:
1da177e4
LT
1012 /* do nothing */
1013 break;
1014
1015 default:
75ed3a17 1016 dev_warn(info->device, "unknown Board\n");
1da177e4
LT
1017 break;
1018 }
1019
8503df65
KH
1020 /* pixel mask: pass-through for first plane */
1021 WGen(cinfo, VGA_PEL_MSK, 0x01);
48c329e9 1022 if (cinfo->multiplexing)
8503df65
KH
1023 /* hidden dac reg: 1280x1024 */
1024 WHDR(cinfo, 0x4a);
1da177e4 1025 else
8503df65
KH
1026 /* hidden dac: nothing */
1027 WHDR(cinfo, 0);
1028 /* memory mode: odd/even, ext. memory */
1029 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1030 /* plane mask: only write to first plane */
1031 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1da177e4
LT
1032 }
1033
1034 /******************************************************
1035 *
1036 * 8 bpp
1037 *
1038 */
1039
1040 else if (var->bits_per_pixel == 8) {
75ed3a17 1041 dev_dbg(info->device, "preparing for 8 bit deep display\n");
1da177e4
LT
1042 switch (cinfo->btype) {
1043 case BT_SD64:
1044 case BT_PICCOLO:
1045 case BT_PICASSO:
1046 case BT_SPECTRUM:
1047 case BT_PICASSO4:
1048 case BT_ALPINE:
1049 case BT_GD5480:
8503df65 1050 vga_wseq(regbase, CL_SEQR7,
48c329e9 1051 cinfo->multiplexing ?
1da177e4
LT
1052 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1053 break;
1054
1055 case BT_LAGUNA:
78d780e0 1056 case BT_LAGUNAB:
8503df65
KH
1057 vga_wseq(regbase, CL_SEQR7,
1058 vga_rseq(regbase, CL_SEQR7) | 0x01);
6e30fc08 1059 threshold |= 0x10;
1da177e4
LT
1060 break;
1061
1062 default:
75ed3a17 1063 dev_warn(info->device, "unknown Board\n");
1da177e4
LT
1064 break;
1065 }
1066
1067 switch (cinfo->btype) {
1da177e4 1068 case BT_PICCOLO:
1da177e4 1069 case BT_PICASSO:
1da177e4 1070 case BT_SPECTRUM:
8503df65
KH
1071 /* Fast Page-Mode writes */
1072 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1073 break;
1074
1075 case BT_PICASSO4:
1076#ifdef CONFIG_ZORRO
8503df65
KH
1077 /* ### INCOMPLETE!! */
1078 vga_wseq(regbase, CL_SEQRF, 0xb8);
1da177e4 1079#endif
1da177e4 1080 case BT_ALPINE:
8f19e15b 1081 case BT_SD64:
1da177e4
LT
1082 case BT_GD5480:
1083 case BT_LAGUNA:
78d780e0 1084 case BT_LAGUNAB:
1da177e4
LT
1085 /* do nothing */
1086 break;
1087
1088 default:
75ed3a17 1089 dev_warn(info->device, "unknown board\n");
1da177e4
LT
1090 break;
1091 }
1092
8503df65
KH
1093 /* mode register: 256 color mode */
1094 vga_wgfx(regbase, VGA_GFX_MODE, 64);
48c329e9 1095 if (cinfo->multiplexing)
8503df65
KH
1096 /* hidden dac reg: 1280x1024 */
1097 WHDR(cinfo, 0x4a);
1da177e4 1098 else
8503df65
KH
1099 /* hidden dac: nothing */
1100 WHDR(cinfo, 0);
1da177e4
LT
1101 }
1102
1103 /******************************************************
1104 *
1105 * 16 bpp
1106 *
1107 */
1108
1109 else if (var->bits_per_pixel == 16) {
75ed3a17 1110 dev_dbg(info->device, "preparing for 16 bit deep display\n");
1da177e4 1111 switch (cinfo->btype) {
1da177e4 1112 case BT_PICCOLO:
060b6002 1113 case BT_SPECTRUM:
8503df65
KH
1114 vga_wseq(regbase, CL_SEQR7, 0x87);
1115 /* Fast Page-Mode writes */
1116 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1117 break;
1118
1119 case BT_PICASSO:
8503df65
KH
1120 vga_wseq(regbase, CL_SEQR7, 0x27);
1121 /* Fast Page-Mode writes */
1122 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1123 break;
1124
8f19e15b 1125 case BT_SD64:
1da177e4 1126 case BT_PICASSO4:
1da177e4 1127 case BT_ALPINE:
8f19e15b 1128 /* Extended Sequencer Mode: 256c col. mode */
df3aafd5
KH
1129 vga_wseq(regbase, CL_SEQR7,
1130 cinfo->doubleVCLK ? 0xa3 : 0xa7);
1da177e4
LT
1131 break;
1132
1133 case BT_GD5480:
8503df65 1134 vga_wseq(regbase, CL_SEQR7, 0x17);
1da177e4
LT
1135 /* We already set SRF and SR1F */
1136 break;
1137
1138 case BT_LAGUNA:
78d780e0 1139 case BT_LAGUNAB:
8503df65
KH
1140 vga_wseq(regbase, CL_SEQR7,
1141 vga_rseq(regbase, CL_SEQR7) & ~0x01);
6e30fc08
KH
1142 control |= 0x2000;
1143 format |= 0x1400;
1144 threshold |= 0x10;
1da177e4
LT
1145 break;
1146
1147 default:
75ed3a17 1148 dev_warn(info->device, "unknown Board\n");
1da177e4
LT
1149 break;
1150 }
1151
8503df65
KH
1152 /* mode register: 256 color mode */
1153 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1da177e4 1154#ifdef CONFIG_PCI
df3aafd5 1155 WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
1da177e4
LT
1156#elif defined(CONFIG_ZORRO)
1157 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
8503df65 1158 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1da177e4 1159#endif
1da177e4
LT
1160 }
1161
1162 /******************************************************
1163 *
7cade31c 1164 * 24 bpp
1da177e4
LT
1165 *
1166 */
1167
7cade31c
KH
1168 else if (var->bits_per_pixel == 24) {
1169 dev_dbg(info->device, "preparing for 24 bit deep display\n");
1da177e4 1170 switch (cinfo->btype) {
1da177e4 1171 case BT_PICCOLO:
060b6002 1172 case BT_SPECTRUM:
8503df65
KH
1173 vga_wseq(regbase, CL_SEQR7, 0x85);
1174 /* Fast Page-Mode writes */
1175 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1176 break;
1177
1178 case BT_PICASSO:
8503df65
KH
1179 vga_wseq(regbase, CL_SEQR7, 0x25);
1180 /* Fast Page-Mode writes */
1181 vga_wseq(regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1182 break;
1183
8f19e15b 1184 case BT_SD64:
1da177e4 1185 case BT_PICASSO4:
1da177e4 1186 case BT_ALPINE:
8f19e15b 1187 /* Extended Sequencer Mode: 256c col. mode */
7cade31c 1188 vga_wseq(regbase, CL_SEQR7, 0xa5);
1da177e4
LT
1189 break;
1190
1191 case BT_GD5480:
7cade31c 1192 vga_wseq(regbase, CL_SEQR7, 0x15);
1da177e4
LT
1193 /* We already set SRF and SR1F */
1194 break;
1195
1196 case BT_LAGUNA:
78d780e0 1197 case BT_LAGUNAB:
8503df65
KH
1198 vga_wseq(regbase, CL_SEQR7,
1199 vga_rseq(regbase, CL_SEQR7) & ~0x01);
7cade31c
KH
1200 control |= 0x4000;
1201 format |= 0x2400;
6e30fc08 1202 threshold |= 0x20;
1da177e4
LT
1203 break;
1204
1205 default:
75ed3a17 1206 dev_warn(info->device, "unknown Board\n");
1da177e4
LT
1207 break;
1208 }
1209
8503df65
KH
1210 /* mode register: 256 color mode */
1211 vga_wgfx(regbase, VGA_GFX_MODE, 64);
8503df65
KH
1212 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1213 WHDR(cinfo, 0xc5);
1da177e4
LT
1214 }
1215
1216 /******************************************************
1217 *
1218 * unknown/unsupported bpp
1219 *
1220 */
1221
8503df65 1222 else
75ed3a17
KH
1223 dev_err(info->device,
1224 "What's this? requested color depth == %d.\n",
1da177e4 1225 var->bits_per_pixel);
1da177e4 1226
6683e01e
KH
1227 pitch = info->fix.line_length >> 3;
1228 vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1da177e4 1229 tmp = 0x22;
6683e01e 1230 if (pitch & 0x100)
1da177e4
LT
1231 tmp |= 0x10; /* offset overflow bit */
1232
8503df65
KH
1233 /* screen start addr #16-18, fastpagemode cycles */
1234 vga_wcrt(regbase, CL_CRT1B, tmp);
1da177e4 1235
213d4bdd
KH
1236 /* screen start address bit 19 */
1237 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
6683e01e 1238 vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
8503df65 1239
78d780e0 1240 if (is_laguna(cinfo)) {
213d4bdd
KH
1241 tmp = 0;
1242 if ((htotal + 5) & 256)
1243 tmp |= 128;
1244 if (hdispend & 256)
1245 tmp |= 64;
1246 if (hsyncstart & 256)
1247 tmp |= 48;
1248 if (vtotal & 1024)
1249 tmp |= 8;
1250 if (vdispend & 1024)
1251 tmp |= 4;
1252 if (vsyncstart & 1024)
1253 tmp |= 3;
1254
1255 vga_wcrt(regbase, CL_CRT1E, tmp);
1256 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1257 }
1258
8503df65
KH
1259 /* pixel panning */
1260 vga_wattr(regbase, CL_AR33, 0);
1da177e4
LT
1261
1262 /* [ EGS: SetOffset(); ] */
1263 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
8503df65
KH
1264 AttrOn(cinfo);
1265
78d780e0 1266 if (is_laguna(cinfo)) {
6e30fc08
KH
1267 /* no tiles */
1268 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1269 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1270 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1271 }
1da177e4
LT
1272 /* finally, turn on everything - turn off "FullBandwidth" bit */
1273 /* also, set "DotClock%2" bit where requested */
1274 tmp = 0x01;
1275
1276/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1277 if (var->vmode & FB_VMODE_CLOCK_HALVE)
1278 tmp |= 0x08;
1279*/
1280
8503df65 1281 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
75ed3a17 1282 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1da177e4 1283
1da177e4 1284#ifdef CIRRUSFB_DEBUG
75ed3a17 1285 cirrusfb_dbg_reg_dump(info, NULL);
1da177e4
LT
1286#endif
1287
1da177e4
LT
1288 return 0;
1289}
1290
1291/* for some reason incomprehensible to me, cirrusfb requires that you write
1292 * the registers twice for the settings to take..grr. -dte */
8503df65 1293static int cirrusfb_set_par(struct fb_info *info)
1da177e4 1294{
8503df65
KH
1295 cirrusfb_set_par_foo(info);
1296 return cirrusfb_set_par_foo(info);
1da177e4
LT
1297}
1298
8503df65
KH
1299static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1300 unsigned blue, unsigned transp,
1301 struct fb_info *info)
1da177e4
LT
1302{
1303 struct cirrusfb_info *cinfo = info->par;
1304
1305 if (regno > 255)
1306 return -EINVAL;
1307
1308 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1309 u32 v;
1310 red >>= (16 - info->var.red.length);
1311 green >>= (16 - info->var.green.length);
1312 blue >>= (16 - info->var.blue.length);
1313
8503df65 1314 if (regno >= 16)
1da177e4
LT
1315 return 1;
1316 v = (red << info->var.red.offset) |
1317 (green << info->var.green.offset) |
1318 (blue << info->var.blue.offset);
1319
060b6002 1320 cinfo->pseudo_palette[regno] = v;
1da177e4
LT
1321 return 0;
1322 }
1323
8503df65
KH
1324 if (info->var.bits_per_pixel == 8)
1325 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1da177e4
LT
1326
1327 return 0;
1328
1329}
1330
1331/*************************************************************************
1332 cirrusfb_pan_display()
1333
1334 performs display panning - provided hardware permits this
1335**************************************************************************/
8503df65
KH
1336static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1337 struct fb_info *info)
1da177e4 1338{
99a45847 1339 int xoffset;
1da177e4 1340 unsigned long base;
213d4bdd 1341 unsigned char tmp, xpix;
1da177e4
LT
1342 struct cirrusfb_info *cinfo = info->par;
1343
1da177e4
LT
1344 /* no range checks for xoffset and yoffset, */
1345 /* as fb_pan_display has already done this */
1346 if (var->vmode & FB_VMODE_YWRAP)
1347 return -EINVAL;
1348
1da177e4 1349 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1da177e4 1350
99a45847 1351 base = var->yoffset * info->fix.line_length + xoffset;
1da177e4
LT
1352
1353 if (info->var.bits_per_pixel == 1) {
1354 /* base is already correct */
1355 xpix = (unsigned char) (var->xoffset % 8);
1356 } else {
1357 base /= 4;
1358 xpix = (unsigned char) ((xoffset % 4) * 2);
1359 }
1360
78d780e0 1361 if (!is_laguna(cinfo))
1b48cb56 1362 cirrusfb_WaitBLT(cinfo->regbase);
1da177e4
LT
1363
1364 /* lower 8 + 8 bits of screen start address */
99a45847
KH
1365 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1366 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1da177e4 1367
213d4bdd
KH
1368 /* 0xf2 is %11110010, exclude tmp bits */
1369 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1da177e4
LT
1370 /* construct bits 16, 17 and 18 of screen start address */
1371 if (base & 0x10000)
1372 tmp |= 0x01;
1373 if (base & 0x20000)
1374 tmp |= 0x04;
1375 if (base & 0x40000)
1376 tmp |= 0x08;
1377
213d4bdd 1378 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1da177e4
LT
1379
1380 /* construct bit 19 of screen start address */
48c329e9 1381 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
78d780e0
KH
1382 tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1383 if (is_laguna(cinfo))
1384 tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1385 else
1386 tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
48c329e9
KH
1387 vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1388 }
1da177e4 1389
8503df65
KH
1390 /* write pixel panning value to AR33; this does not quite work in 8bpp
1391 *
1392 * ### Piccolo..? Will this work?
1393 */
1da177e4 1394 if (info->var.bits_per_pixel == 1)
8503df65 1395 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1da177e4 1396
8503df65 1397 return 0;
1da177e4
LT
1398}
1399
8503df65 1400static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1da177e4
LT
1401{
1402 /*
8503df65
KH
1403 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1404 * then the caller blanks by setting the CLUT (Color Look Up Table)
1405 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1406 * failed due to e.g. a video mode which doesn't support it.
1407 * Implements VESA suspend and powerdown modes on hardware that
1408 * supports disabling hsync/vsync:
1409 * blank_mode == 2: suspend vsync
1410 * blank_mode == 3: suspend hsync
1411 * blank_mode == 4: powerdown
1da177e4
LT
1412 */
1413 unsigned char val;
1414 struct cirrusfb_info *cinfo = info->par;
1415 int current_mode = cinfo->blank_mode;
1416
75ed3a17 1417 dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1da177e4
LT
1418
1419 if (info->state != FBINFO_STATE_RUNNING ||
1420 current_mode == blank_mode) {
75ed3a17 1421 dev_dbg(info->device, "EXIT, returning 0\n");
1da177e4
LT
1422 return 0;
1423 }
1424
1425 /* Undo current */
1426 if (current_mode == FB_BLANK_NORMAL ||
213d4bdd 1427 current_mode == FB_BLANK_UNBLANK)
8503df65 1428 /* clear "FullBandwidth" bit */
213d4bdd
KH
1429 val = 0;
1430 else
8503df65 1431 /* set "FullBandwidth" bit */
213d4bdd
KH
1432 val = 0x20;
1433
1434 val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1435 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1da177e4
LT
1436
1437 switch (blank_mode) {
1438 case FB_BLANK_UNBLANK:
1439 case FB_BLANK_NORMAL:
213d4bdd 1440 val = 0x00;
1da177e4
LT
1441 break;
1442 case FB_BLANK_VSYNC_SUSPEND:
213d4bdd 1443 val = 0x04;
1da177e4
LT
1444 break;
1445 case FB_BLANK_HSYNC_SUSPEND:
213d4bdd 1446 val = 0x02;
1da177e4
LT
1447 break;
1448 case FB_BLANK_POWERDOWN:
213d4bdd 1449 val = 0x06;
1da177e4
LT
1450 break;
1451 default:
75ed3a17 1452 dev_dbg(info->device, "EXIT, returning 1\n");
1da177e4
LT
1453 return 1;
1454 }
1455
213d4bdd
KH
1456 vga_wgfx(cinfo->regbase, CL_GRE, val);
1457
1da177e4 1458 cinfo->blank_mode = blank_mode;
75ed3a17 1459 dev_dbg(info->device, "EXIT, returning 0\n");
1da177e4
LT
1460
1461 /* Let fbcon do a soft blank for us */
1462 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1463}
213d4bdd 1464
1da177e4
LT
1465/**** END Hardware specific Routines **************************************/
1466/****************************************************************************/
1467/**** BEGIN Internal Routines ***********************************************/
1468
9199ec5c 1469static void init_vgachip(struct fb_info *info)
1da177e4 1470{
9199ec5c 1471 struct cirrusfb_info *cinfo = info->par;
1da177e4
LT
1472 const struct cirrusfb_board_info_rec *bi;
1473
8503df65 1474 assert(cinfo != NULL);
1da177e4
LT
1475
1476 bi = &cirrusfb_board_info[cinfo->btype];
1477
1478 /* reset board globally */
1479 switch (cinfo->btype) {
1480 case BT_PICCOLO:
8503df65
KH
1481 WSFR(cinfo, 0x01);
1482 udelay(500);
1483 WSFR(cinfo, 0x51);
1484 udelay(500);
1da177e4
LT
1485 break;
1486 case BT_PICASSO:
8503df65
KH
1487 WSFR2(cinfo, 0xff);
1488 udelay(500);
1da177e4
LT
1489 break;
1490 case BT_SD64:
1491 case BT_SPECTRUM:
8503df65
KH
1492 WSFR(cinfo, 0x1f);
1493 udelay(500);
1494 WSFR(cinfo, 0x4f);
1495 udelay(500);
1da177e4
LT
1496 break;
1497 case BT_PICASSO4:
8503df65
KH
1498 /* disable flickerfixer */
1499 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1500 mdelay(100);
8503df65
KH
1501 /* mode */
1502 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
7cade31c 1503 case BT_GD5480: /* fall through */
8503df65
KH
1504 /* from Klaus' NetBSD driver: */
1505 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
7cade31c
KH
1506 case BT_ALPINE: /* fall through */
1507 /* put blitter into 542x compat */
1508 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1da177e4
LT
1509 break;
1510
1b48cb56 1511 case BT_LAGUNA:
78d780e0 1512 case BT_LAGUNAB:
1da177e4
LT
1513 /* Nothing to do to reset the board. */
1514 break;
1515
1516 default:
75ed3a17 1517 dev_err(info->device, "Warning: Unknown board type\n");
1da177e4
LT
1518 break;
1519 }
1520
9199ec5c
KH
1521 /* make sure RAM size set by this point */
1522 assert(info->screen_size > 0);
1da177e4
LT
1523
1524 /* the P4 is not fully initialized here; I rely on it having been */
1525 /* inited under AmigaOS already, which seems to work just fine */
8503df65 1526 /* (Klaus advised to do it this way) */
1da177e4
LT
1527
1528 if (cinfo->btype != BT_PICASSO4) {
8503df65
KH
1529 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1530 WGen(cinfo, CL_POS102, 0x01);
1531 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1da177e4
LT
1532
1533 if (cinfo->btype != BT_SD64)
8503df65 1534 WGen(cinfo, CL_VSSM2, 0x01);
1da177e4 1535
8503df65 1536 /* reset sequencer logic */
1b48cb56 1537 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1da177e4 1538
8503df65
KH
1539 /* FullBandwidth (video off) and 8/9 dot clock */
1540 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1da177e4 1541
8503df65
KH
1542 /* "magic cookie" - doesn't make any sense to me.. */
1543/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1544 /* unlock all extension registers */
1545 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1da177e4 1546
1da177e4
LT
1547 switch (cinfo->btype) {
1548 case BT_GD5480:
8503df65 1549 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1da177e4
LT
1550 break;
1551 case BT_ALPINE:
1b48cb56 1552 case BT_LAGUNA:
78d780e0 1553 case BT_LAGUNAB:
1da177e4
LT
1554 break;
1555 case BT_SD64:
df3aafd5 1556#ifdef CONFIG_ZORRO
8503df65 1557 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
df3aafd5 1558#endif
1da177e4
LT
1559 break;
1560 default:
8503df65
KH
1561 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1562 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1da177e4
LT
1563 break;
1564 }
1565 }
8503df65
KH
1566 /* plane mask: nothing */
1567 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1568 /* character map select: doesn't even matter in gx mode */
1569 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
48c329e9
KH
1570 /* memory mode: chain4, ext. memory */
1571 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1da177e4
LT
1572
1573 /* controller-internal base address of video memory */
1574 if (bi->init_sr07)
8503df65 1575 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1da177e4 1576
8503df65
KH
1577 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1578 /* EEPROM control: shouldn't be necessary to write to this at all.. */
1da177e4 1579
8503df65
KH
1580 /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1581 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1582 /* graphics cursor Y position (..."... ) */
1583 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1584 /* graphics cursor attributes */
1585 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1586 /* graphics cursor pattern address */
1587 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1da177e4
LT
1588
1589 /* writing these on a P4 might give problems.. */
1590 if (cinfo->btype != BT_PICASSO4) {
8503df65
KH
1591 /* configuration readback and ext. color */
1592 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1593 /* signature generator */
1594 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1da177e4
LT
1595 }
1596
8503df65
KH
1597 /* Screen A preset row scan: none */
1598 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1599 /* Text cursor start: disable text cursor */
1600 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1601 /* Text cursor end: - */
1602 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
8503df65
KH
1603 /* text cursor location high: 0 */
1604 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1605 /* text cursor location low: 0 */
1606 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1607
1608 /* Underline Row scanline: - */
1609 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1da177e4 1610 /* ### add 0x40 for text modes with > 30 MHz pixclock */
8503df65
KH
1611 /* ext. display controls: ext.adr. wrap */
1612 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1613
1614 /* Set/Reset registes: - */
1615 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1616 /* Set/Reset enable: - */
1617 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1618 /* Color Compare: - */
1619 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1620 /* Data Rotate: - */
1621 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1622 /* Read Map Select: - */
1623 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1624 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1625 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1626 /* Miscellaneous: memory map base address, graphics mode */
1627 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1628 /* Color Don't care: involve all planes */
1629 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1630 /* Bit Mask: no mask at all */
1631 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1b48cb56 1632
df3aafd5
KH
1633 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1634 is_laguna(cinfo))
8503df65
KH
1635 /* (5434 can't have bit 3 set for bitblt) */
1636 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1da177e4 1637 else
8503df65
KH
1638 /* Graphics controller mode extensions: finer granularity,
1639 * 8byte data latches
1640 */
1641 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1642
1643 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1644 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1645 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1646 /* Background color byte 1: - */
1647 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1648 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1649
1650 /* Attribute Controller palette registers: "identity mapping" */
1651 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1652 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1653 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1654 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1655 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1656 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1657 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1658 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1659 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1660 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1661 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1662 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1663 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1664 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1665 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1666 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1667
1668 /* Attribute Controller mode: graphics mode */
1669 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1670 /* Overscan color reg.: reg. 0 */
1671 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1672 /* Color Plane enable: Enable all 4 planes */
1673 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
8503df65
KH
1674 /* Color Select: - */
1675 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1676
1677 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1da177e4 1678
8503df65
KH
1679 /* BLT Start/status: Blitter reset */
1680 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1681 /* - " - : "end-of-reset" */
1682 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1da177e4
LT
1683
1684 /* misc... */
8503df65 1685 WHDR(cinfo, 0); /* Hidden DAC register: - */
1da177e4
LT
1686 return;
1687}
1688
8503df65 1689static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1da177e4
LT
1690{
1691#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1692 static int IsOn = 0; /* XXX not ok for multiple boards */
1693
1da177e4
LT
1694 if (cinfo->btype == BT_PICASSO4)
1695 return; /* nothing to switch */
1696 if (cinfo->btype == BT_ALPINE)
1697 return; /* nothing to switch */
1698 if (cinfo->btype == BT_GD5480)
1699 return; /* nothing to switch */
1700 if (cinfo->btype == BT_PICASSO) {
1701 if ((on && !IsOn) || (!on && IsOn))
8503df65 1702 WSFR(cinfo, 0xff);
1da177e4
LT
1703 return;
1704 }
1705 if (on) {
1706 switch (cinfo->btype) {
1707 case BT_SD64:
8503df65 1708 WSFR(cinfo, cinfo->SFR | 0x21);
1da177e4
LT
1709 break;
1710 case BT_PICCOLO:
8503df65 1711 WSFR(cinfo, cinfo->SFR | 0x28);
1da177e4
LT
1712 break;
1713 case BT_SPECTRUM:
8503df65 1714 WSFR(cinfo, 0x6f);
1da177e4
LT
1715 break;
1716 default: /* do nothing */ break;
1717 }
1718 } else {
1719 switch (cinfo->btype) {
1720 case BT_SD64:
8503df65 1721 WSFR(cinfo, cinfo->SFR & 0xde);
1da177e4
LT
1722 break;
1723 case BT_PICCOLO:
8503df65 1724 WSFR(cinfo, cinfo->SFR & 0xd7);
1da177e4
LT
1725 break;
1726 case BT_SPECTRUM:
8503df65 1727 WSFR(cinfo, 0x4f);
1da177e4 1728 break;
75ed3a17
KH
1729 default: /* do nothing */
1730 break;
1da177e4
LT
1731 }
1732 }
1da177e4
LT
1733#endif /* CONFIG_ZORRO */
1734}
1735
1da177e4
LT
1736/******************************************/
1737/* Linux 2.6-style accelerated functions */
1738/******************************************/
1739
8343c89c
KH
1740static int cirrusfb_sync(struct fb_info *info)
1741{
1742 struct cirrusfb_info *cinfo = info->par;
1743
1744 if (!is_laguna(cinfo)) {
1745 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1746 cpu_relax();
1747 }
1748 return 0;
1749}
1750
8503df65
KH
1751static void cirrusfb_fillrect(struct fb_info *info,
1752 const struct fb_fillrect *region)
1da177e4 1753{
1da177e4
LT
1754 struct fb_fillrect modded;
1755 int vxres, vyres;
060b6002
KH
1756 struct cirrusfb_info *cinfo = info->par;
1757 int m = info->var.bits_per_pixel;
1758 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1759 cinfo->pseudo_palette[region->color] : region->color;
1da177e4
LT
1760
1761 if (info->state != FBINFO_STATE_RUNNING)
1762 return;
1763 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1764 cfb_fillrect(info, region);
1765 return;
1766 }
1767
1768 vxres = info->var.xres_virtual;
1769 vyres = info->var.yres_virtual;
1770
1771 memcpy(&modded, region, sizeof(struct fb_fillrect));
1772
8503df65 1773 if (!modded.width || !modded.height ||
1da177e4
LT
1774 modded.dx >= vxres || modded.dy >= vyres)
1775 return;
1776
8503df65
KH
1777 if (modded.dx + modded.width > vxres)
1778 modded.width = vxres - modded.dx;
1779 if (modded.dy + modded.height > vyres)
1780 modded.height = vyres - modded.dy;
1da177e4 1781
060b6002
KH
1782 cirrusfb_RectFill(cinfo->regbase,
1783 info->var.bits_per_pixel,
1784 (region->dx * m) / 8, region->dy,
1785 (region->width * m) / 8, region->height,
9e848062
KH
1786 color, color,
1787 info->fix.line_length, 0x40);
1da177e4
LT
1788}
1789
8503df65
KH
1790static void cirrusfb_copyarea(struct fb_info *info,
1791 const struct fb_copyarea *area)
1da177e4 1792{
1da177e4
LT
1793 struct fb_copyarea modded;
1794 u32 vxres, vyres;
060b6002
KH
1795 struct cirrusfb_info *cinfo = info->par;
1796 int m = info->var.bits_per_pixel;
1da177e4
LT
1797
1798 if (info->state != FBINFO_STATE_RUNNING)
1799 return;
1800 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1801 cfb_copyarea(info, area);
1802 return;
1803 }
1804
1805 vxres = info->var.xres_virtual;
1806 vyres = info->var.yres_virtual;
060b6002 1807 memcpy(&modded, area, sizeof(struct fb_copyarea));
1da177e4 1808
8503df65 1809 if (!modded.width || !modded.height ||
1da177e4
LT
1810 modded.sx >= vxres || modded.sy >= vyres ||
1811 modded.dx >= vxres || modded.dy >= vyres)
1812 return;
1813
8503df65
KH
1814 if (modded.sx + modded.width > vxres)
1815 modded.width = vxres - modded.sx;
1816 if (modded.dx + modded.width > vxres)
1817 modded.width = vxres - modded.dx;
1818 if (modded.sy + modded.height > vyres)
1819 modded.height = vyres - modded.sy;
1820 if (modded.dy + modded.height > vyres)
1821 modded.height = vyres - modded.dy;
1da177e4 1822
060b6002
KH
1823 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1824 (area->sx * m) / 8, area->sy,
1825 (area->dx * m) / 8, area->dy,
1826 (area->width * m) / 8, area->height,
0ff1edee 1827 info->fix.line_length);
060b6002 1828
1da177e4
LT
1829}
1830
8503df65
KH
1831static void cirrusfb_imageblit(struct fb_info *info,
1832 const struct fb_image *image)
1da177e4
LT
1833{
1834 struct cirrusfb_info *cinfo = info->par;
7cade31c 1835 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1da177e4 1836
9e848062
KH
1837 if (info->state != FBINFO_STATE_RUNNING)
1838 return;
df3aafd5
KH
1839 /* Alpine/SD64 does not work at 24bpp ??? */
1840 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1841 cfb_imageblit(info, image);
1842 else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1843 op == 0xc)
9e848062
KH
1844 cfb_imageblit(info, image);
1845 else {
1846 unsigned size = ((image->width + 7) >> 3) * image->height;
1847 int m = info->var.bits_per_pixel;
1848 u32 fg, bg;
1849
1850 if (info->var.bits_per_pixel == 8) {
1851 fg = image->fg_color;
1852 bg = image->bg_color;
1853 } else {
1854 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1855 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1856 }
7cade31c
KH
1857 if (info->var.bits_per_pixel == 24) {
1858 /* clear background first */
1859 cirrusfb_RectFill(cinfo->regbase,
1860 info->var.bits_per_pixel,
1861 (image->dx * m) / 8, image->dy,
1862 (image->width * m) / 8,
1863 image->height,
1864 bg, bg,
1865 info->fix.line_length, 0x40);
1866 }
9e848062
KH
1867 cirrusfb_RectFill(cinfo->regbase,
1868 info->var.bits_per_pixel,
1869 (image->dx * m) / 8, image->dy,
1870 (image->width * m) / 8, image->height,
1871 fg, bg,
7cade31c 1872 info->fix.line_length, op);
9e848062
KH
1873 memcpy(info->screen_base, image->data, size);
1874 }
1da177e4
LT
1875}
1876
1da177e4
LT
1877#ifdef CONFIG_PPC_PREP
1878#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1879#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
8503df65 1880static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1da177e4 1881{
1da177e4
LT
1882 *display = PREP_VIDEO_BASE;
1883 *registers = (unsigned long) PREP_IO_BASE;
1da177e4
LT
1884}
1885
1886#endif /* CONFIG_PPC_PREP */
1887
1da177e4 1888#ifdef CONFIG_PCI
8503df65 1889static int release_io_ports;
1da177e4
LT
1890
1891/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1892 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
1893 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1894 * seem to have. */
75ed3a17
KH
1895static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1896 u8 __iomem *regbase)
1da177e4
LT
1897{
1898 unsigned long mem;
55a4ea6a 1899 struct cirrusfb_info *cinfo = info->par;
1da177e4 1900
78d780e0 1901 if (is_laguna(cinfo)) {
55a4ea6a
KH
1902 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1903
1904 mem = ((SR14 & 7) + 1) << 20;
1905 } else {
1906 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1907 switch ((SRF & 0x18)) {
1908 case 0x08:
1909 mem = 512 * 1024;
1910 break;
1911 case 0x10:
1912 mem = 1024 * 1024;
1913 break;
1914 /* 64-bit DRAM data bus width; assume 2MB.
1915 * Also indicates 2MB memory on the 5430.
1916 */
1917 case 0x18:
1918 mem = 2048 * 1024;
1919 break;
1920 default:
1921 dev_warn(info->device, "Unknown memory size!\n");
1922 mem = 1024 * 1024;
1923 }
1924 /* If DRAM bank switching is enabled, there must be
1925 * twice as much memory installed. (4MB on the 5434)
1926 */
df3aafd5 1927 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
55a4ea6a 1928 mem *= 2;
1da177e4 1929 }
8503df65 1930
1da177e4 1931 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1da177e4
LT
1932 return mem;
1933}
1934
8503df65
KH
1935static void get_pci_addrs(const struct pci_dev *pdev,
1936 unsigned long *display, unsigned long *registers)
1da177e4 1937{
8503df65
KH
1938 assert(pdev != NULL);
1939 assert(display != NULL);
1940 assert(registers != NULL);
1da177e4 1941
1da177e4
LT
1942 *display = 0;
1943 *registers = 0;
1944
1945 /* This is a best-guess for now */
1946
1947 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1948 *display = pci_resource_start(pdev, 1);
1949 *registers = pci_resource_start(pdev, 0);
1950 } else {
1951 *display = pci_resource_start(pdev, 0);
1952 *registers = pci_resource_start(pdev, 1);
1953 }
1954
8503df65 1955 assert(*display != 0);
1da177e4
LT
1956}
1957
9199ec5c 1958static void cirrusfb_pci_unmap(struct fb_info *info)
1da177e4 1959{
64beab14 1960 struct pci_dev *pdev = to_pci_dev(info->device);
6e30fc08 1961 struct cirrusfb_info *cinfo = info->par;
1da177e4 1962
6e30fc08
KH
1963 if (cinfo->laguna_mmio == NULL)
1964 iounmap(cinfo->laguna_mmio);
9199ec5c 1965 iounmap(info->screen_base);
1da177e4
LT
1966#if 0 /* if system didn't claim this region, we would... */
1967 release_mem_region(0xA0000, 65535);
1968#endif
1969 if (release_io_ports)
1970 release_region(0x3C0, 32);
1971 pci_release_regions(pdev);
1da177e4
LT
1972}
1973#endif /* CONFIG_PCI */
1974
1da177e4 1975#ifdef CONFIG_ZORRO
f5ee051e 1976static void cirrusfb_zorro_unmap(struct fb_info *info)
1da177e4 1977{
d91f5bb6 1978 struct cirrusfb_info *cinfo = info->par;
64beab14
KH
1979 struct zorro_dev *zdev = to_zorro_dev(info->device);
1980
0e0d1336 1981 if (info->fix.smem_start > 16 * MB_)
9199ec5c 1982 iounmap(info->screen_base);
0e0d1336
GU
1983 if (info->fix.mmio_start > 16 * MB_)
1984 iounmap(cinfo->regbase);
1985
1986 zorro_release_device(zdev);
1da177e4
LT
1987}
1988#endif /* CONFIG_ZORRO */
1989
48c329e9
KH
1990/* function table of the above functions */
1991static struct fb_ops cirrusfb_ops = {
1992 .owner = THIS_MODULE,
1993 .fb_open = cirrusfb_open,
1994 .fb_release = cirrusfb_release,
1995 .fb_setcolreg = cirrusfb_setcolreg,
1996 .fb_check_var = cirrusfb_check_var,
1997 .fb_set_par = cirrusfb_set_par,
1998 .fb_pan_display = cirrusfb_pan_display,
1999 .fb_blank = cirrusfb_blank,
2000 .fb_fillrect = cirrusfb_fillrect,
2001 .fb_copyarea = cirrusfb_copyarea,
8343c89c 2002 .fb_sync = cirrusfb_sync,
48c329e9
KH
2003 .fb_imageblit = cirrusfb_imageblit,
2004};
2005
c395d3e8 2006static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
1da177e4 2007{
9199ec5c 2008 struct cirrusfb_info *cinfo = info->par;
1da177e4
LT
2009 struct fb_var_screeninfo *var = &info->var;
2010
1da177e4
LT
2011 info->pseudo_palette = cinfo->pseudo_palette;
2012 info->flags = FBINFO_DEFAULT
2013 | FBINFO_HWACCEL_XPAN
2014 | FBINFO_HWACCEL_YPAN
2015 | FBINFO_HWACCEL_FILLRECT
9e848062 2016 | FBINFO_HWACCEL_IMAGEBLIT
1da177e4 2017 | FBINFO_HWACCEL_COPYAREA;
614c0dc9 2018 if (noaccel || is_laguna(cinfo)) {
1da177e4 2019 info->flags |= FBINFO_HWACCEL_DISABLED;
614c0dc9
KH
2020 info->fix.accel = FB_ACCEL_NONE;
2021 } else
2022 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
2023
1da177e4 2024 info->fbops = &cirrusfb_ops;
9e848062 2025
1da177e4
LT
2026 if (cinfo->btype == BT_GD5480) {
2027 if (var->bits_per_pixel == 16)
2028 info->screen_base += 1 * MB_;
1cea9a9a 2029 if (var->bits_per_pixel == 32)
1da177e4
LT
2030 info->screen_base += 2 * MB_;
2031 }
2032
2033 /* Fill fix common fields */
2034 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2035 sizeof(info->fix.id));
2036
2037 /* monochrome: only 1 memory plane */
2038 /* 8 bit and above: Use whole memory area */
9199ec5c
KH
2039 info->fix.smem_len = info->screen_size;
2040 if (var->bits_per_pixel == 1)
2041 info->fix.smem_len /= 4;
1da177e4 2042 info->fix.type_aux = 0;
1da177e4
LT
2043 info->fix.xpanstep = 1;
2044 info->fix.ypanstep = 1;
2045 info->fix.ywrapstep = 0;
1da177e4
LT
2046
2047 /* FIXME: map region at 0xB8000 if available, fill in here */
1da177e4 2048 info->fix.mmio_len = 0;
1da177e4
LT
2049
2050 fb_alloc_cmap(&info->cmap, 256, 0);
2051
2052 return 0;
2053}
2054
c395d3e8 2055static int __devinit cirrusfb_register(struct fb_info *info)
1da177e4 2056{
9199ec5c 2057 struct cirrusfb_info *cinfo = info->par;
1da177e4 2058 int err;
1da177e4
LT
2059
2060 /* sanity checks */
48c329e9 2061 assert(cinfo->btype != BT_NONE);
1da177e4 2062
a1d35a7a
KH
2063 /* set all the vital stuff */
2064 cirrusfb_set_fbinfo(info);
2065
75ed3a17 2066 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
1da177e4 2067
a1d35a7a
KH
2068 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2069 if (!err) {
75ed3a17 2070 dev_dbg(info->device, "wrong initial video mode\n");
a1d35a7a
KH
2071 err = -EINVAL;
2072 goto err_dealloc_cmap;
2073 }
2074
1da177e4
LT
2075 info->var.activate = FB_ACTIVATE_NOW;
2076
99a45847 2077 err = cirrusfb_check_var(&info->var, info);
1da177e4
LT
2078 if (err < 0) {
2079 /* should never happen */
75ed3a17
KH
2080 dev_dbg(info->device,
2081 "choking on default var... umm, no good.\n");
a1d35a7a 2082 goto err_dealloc_cmap;
1da177e4
LT
2083 }
2084
1da177e4
LT
2085 err = register_framebuffer(info);
2086 if (err < 0) {
75ed3a17
KH
2087 dev_err(info->device,
2088 "could not register fb device; err = %d!\n", err);
1da177e4
LT
2089 goto err_dealloc_cmap;
2090 }
2091
1da177e4
LT
2092 return 0;
2093
2094err_dealloc_cmap:
2095 fb_dealloc_cmap(&info->cmap);
1da177e4
LT
2096 return err;
2097}
2098
8503df65 2099static void __devexit cirrusfb_cleanup(struct fb_info *info)
1da177e4
LT
2100{
2101 struct cirrusfb_info *cinfo = info->par;
1da177e4 2102
8503df65 2103 switch_monitor(cinfo, 0);
8503df65
KH
2104 unregister_framebuffer(info);
2105 fb_dealloc_cmap(&info->cmap);
75ed3a17 2106 dev_dbg(info->device, "Framebuffer unregistered\n");
9199ec5c 2107 cinfo->unmap(info);
060b6002 2108 framebuffer_release(info);
1da177e4
LT
2109}
2110
1da177e4 2111#ifdef CONFIG_PCI
c395d3e8
KH
2112static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2113 const struct pci_device_id *ent)
1da177e4
LT
2114{
2115 struct cirrusfb_info *cinfo;
2116 struct fb_info *info;
1da177e4
LT
2117 unsigned long board_addr, board_size;
2118 int ret;
2119
2120 ret = pci_enable_device(pdev);
2121 if (ret < 0) {
2122 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2123 goto err_out;
2124 }
2125
2126 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2127 if (!info) {
2128 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2129 ret = -ENOMEM;
78d780e0 2130 goto err_out;
1da177e4
LT
2131 }
2132
2133 cinfo = info->par;
48c329e9 2134 cinfo->btype = (enum cirrus_board) ent->driver_data;
1da177e4 2135
75ed3a17
KH
2136 dev_dbg(info->device,
2137 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
48c329e9 2138 (unsigned long long)pdev->resource[0].start, cinfo->btype);
75ed3a17
KH
2139 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2140 (unsigned long long)pdev->resource[1].start);
1da177e4 2141
8503df65
KH
2142 if (isPReP) {
2143 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
1da177e4 2144#ifdef CONFIG_PPC_PREP
9199ec5c 2145 get_prep_addrs(&board_addr, &info->fix.mmio_start);
1da177e4 2146#endif
8503df65 2147 /* PReP dies if we ioremap the IO registers, but it works w/out... */
9199ec5c 2148 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
1da177e4 2149 } else {
75ed3a17
KH
2150 dev_dbg(info->device,
2151 "Attempt to get PCI info for Cirrus Graphics Card\n");
9199ec5c 2152 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
8503df65
KH
2153 /* FIXME: this forces VGA. alternatives? */
2154 cinfo->regbase = NULL;
6e30fc08 2155 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
1da177e4
LT
2156 }
2157
75ed3a17 2158 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
9199ec5c 2159 board_addr, info->fix.mmio_start);
1da177e4 2160
48c329e9 2161 board_size = (cinfo->btype == BT_GD5480) ?
75ed3a17 2162 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
1da177e4
LT
2163
2164 ret = pci_request_regions(pdev, "cirrusfb");
8503df65 2165 if (ret < 0) {
75ed3a17
KH
2166 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2167 board_addr);
1da177e4
LT
2168 goto err_release_fb;
2169 }
2170#if 0 /* if the system didn't claim this region, we would... */
2171 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
75ed3a17
KH
2172 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2173 0xA0000L);
1da177e4
LT
2174 ret = -EBUSY;
2175 goto err_release_regions;
2176 }
2177#endif
2178 if (request_region(0x3C0, 32, "cirrusfb"))
2179 release_io_ports = 1;
2180
9199ec5c
KH
2181 info->screen_base = ioremap(board_addr, board_size);
2182 if (!info->screen_base) {
1da177e4
LT
2183 ret = -EIO;
2184 goto err_release_legacy;
2185 }
2186
9199ec5c
KH
2187 info->fix.smem_start = board_addr;
2188 info->screen_size = board_size;
1da177e4
LT
2189 cinfo->unmap = cirrusfb_pci_unmap;
2190
75ed3a17
KH
2191 dev_info(info->device,
2192 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2193 info->screen_size >> 10, board_addr);
1da177e4
LT
2194 pci_set_drvdata(pdev, info);
2195
9199ec5c 2196 ret = cirrusfb_register(info);
78d780e0
KH
2197 if (!ret)
2198 return 0;
1da177e4 2199
78d780e0
KH
2200 pci_set_drvdata(pdev, NULL);
2201 iounmap(info->screen_base);
1da177e4
LT
2202err_release_legacy:
2203 if (release_io_ports)
2204 release_region(0x3C0, 32);
2205#if 0
2206 release_mem_region(0xA0000, 65535);
2207err_release_regions:
2208#endif
2209 pci_release_regions(pdev);
2210err_release_fb:
78d780e0 2211 if (cinfo->laguna_mmio != NULL)
6e30fc08 2212 iounmap(cinfo->laguna_mmio);
1da177e4 2213 framebuffer_release(info);
1da177e4
LT
2214err_out:
2215 return ret;
2216}
2217
8503df65 2218static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
1da177e4
LT
2219{
2220 struct fb_info *info = pci_get_drvdata(pdev);
1da177e4 2221
8503df65 2222 cirrusfb_cleanup(info);
1da177e4
LT
2223}
2224
2225static struct pci_driver cirrusfb_pci_driver = {
2226 .name = "cirrusfb",
2227 .id_table = cirrusfb_pci_table,
2228 .probe = cirrusfb_pci_register,
2229 .remove = __devexit_p(cirrusfb_pci_unregister),
2230#ifdef CONFIG_PM
2231#if 0
2232 .suspend = cirrusfb_pci_suspend,
2233 .resume = cirrusfb_pci_resume,
2234#endif
2235#endif
2236};
2237#endif /* CONFIG_PCI */
2238
1da177e4 2239#ifdef CONFIG_ZORRO
c395d3e8
KH
2240static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2241 const struct zorro_device_id *ent)
1da177e4 2242{
1da177e4 2243 struct fb_info *info;
0e0d1336
GU
2244 int error;
2245 const struct zorrocl *zcl;
7345de32 2246 enum cirrus_board btype;
0e0d1336
GU
2247 unsigned long regbase, ramsize, rambase;
2248 struct cirrusfb_info *cinfo;
1da177e4
LT
2249
2250 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2251 if (!info) {
8503df65 2252 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
0e0d1336 2253 return -ENOMEM;
1da177e4
LT
2254 }
2255
0e0d1336
GU
2256 zcl = (const struct zorrocl *)ent->driver_data;
2257 btype = zcl->type;
2258 regbase = zorro_resource_start(z) + zcl->regoffset;
2259 ramsize = zcl->ramsize;
2260 if (ramsize) {
2261 rambase = zorro_resource_start(z) + zcl->ramoffset;
e78bb882
GU
2262 if (zorro_resource_len(z) == 64 * MB_) {
2263 /* Quirk for 64 MiB Picasso IV */
2264 rambase += zcl->ramoffset;
2265 }
0e0d1336
GU
2266 } else {
2267 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2268 if (!ram || !zorro_resource_len(ram)) {
2269 dev_err(info->device, "No video RAM found\n");
2270 error = -ENODEV;
2271 goto err_release_fb;
2272 }
2273 rambase = zorro_resource_start(ram);
2274 ramsize = zorro_resource_len(ram);
17bdf489
GU
2275 if (zcl->ramid2 &&
2276 (ram = zorro_find_device(zcl->ramid2, NULL))) {
2277 if (zorro_resource_start(ram) != rambase + ramsize) {
2278 dev_warn(info->device,
2279 "Skipping non-contiguous RAM at %pR\n",
2280 &ram->resource);
2281 } else {
2282 ramsize += zorro_resource_len(ram);
2283 }
2284 }
0e0d1336 2285 }
1da177e4 2286
0e0d1336
GU
2287 dev_info(info->device,
2288 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2289 cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2290 rambase);
1da177e4
LT
2291
2292 if (!zorro_request_device(z, "cirrusfb")) {
0e0d1336
GU
2293 dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2294 error = -EBUSY;
1da177e4
LT
2295 goto err_release_fb;
2296 }
2297
0e0d1336
GU
2298 cinfo = info->par;
2299 cinfo->btype = btype;
1da177e4 2300
0e0d1336
GU
2301 info->fix.mmio_start = regbase;
2302 cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2303 : (caddr_t)ZTWO_VADDR(regbase);
2304 if (!cinfo->regbase) {
2305 dev_err(info->device, "Cannot map registers\n");
2306 error = -EIO;
2307 goto err_release_dev;
2308 }
1da177e4 2309
0e0d1336
GU
2310 info->fix.smem_start = rambase;
2311 info->screen_size = ramsize;
2312 info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2313 : (caddr_t)ZTWO_VADDR(rambase);
2314 if (!info->screen_base) {
2315 dev_err(info->device, "Cannot map video RAM\n");
2316 error = -EIO;
2317 goto err_unmap_reg;
1da177e4 2318 }
0e0d1336 2319
1da177e4
LT
2320 cinfo->unmap = cirrusfb_zorro_unmap;
2321
75ed3a17 2322 dev_info(info->device,
0e0d1336
GU
2323 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2324 ramsize / MB_, rambase);
1da177e4 2325
8f19e15b
KH
2326 /* MCLK select etc. */
2327 if (cirrusfb_board_info[btype].init_sr1f)
2328 vga_wseq(cinfo->regbase, CL_SEQR1F,
2329 cirrusfb_board_info[btype].sr1f);
2330
0e0d1336
GU
2331 error = cirrusfb_register(info);
2332 if (error) {
2333 dev_err(info->device, "Failed to register device, error %d\n",
2334 error);
2335 goto err_unmap_ram;
2336 }
bc5d8ac0 2337
0e0d1336
GU
2338 zorro_set_drvdata(z, info);
2339 return 0;
bc5d8ac0 2340
0e0d1336
GU
2341err_unmap_ram:
2342 if (rambase > 16 * MB_)
bc5d8ac0 2343 iounmap(info->screen_base);
1da177e4 2344
0e0d1336
GU
2345err_unmap_reg:
2346 if (regbase > 16 * MB_)
2347 iounmap(cinfo->regbase);
2348err_release_dev:
2349 zorro_release_device(z);
1da177e4
LT
2350err_release_fb:
2351 framebuffer_release(info);
0e0d1336 2352 return error;
1da177e4
LT
2353}
2354
2355void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2356{
2357 struct fb_info *info = zorro_get_drvdata(z);
1da177e4 2358
8503df65 2359 cirrusfb_cleanup(info);
0e0d1336 2360 zorro_set_drvdata(z, NULL);
1da177e4
LT
2361}
2362
2363static struct zorro_driver cirrusfb_zorro_driver = {
2364 .name = "cirrusfb",
2365 .id_table = cirrusfb_zorro_table,
2366 .probe = cirrusfb_zorro_register,
2367 .remove = __devexit_p(cirrusfb_zorro_unregister),
2368};
2369#endif /* CONFIG_ZORRO */
2370
1da177e4 2371#ifndef MODULE
75ed3a17
KH
2372static int __init cirrusfb_setup(char *options)
2373{
ee11940f 2374 char *this_opt;
1da177e4 2375
1da177e4
LT
2376 if (!options || !*options)
2377 return 0;
2378
8503df65 2379 while ((this_opt = strsep(&options, ",")) != NULL) {
a1d35a7a
KH
2380 if (!*this_opt)
2381 continue;
1da177e4 2382
1da177e4
LT
2383 if (!strcmp(this_opt, "noaccel"))
2384 noaccel = 1;
a1d35a7a
KH
2385 else if (!strncmp(this_opt, "mode:", 5))
2386 mode_option = this_opt + 5;
2387 else
2388 mode_option = this_opt;
1da177e4
LT
2389 }
2390 return 0;
2391}
2392#endif
2393
1da177e4
LT
2394 /*
2395 * Modularization
2396 */
2397
2398MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2399MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2400MODULE_LICENSE("GPL");
2401
48c329e9
KH
2402static int __init cirrusfb_init(void)
2403{
2404 int error = 0;
2405
2406#ifndef MODULE
2407 char *option = NULL;
2408
2409 if (fb_get_options("cirrusfb", &option))
2410 return -ENODEV;
2411 cirrusfb_setup(option);
2412#endif
2413
2414#ifdef CONFIG_ZORRO
2415 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2416#endif
2417#ifdef CONFIG_PCI
2418 error |= pci_register_driver(&cirrusfb_pci_driver);
2419#endif
2420 return error;
2421}
2422
8503df65 2423static void __exit cirrusfb_exit(void)
1da177e4
LT
2424{
2425#ifdef CONFIG_PCI
2426 pci_unregister_driver(&cirrusfb_pci_driver);
2427#endif
2428#ifdef CONFIG_ZORRO
2429 zorro_unregister_driver(&cirrusfb_zorro_driver);
2430#endif
2431}
2432
2433module_init(cirrusfb_init);
2434
a1d35a7a
KH
2435module_param(mode_option, charp, 0);
2436MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
55a0dd83
KH
2437module_param(noaccel, bool, 0);
2438MODULE_PARM_DESC(noaccel, "Disable acceleration");
a1d35a7a 2439
1da177e4
LT
2440#ifdef MODULE
2441module_exit(cirrusfb_exit);
2442#endif
2443
1da177e4
LT
2444/**********************************************************************/
2445/* about the following functions - I have used the same names for the */
2446/* functions as Markus Wild did in his Retina driver for NetBSD as */
2447/* they just made sense for this purpose. Apart from that, I wrote */
8503df65 2448/* these functions myself. */
1da177e4
LT
2449/**********************************************************************/
2450
2451/*** WGen() - write into one of the external/general registers ***/
8503df65 2452static void WGen(const struct cirrusfb_info *cinfo,
1da177e4
LT
2453 int regnum, unsigned char val)
2454{
2455 unsigned long regofs = 0;
2456
2457 if (cinfo->btype == BT_PICASSO) {
2458 /* Picasso II specific hack */
8503df65
KH
2459/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2460 regnum == CL_VSSM2) */
1da177e4
LT
2461 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2462 regofs = 0xfff;
2463 }
2464
8503df65 2465 vga_w(cinfo->regbase, regofs + regnum, val);
1da177e4
LT
2466}
2467
2468/*** RGen() - read out one of the external/general registers ***/
8503df65 2469static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
1da177e4
LT
2470{
2471 unsigned long regofs = 0;
2472
2473 if (cinfo->btype == BT_PICASSO) {
2474 /* Picasso II specific hack */
8503df65
KH
2475/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2476 regnum == CL_VSSM2) */
1da177e4
LT
2477 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2478 regofs = 0xfff;
2479 }
2480
8503df65 2481 return vga_r(cinfo->regbase, regofs + regnum);
1da177e4
LT
2482}
2483
2484/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
8503df65 2485static void AttrOn(const struct cirrusfb_info *cinfo)
1da177e4 2486{
8503df65 2487 assert(cinfo != NULL);
1da177e4 2488
8503df65 2489 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
1da177e4
LT
2490 /* if we're just in "write value" mode, write back the */
2491 /* same value as before to not modify anything */
8503df65
KH
2492 vga_w(cinfo->regbase, VGA_ATT_IW,
2493 vga_r(cinfo->regbase, VGA_ATT_R));
1da177e4
LT
2494 }
2495 /* turn on video bit */
8503df65
KH
2496/* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2497 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
1da177e4
LT
2498
2499 /* dummy write on Reg0 to be on "write index" mode next time */
8503df65 2500 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
1da177e4
LT
2501}
2502
2503/*** WHDR() - write into the Hidden DAC register ***/
2504/* as the HDR is the only extension register that requires special treatment
2505 * (the other extension registers are accessible just like the "ordinary"
2506 * registers of their functional group) here is a specialized routine for
2507 * accessing the HDR
2508 */
8503df65 2509static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
1da177e4
LT
2510{
2511 unsigned char dummy;
2512
78d780e0 2513 if (is_laguna(cinfo))
1b48cb56 2514 return;
1da177e4
LT
2515 if (cinfo->btype == BT_PICASSO) {
2516 /* Klaus' hint for correct access to HDR on some boards */
2517 /* first write 0 to pixel mask (3c6) */
8503df65
KH
2518 WGen(cinfo, VGA_PEL_MSK, 0x00);
2519 udelay(200);
1da177e4 2520 /* next read dummy from pixel address (3c8) */
8503df65
KH
2521 dummy = RGen(cinfo, VGA_PEL_IW);
2522 udelay(200);
1da177e4
LT
2523 }
2524 /* now do the usual stuff to access the HDR */
2525
8503df65
KH
2526 dummy = RGen(cinfo, VGA_PEL_MSK);
2527 udelay(200);
2528 dummy = RGen(cinfo, VGA_PEL_MSK);
2529 udelay(200);
2530 dummy = RGen(cinfo, VGA_PEL_MSK);
2531 udelay(200);
2532 dummy = RGen(cinfo, VGA_PEL_MSK);
2533 udelay(200);
1da177e4 2534
8503df65
KH
2535 WGen(cinfo, VGA_PEL_MSK, val);
2536 udelay(200);
1da177e4
LT
2537
2538 if (cinfo->btype == BT_PICASSO) {
2539 /* now first reset HDR access counter */
8503df65
KH
2540 dummy = RGen(cinfo, VGA_PEL_IW);
2541 udelay(200);
1da177e4
LT
2542
2543 /* and at the end, restore the mask value */
2544 /* ## is this mask always 0xff? */
8503df65
KH
2545 WGen(cinfo, VGA_PEL_MSK, 0xff);
2546 udelay(200);
1da177e4
LT
2547 }
2548}
2549
1da177e4 2550/*** WSFR() - write to the "special function register" (SFR) ***/
8503df65 2551static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
1da177e4
LT
2552{
2553#ifdef CONFIG_ZORRO
8503df65 2554 assert(cinfo->regbase != NULL);
1da177e4 2555 cinfo->SFR = val;
8503df65 2556 z_writeb(val, cinfo->regbase + 0x8000);
1da177e4
LT
2557#endif
2558}
2559
2560/* The Picasso has a second register for switching the monitor bit */
8503df65 2561static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
1da177e4
LT
2562{
2563#ifdef CONFIG_ZORRO
2564 /* writing an arbitrary value to this one causes the monitor switcher */
2565 /* to flip to Amiga display */
8503df65 2566 assert(cinfo->regbase != NULL);
1da177e4 2567 cinfo->SFR = val;
8503df65 2568 z_writeb(val, cinfo->regbase + 0x9000);
1da177e4
LT
2569#endif
2570}
2571
1da177e4 2572/*** WClut - set CLUT entry (range: 0..63) ***/
8503df65 2573static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
1da177e4
LT
2574 unsigned char green, unsigned char blue)
2575{
2576 unsigned int data = VGA_PEL_D;
2577
2578 /* address write mode register is not translated.. */
8503df65 2579 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
1da177e4
LT
2580
2581 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
1b48cb56 2582 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
df3aafd5 2583 cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
1da177e4
LT
2584 /* but DAC data register IS, at least for Picasso II */
2585 if (cinfo->btype == BT_PICASSO)
2586 data += 0xfff;
8503df65
KH
2587 vga_w(cinfo->regbase, data, red);
2588 vga_w(cinfo->regbase, data, green);
2589 vga_w(cinfo->regbase, data, blue);
1da177e4 2590 } else {
8503df65
KH
2591 vga_w(cinfo->regbase, data, blue);
2592 vga_w(cinfo->regbase, data, green);
2593 vga_w(cinfo->regbase, data, red);
1da177e4
LT
2594 }
2595}
2596
1da177e4
LT
2597#if 0
2598/*** RClut - read CLUT entry (range 0..63) ***/
8503df65 2599static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
1da177e4
LT
2600 unsigned char *green, unsigned char *blue)
2601{
2602 unsigned int data = VGA_PEL_D;
2603
8503df65 2604 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
1da177e4
LT
2605
2606 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2607 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2608 if (cinfo->btype == BT_PICASSO)
2609 data += 0xfff;
8503df65
KH
2610 *red = vga_r(cinfo->regbase, data);
2611 *green = vga_r(cinfo->regbase, data);
2612 *blue = vga_r(cinfo->regbase, data);
1da177e4 2613 } else {
8503df65
KH
2614 *blue = vga_r(cinfo->regbase, data);
2615 *green = vga_r(cinfo->regbase, data);
2616 *red = vga_r(cinfo->regbase, data);
1da177e4
LT
2617 }
2618}
2619#endif
2620
1da177e4
LT
2621/*******************************************************************
2622 cirrusfb_WaitBLT()
2623
2624 Wait for the BitBLT engine to complete a possible earlier job
2625*********************************************************************/
2626
2627/* FIXME: use interrupts instead */
8503df65 2628static void cirrusfb_WaitBLT(u8 __iomem *regbase)
1da177e4 2629{
8503df65 2630 while (vga_rgfx(regbase, CL_GR31) & 0x08)
48c329e9 2631 cpu_relax();
1da177e4
LT
2632}
2633
2634/*******************************************************************
2635 cirrusfb_BitBLT()
2636
2637 perform accelerated "scrolling"
2638********************************************************************/
2639
8343c89c
KH
2640static void cirrusfb_set_blitter(u8 __iomem *regbase,
2641 u_short nwidth, u_short nheight,
2642 u_long nsrc, u_long ndest,
2643 u_short bltmode, u_short line_length)
1da177e4 2644
8343c89c 2645{
1da177e4 2646 /* pitch: set to line_length */
8503df65
KH
2647 /* dest pitch low */
2648 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2649 /* dest pitch hi */
2650 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2651 /* source pitch low */
2652 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2653 /* source pitch hi */
2654 vga_wgfx(regbase, CL_GR27, line_length >> 8);
1da177e4
LT
2655
2656 /* BLT width: actual number of pixels - 1 */
8503df65
KH
2657 /* BLT width low */
2658 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2659 /* BLT width hi */
2660 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
1da177e4
LT
2661
2662 /* BLT height: actual number of lines -1 */
8503df65
KH
2663 /* BLT height low */
2664 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2665 /* BLT width hi */
2666 vga_wgfx(regbase, CL_GR23, nheight >> 8);
1da177e4
LT
2667
2668 /* BLT destination */
8503df65
KH
2669 /* BLT dest low */
2670 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2671 /* BLT dest mid */
2672 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2673 /* BLT dest hi */
2674 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
1da177e4
LT
2675
2676 /* BLT source */
8503df65
KH
2677 /* BLT src low */
2678 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2679 /* BLT src mid */
2680 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2681 /* BLT src hi */
2682 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
1da177e4
LT
2683
2684 /* BLT mode */
8503df65 2685 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
1da177e4
LT
2686
2687 /* BLT ROP: SrcCopy */
8503df65 2688 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
1da177e4
LT
2689
2690 /* and finally: GO! */
527410ff 2691 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
1da177e4
LT
2692}
2693
1da177e4 2694/*******************************************************************
8343c89c 2695 cirrusfb_BitBLT()
1da177e4 2696
8343c89c 2697 perform accelerated "scrolling"
1da177e4
LT
2698********************************************************************/
2699
8343c89c
KH
2700static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2701 u_short curx, u_short cury,
2702 u_short destx, u_short desty,
2703 u_short width, u_short height,
2704 u_short line_length)
1da177e4 2705{
8343c89c
KH
2706 u_short nwidth = width - 1;
2707 u_short nheight = height - 1;
2708 u_long nsrc, ndest;
2709 u_char bltmode;
1da177e4 2710
8343c89c
KH
2711 bltmode = 0x00;
2712 /* if source adr < dest addr, do the Blt backwards */
2713 if (cury <= desty) {
2714 if (cury == desty) {
2715 /* if src and dest are on the same line, check x */
2716 if (curx < destx)
2717 bltmode |= 0x01;
2718 } else
2719 bltmode |= 0x01;
2720 }
2721 /* standard case: forward blitting */
2722 nsrc = (cury * line_length) + curx;
2723 ndest = (desty * line_length) + destx;
2724 if (bltmode) {
2725 /* this means start addresses are at the end,
2726 * counting backwards
2727 */
2728 nsrc += nheight * line_length + nwidth;
2729 ndest += nheight * line_length + nwidth;
2730 }
1da177e4 2731
8503df65 2732 cirrusfb_WaitBLT(regbase);
1da177e4 2733
8343c89c
KH
2734 cirrusfb_set_blitter(regbase, nwidth, nheight,
2735 nsrc, ndest, bltmode, line_length);
2736}
1da177e4 2737
8343c89c
KH
2738/*******************************************************************
2739 cirrusfb_RectFill()
1da177e4 2740
8343c89c
KH
2741 perform accelerated rectangle fill
2742********************************************************************/
1da177e4 2743
8343c89c
KH
2744static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2745 u_short x, u_short y, u_short width, u_short height,
9e848062
KH
2746 u32 fg_color, u32 bg_color, u_short line_length,
2747 u_char blitmode)
8343c89c
KH
2748{
2749 u_long ndest = (y * line_length) + x;
2750 u_char op;
1da177e4 2751
8343c89c 2752 cirrusfb_WaitBLT(regbase);
1da177e4
LT
2753
2754 /* This is a ColorExpand Blt, using the */
2755 /* same color for foreground and background */
9e848062
KH
2756 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2757 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
1da177e4 2758
9e848062 2759 op = 0x80;
8343c89c 2760 if (bits_per_pixel >= 16) {
9e848062
KH
2761 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2762 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2763 op = 0x90;
8343c89c 2764 }
7cade31c 2765 if (bits_per_pixel >= 24) {
9e848062
KH
2766 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2767 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
7cade31c
KH
2768 op = 0xa0;
2769 }
2770 if (bits_per_pixel == 32) {
9e848062
KH
2771 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2772 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2773 op = 0xb0;
1da177e4 2774 }
8343c89c 2775 cirrusfb_set_blitter(regbase, width - 1, height - 1,
9e848062 2776 0, ndest, op | blitmode, line_length);
1da177e4
LT
2777}
2778
1da177e4
LT
2779/**************************************************************************
2780 * bestclock() - determine closest possible clock lower(?) than the
2781 * desired pixel clock
2782 **************************************************************************/
dafa32c5 2783static void bestclock(long freq, int *nom, int *den, int *div)
1da177e4 2784{
dafa32c5
KH
2785 int n, d;
2786 long h, diff;
1da177e4 2787
8503df65
KH
2788 assert(nom != NULL);
2789 assert(den != NULL);
2790 assert(div != NULL);
1da177e4
LT
2791
2792 *nom = 0;
2793 *den = 0;
2794 *div = 0;
2795
1da177e4
LT
2796 if (freq < 8000)
2797 freq = 8000;
2798
dafa32c5 2799 diff = freq;
1da177e4
LT
2800
2801 for (n = 32; n < 128; n++) {
7528f543
KH
2802 int s = 0;
2803
dafa32c5 2804 d = (14318 * n) / freq;
1da177e4 2805 if ((d >= 7) && (d <= 63)) {
7528f543
KH
2806 int temp = d;
2807
2808 if (temp > 31) {
2809 s = 1;
2810 temp >>= 1;
2811 }
2812 h = ((14318 * n) / temp) >> s;
dafa32c5
KH
2813 h = h > freq ? h - freq : freq - h;
2814 if (h < diff) {
2815 diff = h;
1da177e4 2816 *nom = n;
7528f543
KH
2817 *den = temp;
2818 *div = s;
1da177e4
LT
2819 }
2820 }
7528f543 2821 d++;
1da177e4 2822 if ((d >= 7) && (d <= 63)) {
7528f543
KH
2823 if (d > 31) {
2824 s = 1;
2825 d >>= 1;
2826 }
2827 h = ((14318 * n) / d) >> s;
dafa32c5
KH
2828 h = h > freq ? h - freq : freq - h;
2829 if (h < diff) {
2830 diff = h;
1da177e4 2831 *nom = n;
7528f543
KH
2832 *den = d;
2833 *div = s;
1da177e4
LT
2834 }
2835 }
2836 }
1da177e4
LT
2837}
2838
1da177e4
LT
2839/* -------------------------------------------------------------------------
2840 *
2841 * debugging functions
2842 *
2843 * -------------------------------------------------------------------------
2844 */
2845
2846#ifdef CIRRUSFB_DEBUG
2847
1da177e4
LT
2848/**
2849 * cirrusfb_dbg_print_regs
2850 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2851 * @reg_class: type of registers to read: %CRT, or %SEQ
2852 *
2853 * DESCRIPTION:
2854 * Dumps the given list of VGA CRTC registers. If @base is %NULL,
2855 * old-style I/O ports are queried for information, otherwise MMIO is
2856 * used at the given @base address to query the information.
2857 */
2858
75ed3a17
KH
2859static void cirrusfb_dbg_print_regs(struct fb_info *info,
2860 caddr_t regbase,
2861 enum cirrusfb_dbg_reg_class reg_class, ...)
1da177e4
LT
2862{
2863 va_list list;
2864 unsigned char val = 0;
2865 unsigned reg;
2866 char *name;
2867
8503df65 2868 va_start(list, reg_class);
1da177e4 2869
8503df65 2870 name = va_arg(list, char *);
1da177e4 2871 while (name != NULL) {
8503df65 2872 reg = va_arg(list, int);
1da177e4
LT
2873
2874 switch (reg_class) {
2875 case CRT:
8503df65 2876 val = vga_rcrt(regbase, (unsigned char) reg);
1da177e4
LT
2877 break;
2878 case SEQ:
8503df65 2879 val = vga_rseq(regbase, (unsigned char) reg);
1da177e4
LT
2880 break;
2881 default:
2882 /* should never occur */
c930faae 2883 assert(false);
1da177e4
LT
2884 break;
2885 }
2886
75ed3a17 2887 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
1da177e4 2888
8503df65 2889 name = va_arg(list, char *);
1da177e4
LT
2890 }
2891
8503df65 2892 va_end(list);
1da177e4
LT
2893}
2894
1da177e4
LT
2895/**
2896 * cirrusfb_dbg_reg_dump
2897 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2898 *
2899 * DESCRIPTION:
2900 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL,
2901 * old-style I/O ports are queried for information, otherwise MMIO is
2902 * used at the given @base address to query the information.
2903 */
2904
75ed3a17 2905static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
1da177e4 2906{
75ed3a17 2907 dev_dbg(info->device, "VGA CRTC register dump:\n");
1da177e4 2908
75ed3a17 2909 cirrusfb_dbg_print_regs(info, regbase, CRT,
1da177e4
LT
2910 "CR00", 0x00,
2911 "CR01", 0x01,
2912 "CR02", 0x02,
2913 "CR03", 0x03,
2914 "CR04", 0x04,
2915 "CR05", 0x05,
2916 "CR06", 0x06,
2917 "CR07", 0x07,
2918 "CR08", 0x08,
2919 "CR09", 0x09,
2920 "CR0A", 0x0A,
2921 "CR0B", 0x0B,
2922 "CR0C", 0x0C,
2923 "CR0D", 0x0D,
2924 "CR0E", 0x0E,
2925 "CR0F", 0x0F,
2926 "CR10", 0x10,
2927 "CR11", 0x11,
2928 "CR12", 0x12,
2929 "CR13", 0x13,
2930 "CR14", 0x14,
2931 "CR15", 0x15,
2932 "CR16", 0x16,
2933 "CR17", 0x17,
2934 "CR18", 0x18,
2935 "CR22", 0x22,
2936 "CR24", 0x24,
2937 "CR26", 0x26,
2938 "CR2D", 0x2D,
2939 "CR2E", 0x2E,
2940 "CR2F", 0x2F,
2941 "CR30", 0x30,
2942 "CR31", 0x31,
2943 "CR32", 0x32,
2944 "CR33", 0x33,
2945 "CR34", 0x34,
2946 "CR35", 0x35,
2947 "CR36", 0x36,
2948 "CR37", 0x37,
2949 "CR38", 0x38,
2950 "CR39", 0x39,
2951 "CR3A", 0x3A,
2952 "CR3B", 0x3B,
2953 "CR3C", 0x3C,
2954 "CR3D", 0x3D,
2955 "CR3E", 0x3E,
2956 "CR3F", 0x3F,
2957 NULL);
2958
75ed3a17 2959 dev_dbg(info->device, "\n");
1da177e4 2960
75ed3a17 2961 dev_dbg(info->device, "VGA SEQ register dump:\n");
1da177e4 2962
75ed3a17 2963 cirrusfb_dbg_print_regs(info, regbase, SEQ,
1da177e4
LT
2964 "SR00", 0x00,
2965 "SR01", 0x01,
2966 "SR02", 0x02,
2967 "SR03", 0x03,
2968 "SR04", 0x04,
2969 "SR08", 0x08,
2970 "SR09", 0x09,
2971 "SR0A", 0x0A,
2972 "SR0B", 0x0B,
2973 "SR0D", 0x0D,
2974 "SR10", 0x10,
2975 "SR11", 0x11,
2976 "SR12", 0x12,
2977 "SR13", 0x13,
2978 "SR14", 0x14,
2979 "SR15", 0x15,
2980 "SR16", 0x16,
2981 "SR17", 0x17,
2982 "SR18", 0x18,
2983 "SR19", 0x19,
2984 "SR1A", 0x1A,
2985 "SR1B", 0x1B,
2986 "SR1C", 0x1C,
2987 "SR1D", 0x1D,
2988 "SR1E", 0x1E,
2989 "SR1F", 0x1F,
2990 NULL);
2991
75ed3a17 2992 dev_dbg(info->device, "\n");
1da177e4
LT
2993}
2994
2995#endif /* CIRRUSFB_DEBUG */
2996
This page took 0.870498 seconds and 5 git commands to generate.