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