1 /* 2 * linux/drivers/video/s3fb.c -- Frame buffer device driver for S3 Trio/Virge 3 * 4 * Copyright (c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org> 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive for 8 * more details. 9 * 10 * Code is based on David Boucher's viafb (http://davesdomain.org.uk/viafb/) 11 * which is based on the code of neofb. 12 */ 13 14 #include <linux/aperture.h> 15 #include <linux/module.h> 16 #include <linux/kernel.h> 17 #include <linux/errno.h> 18 #include <linux/string.h> 19 #include <linux/mm.h> 20 #include <linux/tty.h> 21 #include <linux/delay.h> 22 #include <linux/fb.h> 23 #include <linux/svga.h> 24 #include <linux/init.h> 25 #include <linux/pci.h> 26 #include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */ 27 #include <video/vga.h> 28 29 #include <linux/i2c.h> 30 #include <linux/i2c-algo-bit.h> 31 32 struct s3fb_info { 33 int chip, rev, mclk_freq; 34 int wc_cookie; 35 struct vgastate state; 36 struct mutex open_lock; 37 unsigned int ref_count; 38 u32 pseudo_palette[16]; 39 #ifdef CONFIG_FB_S3_DDC 40 u8 __iomem *mmio; 41 bool ddc_registered; 42 struct i2c_adapter ddc_adapter; 43 struct i2c_algo_bit_data ddc_algo; 44 #endif 45 }; 46 47 48 /* ------------------------------------------------------------------------- */ 49 50 static const struct svga_fb_format s3fb_formats[] = { 51 { 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, 52 FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16}, 53 { 1, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0}, 2, 54 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 32, 64}, 55 { 2, {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, 2, 56 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 16, 32}, 57 { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 1, 58 FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16}, 59 { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 2, 60 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16}, 61 { 8, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0, 62 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8}, 63 {16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0, 64 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4}, 65 {16, {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 0, 66 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4}, 67 {24, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0, 68 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 1, 2}, 69 {32, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0, 70 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 1, 2}, 71 SVGA_FORMAT_END 72 }; 73 74 75 static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 76 35000, 240000, 14318}; 77 static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4, 78 230000, 460000, 14318}; 79 80 static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 81 82 static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+", 83 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX", 84 "S3 Plato/PX", "S3 Aurora64V+", "S3 Virge", 85 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 86 "S3 Virge/GX2", "S3 Virge/GX2+", "", 87 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", 88 "S3 Trio3D", "S3 Virge/MX"}; 89 90 #define CHIP_UNKNOWN 0x00 91 #define CHIP_732_TRIO32 0x01 92 #define CHIP_764_TRIO64 0x02 93 #define CHIP_765_TRIO64VP 0x03 94 #define CHIP_767_TRIO64UVP 0x04 95 #define CHIP_775_TRIO64V2_DX 0x05 96 #define CHIP_785_TRIO64V2_GX 0x06 97 #define CHIP_551_PLATO_PX 0x07 98 #define CHIP_M65_AURORA64VP 0x08 99 #define CHIP_325_VIRGE 0x09 100 #define CHIP_988_VIRGE_VX 0x0A 101 #define CHIP_375_VIRGE_DX 0x0B 102 #define CHIP_385_VIRGE_GX 0x0C 103 #define CHIP_357_VIRGE_GX2 0x0D 104 #define CHIP_359_VIRGE_GX2P 0x0E 105 #define CHIP_360_TRIO3D_1X 0x10 106 #define CHIP_362_TRIO3D_2X 0x11 107 #define CHIP_368_TRIO3D_2X 0x12 108 #define CHIP_365_TRIO3D 0x13 109 #define CHIP_260_VIRGE_MX 0x14 110 111 #define CHIP_XXX_TRIO 0x80 112 #define CHIP_XXX_TRIO64V2_DXGX 0x81 113 #define CHIP_XXX_VIRGE_DXGX 0x82 114 #define CHIP_36X_TRIO3D_1X_2X 0x83 115 116 #define CHIP_UNDECIDED_FLAG 0x80 117 #define CHIP_MASK 0xFF 118 119 #define MMIO_OFFSET 0x1000000 120 #define MMIO_SIZE 0x10000 121 122 /* CRT timing register sets */ 123 124 static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END}; 125 static const struct vga_regset s3_h_display_regs[] = {{0x01, 0, 7}, {0x5D, 1, 1}, VGA_REGSET_END}; 126 static const struct vga_regset s3_h_blank_start_regs[] = {{0x02, 0, 7}, {0x5D, 2, 2}, VGA_REGSET_END}; 127 static const struct vga_regset s3_h_blank_end_regs[] = {{0x03, 0, 4}, {0x05, 7, 7}, VGA_REGSET_END}; 128 static const struct vga_regset s3_h_sync_start_regs[] = {{0x04, 0, 7}, {0x5D, 4, 4}, VGA_REGSET_END}; 129 static const struct vga_regset s3_h_sync_end_regs[] = {{0x05, 0, 4}, VGA_REGSET_END}; 130 131 static const struct vga_regset s3_v_total_regs[] = {{0x06, 0, 7}, {0x07, 0, 0}, {0x07, 5, 5}, {0x5E, 0, 0}, VGA_REGSET_END}; 132 static const struct vga_regset s3_v_display_regs[] = {{0x12, 0, 7}, {0x07, 1, 1}, {0x07, 6, 6}, {0x5E, 1, 1}, VGA_REGSET_END}; 133 static const struct vga_regset s3_v_blank_start_regs[] = {{0x15, 0, 7}, {0x07, 3, 3}, {0x09, 5, 5}, {0x5E, 2, 2}, VGA_REGSET_END}; 134 static const struct vga_regset s3_v_blank_end_regs[] = {{0x16, 0, 7}, VGA_REGSET_END}; 135 static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, 2, 2}, {0x07, 7, 7}, {0x5E, 4, 4}, VGA_REGSET_END}; 136 static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 137 138 static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; 139 static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END}; 140 static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 141 142 static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END}; 143 144 static const struct svga_timing_regs s3_timing_regs = { 145 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 146 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 147 s3_v_total_regs, s3_v_display_regs, s3_v_blank_start_regs, 148 s3_v_blank_end_regs, s3_v_sync_start_regs, s3_v_sync_end_regs, 149 }; 150 151 152 /* ------------------------------------------------------------------------- */ 153 154 /* Module parameters */ 155 156 157 static char *mode_option; 158 static int mtrr = 1; 159 static int fasttext = 1; 160 161 162 MODULE_AUTHOR("(c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>"); 163 MODULE_LICENSE("GPL"); 164 MODULE_DESCRIPTION("fbdev driver for S3 Trio/Virge"); 165 166 module_param(mode_option, charp, 0444); 167 MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)"); 168 module_param_named(mode, mode_option, charp, 0444); 169 MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)"); 170 module_param(mtrr, int, 0444); 171 MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)"); 172 173 module_param(fasttext, int, 0644); 174 MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, default=1)"); 175 176 177 /* ------------------------------------------------------------------------- */ 178 179 #ifdef CONFIG_FB_S3_DDC 180 181 #define DDC_REG 0xaa /* Trio 3D/1X/2X */ 182 #define DDC_MMIO_REG 0xff20 /* all other chips */ 183 #define DDC_SCL_OUT (1 << 0) 184 #define DDC_SDA_OUT (1 << 1) 185 #define DDC_SCL_IN (1 << 2) 186 #define DDC_SDA_IN (1 << 3) 187 #define DDC_DRIVE_EN (1 << 4) 188 189 static bool s3fb_ddc_needs_mmio(int chip) 190 { 191 return !(chip == CHIP_360_TRIO3D_1X || 192 chip == CHIP_362_TRIO3D_2X || 193 chip == CHIP_368_TRIO3D_2X); 194 } 195 196 static u8 s3fb_ddc_read(struct s3fb_info *par) 197 { 198 if (s3fb_ddc_needs_mmio(par->chip)) 199 return readb(par->mmio + DDC_MMIO_REG); 200 else 201 return vga_rcrt(par->state.vgabase, DDC_REG); 202 } 203 204 static void s3fb_ddc_write(struct s3fb_info *par, u8 val) 205 { 206 if (s3fb_ddc_needs_mmio(par->chip)) 207 writeb(val, par->mmio + DDC_MMIO_REG); 208 else 209 vga_wcrt(par->state.vgabase, DDC_REG, val); 210 } 211 212 static void s3fb_ddc_setscl(void *data, int val) 213 { 214 struct s3fb_info *par = data; 215 unsigned char reg; 216 217 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN; 218 if (val) 219 reg |= DDC_SCL_OUT; 220 else 221 reg &= ~DDC_SCL_OUT; 222 s3fb_ddc_write(par, reg); 223 } 224 225 static void s3fb_ddc_setsda(void *data, int val) 226 { 227 struct s3fb_info *par = data; 228 unsigned char reg; 229 230 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN; 231 if (val) 232 reg |= DDC_SDA_OUT; 233 else 234 reg &= ~DDC_SDA_OUT; 235 s3fb_ddc_write(par, reg); 236 } 237 238 static int s3fb_ddc_getscl(void *data) 239 { 240 struct s3fb_info *par = data; 241 242 return !!(s3fb_ddc_read(par) & DDC_SCL_IN); 243 } 244 245 static int s3fb_ddc_getsda(void *data) 246 { 247 struct s3fb_info *par = data; 248 249 return !!(s3fb_ddc_read(par) & DDC_SDA_IN); 250 } 251 252 static int s3fb_setup_ddc_bus(struct fb_info *info) 253 { 254 struct s3fb_info *par = info->par; 255 256 strscpy(par->ddc_adapter.name, info->fix.id, 257 sizeof(par->ddc_adapter.name)); 258 par->ddc_adapter.owner = THIS_MODULE; 259 par->ddc_adapter.algo_data = &par->ddc_algo; 260 par->ddc_adapter.dev.parent = info->device; 261 par->ddc_algo.setsda = s3fb_ddc_setsda; 262 par->ddc_algo.setscl = s3fb_ddc_setscl; 263 par->ddc_algo.getsda = s3fb_ddc_getsda; 264 par->ddc_algo.getscl = s3fb_ddc_getscl; 265 par->ddc_algo.udelay = 10; 266 par->ddc_algo.timeout = 20; 267 par->ddc_algo.data = par; 268 269 i2c_set_adapdata(&par->ddc_adapter, par); 270 271 /* 272 * some Virge cards have external MUX to switch chip I2C bus between 273 * DDC and extension pins - switch it do DDC 274 */ 275 /* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */ 276 if (par->chip == CHIP_357_VIRGE_GX2 || 277 par->chip == CHIP_359_VIRGE_GX2P || 278 par->chip == CHIP_260_VIRGE_MX) 279 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03); 280 else 281 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03); 282 /* some Virge need this or the DDC is ignored */ 283 svga_wcrt_mask(par->state.vgabase, 0x5c, 0x03, 0x03); 284 285 return i2c_bit_add_bus(&par->ddc_adapter); 286 } 287 #endif /* CONFIG_FB_S3_DDC */ 288 289 290 /* ------------------------------------------------------------------------- */ 291 292 /* Set font in S3 fast text mode */ 293 294 static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) 295 { 296 const u8 *font = map->data; 297 u8 __iomem *fb = (u8 __iomem *) info->screen_base; 298 int i, c; 299 300 if ((map->width != 8) || (map->height != 16) || 301 (map->depth != 1) || (map->length != 256)) { 302 fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n", 303 map->width, map->height, map->depth, map->length); 304 return; 305 } 306 307 fb += 2; 308 for (i = 0; i < map->height; i++) { 309 for (c = 0; c < map->length; c++) { 310 fb_writeb(font[c * map->height + i], fb + c * 4); 311 } 312 fb += 1024; 313 } 314 } 315 316 static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) 317 { 318 struct s3fb_info *par = info->par; 319 320 svga_tilecursor(par->state.vgabase, info, cursor); 321 } 322 323 static struct fb_tile_ops s3fb_tile_ops = { 324 .fb_settile = svga_settile, 325 .fb_tilecopy = svga_tilecopy, 326 .fb_tilefill = svga_tilefill, 327 .fb_tileblit = svga_tileblit, 328 .fb_tilecursor = s3fb_tilecursor, 329 .fb_get_tilemax = svga_get_tilemax, 330 }; 331 332 static struct fb_tile_ops s3fb_fast_tile_ops = { 333 .fb_settile = s3fb_settile_fast, 334 .fb_tilecopy = svga_tilecopy, 335 .fb_tilefill = svga_tilefill, 336 .fb_tileblit = svga_tileblit, 337 .fb_tilecursor = s3fb_tilecursor, 338 .fb_get_tilemax = svga_get_tilemax, 339 }; 340 341 342 /* ------------------------------------------------------------------------- */ 343 344 /* image data is MSB-first, fb structure is MSB-first too */ 345 static inline u32 expand_color(u32 c) 346 { 347 return ((c & 1) | ((c & 2) << 7) | ((c & 4) << 14) | ((c & 8) << 21)) * 0xFF; 348 } 349 350 /* s3fb_iplan_imageblit silently assumes that almost everything is 8-pixel aligned */ 351 static void s3fb_iplan_imageblit(struct fb_info *info, const struct fb_image *image) 352 { 353 u32 fg = expand_color(image->fg_color); 354 u32 bg = expand_color(image->bg_color); 355 const u8 *src1, *src; 356 u8 __iomem *dst1; 357 u32 __iomem *dst; 358 u32 val; 359 int x, y; 360 361 src1 = image->data; 362 dst1 = info->screen_base + (image->dy * info->fix.line_length) 363 + ((image->dx / 8) * 4); 364 365 for (y = 0; y < image->height; y++) { 366 src = src1; 367 dst = (u32 __iomem *) dst1; 368 for (x = 0; x < image->width; x += 8) { 369 val = *(src++) * 0x01010101; 370 val = (val & fg) | (~val & bg); 371 fb_writel(val, dst++); 372 } 373 src1 += image->width / 8; 374 dst1 += info->fix.line_length; 375 } 376 377 } 378 379 /* s3fb_iplan_fillrect silently assumes that almost everything is 8-pixel aligned */ 380 static void s3fb_iplan_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 381 { 382 u32 fg = expand_color(rect->color); 383 u8 __iomem *dst1; 384 u32 __iomem *dst; 385 int x, y; 386 387 dst1 = info->screen_base + (rect->dy * info->fix.line_length) 388 + ((rect->dx / 8) * 4); 389 390 for (y = 0; y < rect->height; y++) { 391 dst = (u32 __iomem *) dst1; 392 for (x = 0; x < rect->width; x += 8) { 393 fb_writel(fg, dst++); 394 } 395 dst1 += info->fix.line_length; 396 } 397 } 398 399 400 /* image data is MSB-first, fb structure is high-nibble-in-low-byte-first */ 401 static inline u32 expand_pixel(u32 c) 402 { 403 return (((c & 1) << 24) | ((c & 2) << 27) | ((c & 4) << 14) | ((c & 8) << 17) | 404 ((c & 16) << 4) | ((c & 32) << 7) | ((c & 64) >> 6) | ((c & 128) >> 3)) * 0xF; 405 } 406 407 /* s3fb_cfb4_imageblit silently assumes that almost everything is 8-pixel aligned */ 408 static void s3fb_cfb4_imageblit(struct fb_info *info, const struct fb_image *image) 409 { 410 u32 fg = image->fg_color * 0x11111111; 411 u32 bg = image->bg_color * 0x11111111; 412 const u8 *src1, *src; 413 u8 __iomem *dst1; 414 u32 __iomem *dst; 415 u32 val; 416 int x, y; 417 418 src1 = image->data; 419 dst1 = info->screen_base + (image->dy * info->fix.line_length) 420 + ((image->dx / 8) * 4); 421 422 for (y = 0; y < image->height; y++) { 423 src = src1; 424 dst = (u32 __iomem *) dst1; 425 for (x = 0; x < image->width; x += 8) { 426 val = expand_pixel(*(src++)); 427 val = (val & fg) | (~val & bg); 428 fb_writel(val, dst++); 429 } 430 src1 += image->width / 8; 431 dst1 += info->fix.line_length; 432 } 433 } 434 435 static void s3fb_imageblit(struct fb_info *info, const struct fb_image *image) 436 { 437 if ((info->var.bits_per_pixel == 4) && (image->depth == 1) 438 && ((image->width % 8) == 0) && ((image->dx % 8) == 0)) { 439 if (info->fix.type == FB_TYPE_INTERLEAVED_PLANES) 440 s3fb_iplan_imageblit(info, image); 441 else 442 s3fb_cfb4_imageblit(info, image); 443 } else 444 cfb_imageblit(info, image); 445 } 446 447 static void s3fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 448 { 449 if ((info->var.bits_per_pixel == 4) 450 && ((rect->width % 8) == 0) && ((rect->dx % 8) == 0) 451 && (info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) 452 s3fb_iplan_fillrect(info, rect); 453 else 454 cfb_fillrect(info, rect); 455 } 456 457 458 459 /* ------------------------------------------------------------------------- */ 460 461 462 static void s3_set_pixclock(struct fb_info *info, u32 pixclock) 463 { 464 struct s3fb_info *par = info->par; 465 u16 m, n, r; 466 u8 regval; 467 int rv; 468 469 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll, 470 1000000000 / pixclock, &m, &n, &r, info->node); 471 if (rv < 0) { 472 fb_err(info, "cannot set requested pixclock, keeping old value\n"); 473 return; 474 } 475 476 /* Set VGA misc register */ 477 regval = vga_r(par->state.vgabase, VGA_MIS_R); 478 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 479 480 /* Set S3 clock registers */ 481 if (par->chip == CHIP_357_VIRGE_GX2 || 482 par->chip == CHIP_359_VIRGE_GX2P || 483 par->chip == CHIP_360_TRIO3D_1X || 484 par->chip == CHIP_362_TRIO3D_2X || 485 par->chip == CHIP_368_TRIO3D_2X || 486 par->chip == CHIP_260_VIRGE_MX) { 487 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 488 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ 489 } else 490 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5)); 491 vga_wseq(par->state.vgabase, 0x13, m - 2); 492 493 udelay(1000); 494 495 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ 496 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */ 497 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); 498 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5)); 499 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); 500 } 501 502 503 /* Open framebuffer */ 504 505 static int s3fb_open(struct fb_info *info, int user) 506 { 507 struct s3fb_info *par = info->par; 508 509 mutex_lock(&(par->open_lock)); 510 if (par->ref_count == 0) { 511 void __iomem *vgabase = par->state.vgabase; 512 513 memset(&(par->state), 0, sizeof(struct vgastate)); 514 par->state.vgabase = vgabase; 515 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 516 par->state.num_crtc = 0x70; 517 par->state.num_seq = 0x20; 518 save_vga(&(par->state)); 519 } 520 521 par->ref_count++; 522 mutex_unlock(&(par->open_lock)); 523 524 return 0; 525 } 526 527 /* Close framebuffer */ 528 529 static int s3fb_release(struct fb_info *info, int user) 530 { 531 struct s3fb_info *par = info->par; 532 533 mutex_lock(&(par->open_lock)); 534 if (par->ref_count == 0) { 535 mutex_unlock(&(par->open_lock)); 536 return -EINVAL; 537 } 538 539 if (par->ref_count == 1) 540 restore_vga(&(par->state)); 541 542 par->ref_count--; 543 mutex_unlock(&(par->open_lock)); 544 545 return 0; 546 } 547 548 /* Validate passed in var */ 549 550 static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 551 { 552 struct s3fb_info *par = info->par; 553 int rv, mem, step; 554 u16 m, n, r; 555 556 if (!var->pixclock) 557 return -EINVAL; 558 559 /* Find appropriate format */ 560 rv = svga_match_format (s3fb_formats, var, NULL); 561 562 /* 32bpp mode is not supported on VIRGE VX, 563 24bpp is not supported on others */ 564 if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 9) : (rv == 8)) 565 rv = -EINVAL; 566 567 if (rv < 0) { 568 fb_err(info, "unsupported mode requested\n"); 569 return rv; 570 } 571 572 /* Do not allow to have real resoulution larger than virtual */ 573 if (var->xres > var->xres_virtual) 574 var->xres_virtual = var->xres; 575 576 if (var->yres > var->yres_virtual) 577 var->yres_virtual = var->yres; 578 579 /* Round up xres_virtual to have proper alignment of lines */ 580 step = s3fb_formats[rv].xresstep - 1; 581 var->xres_virtual = (var->xres_virtual+step) & ~step; 582 583 /* Check whether have enough memory */ 584 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual; 585 if (mem > info->screen_size) { 586 fb_err(info, "not enough framebuffer memory (%d kB requested , %u kB available)\n", 587 mem >> 10, (unsigned int) (info->screen_size >> 10)); 588 return -EINVAL; 589 } 590 591 rv = svga_check_timings (&s3_timing_regs, var, info->node); 592 if (rv < 0) { 593 fb_err(info, "invalid timings requested\n"); 594 return rv; 595 } 596 597 rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r, 598 info->node); 599 if (rv < 0) { 600 fb_err(info, "invalid pixclock value requested\n"); 601 return rv; 602 } 603 604 return 0; 605 } 606 607 /* Set video mode from par */ 608 609 static int s3fb_set_par(struct fb_info *info) 610 { 611 struct s3fb_info *par = info->par; 612 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 613 u32 bpp = info->var.bits_per_pixel; 614 u32 htotal, hsstart, pel_msk; 615 616 if (bpp != 0) { 617 info->fix.ypanstep = 1; 618 info->fix.line_length = (info->var.xres_virtual * bpp) / 8; 619 620 info->flags &= ~FBINFO_MISC_TILEBLITTING; 621 info->tileops = NULL; 622 623 /* in 4bpp supports 8p wide tiles only, any tiles otherwise */ 624 if (bpp == 4 && (info->var.nonstd & 1) != 0) { 625 int i; 626 bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 627 for (i = 8; i <= FB_MAX_BLIT_WIDTH; i += 8) 628 set_bit(i - 1, info->pixmap.blit_x); 629 } else { 630 bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 631 } 632 bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 633 634 offset_value = (info->var.xres_virtual * bpp) / 64; 635 screen_size = info->var.yres_virtual * info->fix.line_length; 636 } else { 637 info->fix.ypanstep = 16; 638 info->fix.line_length = 0; 639 640 info->flags |= FBINFO_MISC_TILEBLITTING; 641 info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; 642 643 /* supports 8x16 tiles only */ 644 bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 645 set_bit(8 - 1, info->pixmap.blit_x); 646 bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 647 set_bit(16 - 1, info->pixmap.blit_y); 648 649 offset_value = info->var.xres_virtual / 16; 650 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64; 651 } 652 653 info->var.xoffset = 0; 654 info->var.yoffset = 0; 655 info->var.activate = FB_ACTIVATE_NOW; 656 657 /* Unlock registers */ 658 vga_wcrt(par->state.vgabase, 0x38, 0x48); 659 vga_wcrt(par->state.vgabase, 0x39, 0xA5); 660 vga_wseq(par->state.vgabase, 0x08, 0x06); 661 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80); 662 663 /* Blank screen and turn off sync */ 664 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); 665 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80); 666 667 /* Set default values */ 668 svga_set_default_gfx_regs(par->state.vgabase); 669 svga_set_default_atc_regs(par->state.vgabase); 670 svga_set_default_seq_regs(par->state.vgabase); 671 svga_set_default_crt_regs(par->state.vgabase); 672 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF); 673 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0); 674 675 /* S3 specific initialization */ 676 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */ 677 svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ 678 679 /* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */ 680 /* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */ 681 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */ 682 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */ 683 684 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ 685 686 /* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */ 687 688 /* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */ 689 /* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */ 690 691 692 /* Set the offset register */ 693 fb_dbg(info, "offset register : %d\n", offset_value); 694 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value); 695 696 if (par->chip != CHIP_357_VIRGE_GX2 && 697 par->chip != CHIP_359_VIRGE_GX2P && 698 par->chip != CHIP_360_TRIO3D_1X && 699 par->chip != CHIP_362_TRIO3D_2X && 700 par->chip != CHIP_368_TRIO3D_2X && 701 par->chip != CHIP_260_VIRGE_MX) { 702 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ 703 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ 704 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ 705 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */ 706 } 707 708 vga_wcrt(par->state.vgabase, 0x3A, 0x35); 709 svga_wattr(par->state.vgabase, 0x33, 0x00); 710 711 if (info->var.vmode & FB_VMODE_DOUBLE) 712 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80); 713 else 714 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80); 715 716 if (info->var.vmode & FB_VMODE_INTERLACED) 717 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20); 718 else 719 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20); 720 721 /* Disable hardware graphics cursor */ 722 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01); 723 /* Disable Streams engine */ 724 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C); 725 726 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); 727 728 /* S3 virge DX hack */ 729 if (par->chip == CHIP_375_VIRGE_DX) { 730 vga_wcrt(par->state.vgabase, 0x86, 0x80); 731 vga_wcrt(par->state.vgabase, 0x90, 0x00); 732 } 733 734 /* S3 virge VX hack */ 735 if (par->chip == CHIP_988_VIRGE_VX) { 736 vga_wcrt(par->state.vgabase, 0x50, 0x00); 737 vga_wcrt(par->state.vgabase, 0x67, 0x50); 738 msleep(10); /* screen remains blank sometimes without this */ 739 vga_wcrt(par->state.vgabase, 0x63, (mode <= 4) ? 0x90 : 0x09); 740 vga_wcrt(par->state.vgabase, 0x66, 0x90); 741 } 742 743 if (par->chip == CHIP_357_VIRGE_GX2 || 744 par->chip == CHIP_359_VIRGE_GX2P || 745 par->chip == CHIP_360_TRIO3D_1X || 746 par->chip == CHIP_362_TRIO3D_2X || 747 par->chip == CHIP_368_TRIO3D_2X || 748 par->chip == CHIP_365_TRIO3D || 749 par->chip == CHIP_375_VIRGE_DX || 750 par->chip == CHIP_385_VIRGE_GX || 751 par->chip == CHIP_260_VIRGE_MX) { 752 dbytes = info->var.xres * ((bpp+7)/8); 753 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); 754 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 755 756 vga_wcrt(par->state.vgabase, 0x66, 0x81); 757 } 758 759 if (par->chip == CHIP_357_VIRGE_GX2 || 760 par->chip == CHIP_359_VIRGE_GX2P || 761 par->chip == CHIP_360_TRIO3D_1X || 762 par->chip == CHIP_362_TRIO3D_2X || 763 par->chip == CHIP_368_TRIO3D_2X || 764 par->chip == CHIP_260_VIRGE_MX) 765 vga_wcrt(par->state.vgabase, 0x34, 0x00); 766 else /* enable Data Transfer Position Control (DTPC) */ 767 vga_wcrt(par->state.vgabase, 0x34, 0x10); 768 769 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40); 770 multiplex = 0; 771 hmul = 1; 772 pel_msk = 0xff; 773 774 svga_wcrt_mask(par->state.vgabase, 0x08, 0x00, 0x60); 775 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60); 776 777 /* Set mode-specific register values */ 778 switch (mode) { 779 case 0: 780 fb_dbg(info, "text mode\n"); 781 svga_set_textmode_vga_regs(par->state.vgabase); 782 pel_msk = 0x0f; 783 784 /* Set additional registers like in 8-bit mode */ 785 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 786 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 787 788 /* Disable enhanced mode */ 789 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); 790 791 if (fasttext) { 792 fb_dbg(info, "high speed text mode set\n"); 793 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40); 794 } 795 break; 796 case 1: 797 fb_dbg(info, "1 bit pseudocolor\n"); 798 svga_wseq_mask(par->state.vgabase, 0x01, 0x10, 0x14); 799 svga_wcrt_mask(par->state.vgabase, 0x08, 0x60, 0x60); 800 svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60); 801 pel_msk = 0x01; 802 803 /* Set additional registers like in 8-bit mode */ 804 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 805 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 806 807 /* disable enhanced mode */ 808 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); 809 break; 810 case 2: 811 fb_dbg(info, "2 bit pseudocolor\n"); 812 svga_wseq_mask(par->state.vgabase, 0x01, 0x04, 0x14); 813 svga_wseq_mask(par->state.vgabase, 0x04, 0x08, 0x08); 814 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x20); 815 svga_wcrt_mask(par->state.vgabase, 0x08, 0x20, 0x60); 816 svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60); 817 pel_msk = 0x03; 818 819 /* Set additional registers like in 8-bit mode */ 820 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 821 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 822 823 /* disable enhanced mode */ 824 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); 825 break; 826 case 3: 827 fb_dbg(info, "4 bit pseudocolor, planar\n"); 828 pel_msk = 0x0f; 829 830 /* Set additional registers like in 8-bit mode */ 831 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 832 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 833 svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60); 834 835 /* disable enhanced mode */ 836 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); 837 break; 838 case 4: 839 fb_dbg(info, "4 bit pseudocolor\n"); 840 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40); 841 svga_wattr(par->state.vgabase, 0x33, 0x01); 842 svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60); 843 pel_msk = 0xf0; 844 845 /* Set additional registers like in 8-bit mode */ 846 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 847 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 848 849 /* disable enhanced mode */ 850 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); 851 break; 852 case 5: 853 fb_dbg(info, "8 bit pseudocolor\n"); 854 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 855 svga_wcrt_mask(par->state.vgabase, 0x05, 0x20, 0x60); 856 if (info->var.pixclock > 20000 || 857 par->chip == CHIP_357_VIRGE_GX2 || 858 par->chip == CHIP_359_VIRGE_GX2P || 859 par->chip == CHIP_360_TRIO3D_1X || 860 par->chip == CHIP_362_TRIO3D_2X || 861 par->chip == CHIP_368_TRIO3D_2X || 862 par->chip == CHIP_260_VIRGE_MX) 863 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 864 else { 865 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); 866 multiplex = 1; 867 } 868 break; 869 case 6: 870 fb_dbg(info, "5/5/5 truecolor\n"); 871 if (par->chip == CHIP_988_VIRGE_VX) { 872 if (info->var.pixclock > 20000) 873 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); 874 else 875 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); 876 } else if (par->chip == CHIP_365_TRIO3D) { 877 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 878 if (info->var.pixclock > 8695) { 879 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); 880 hmul = 2; 881 } else { 882 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); 883 multiplex = 1; 884 } 885 } else { 886 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 887 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); 888 if (par->chip != CHIP_357_VIRGE_GX2 && 889 par->chip != CHIP_359_VIRGE_GX2P && 890 par->chip != CHIP_360_TRIO3D_1X && 891 par->chip != CHIP_362_TRIO3D_2X && 892 par->chip != CHIP_368_TRIO3D_2X && 893 par->chip != CHIP_260_VIRGE_MX) 894 hmul = 2; 895 } 896 break; 897 case 7: 898 fb_dbg(info, "5/6/5 truecolor\n"); 899 if (par->chip == CHIP_988_VIRGE_VX) { 900 if (info->var.pixclock > 20000) 901 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); 902 else 903 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); 904 } else if (par->chip == CHIP_365_TRIO3D) { 905 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 906 if (info->var.pixclock > 8695) { 907 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); 908 hmul = 2; 909 } else { 910 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); 911 multiplex = 1; 912 } 913 } else { 914 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 915 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); 916 if (par->chip != CHIP_357_VIRGE_GX2 && 917 par->chip != CHIP_359_VIRGE_GX2P && 918 par->chip != CHIP_360_TRIO3D_1X && 919 par->chip != CHIP_362_TRIO3D_2X && 920 par->chip != CHIP_368_TRIO3D_2X && 921 par->chip != CHIP_260_VIRGE_MX) 922 hmul = 2; 923 } 924 break; 925 case 8: 926 /* VIRGE VX case */ 927 fb_dbg(info, "8/8/8 truecolor\n"); 928 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); 929 break; 930 case 9: 931 fb_dbg(info, "8/8/8/8 truecolor\n"); 932 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30); 933 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); 934 break; 935 default: 936 fb_err(info, "unsupported mode - bug\n"); 937 return -EINVAL; 938 } 939 vga_w(par->state.vgabase, VGA_PEL_MSK, pel_msk); 940 941 if (par->chip != CHIP_988_VIRGE_VX) { 942 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10); 943 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80); 944 } 945 946 s3_set_pixclock(info, info->var.pixclock); 947 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1, 948 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 949 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 950 hmul, info->node); 951 952 /* Set interlaced mode start/end register */ 953 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 954 htotal = ((htotal * hmul) / 8) - 5; 955 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2); 956 957 /* Set Data Transfer Position */ 958 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8; 959 /* + 2 is needed for Virge/VX, does no harm on other cards */ 960 value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1); 961 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value); 962 963 if (screen_size > info->screen_size) 964 screen_size = info->screen_size; 965 memset_io(info->screen_base, 0x00, screen_size); 966 /* Device and screen back on */ 967 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80); 968 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20); 969 970 return 0; 971 } 972 973 /* Set a colour register */ 974 975 static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 976 u_int transp, struct fb_info *fb) 977 { 978 struct s3fb_info *par = fb->par; 979 int cols; 980 981 switch (fb->var.bits_per_pixel) { 982 case 0: 983 case 1: 984 case 2: 985 case 4: 986 case 8: 987 cols = 1 << (fb->var.bits_per_pixel ? fb->var.bits_per_pixel : 4); 988 if (regno >= cols) 989 return -EINVAL; 990 991 if ((fb->var.bits_per_pixel == 4) && ((fb->var.nonstd & 1) == 0)) 992 regno <<= 4; 993 994 vga_w(par->state.vgabase, VGA_PEL_IW, regno); 995 vga_w(par->state.vgabase, VGA_PEL_D, red >> 10); 996 vga_w(par->state.vgabase, VGA_PEL_D, green >> 10); 997 vga_w(par->state.vgabase, VGA_PEL_D, blue >> 10); 998 break; 999 case 16: 1000 if (regno >= 16) 1001 return 0; 1002 1003 if (fb->var.green.length == 5) 1004 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | 1005 ((green & 0xF800) >> 6) | ((blue & 0xF800) >> 11); 1006 else if (fb->var.green.length == 6) 1007 ((u32*)fb->pseudo_palette)[regno] = (red & 0xF800) | 1008 ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); 1009 else return -EINVAL; 1010 break; 1011 case 24: 1012 case 32: 1013 if (regno >= 16) 1014 return 0; 1015 1016 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) | 1017 (green & 0xFF00) | ((blue & 0xFF00) >> 8); 1018 break; 1019 default: 1020 return -EINVAL; 1021 } 1022 1023 return 0; 1024 } 1025 1026 1027 /* Set the display blanking state */ 1028 1029 static int s3fb_blank(int blank_mode, struct fb_info *info) 1030 { 1031 struct s3fb_info *par = info->par; 1032 u8 data; 1033 1034 data = (blank_mode == FB_BLANK_UNBLANK) ? 0x00 : 0x20; 1035 svga_wseq_mask(par->state.vgabase, 0x01, data, 0x20); 1036 svga_wseq_mask(par->state.vgabase, 0x18, data, 0x20); 1037 1038 switch (blank_mode) { 1039 default: 1040 data = 0x00; 1041 break; 1042 case FB_BLANK_HSYNC_SUSPEND: 1043 data = 0x02; 1044 break; 1045 case FB_BLANK_VSYNC_SUSPEND: 1046 data = 0x04; 1047 break; 1048 case FB_BLANK_POWERDOWN: 1049 data = 0x06; 1050 break; 1051 } 1052 svga_wcrt_mask(par->state.vgabase, 0x56, data, 0x06); 1053 1054 data = (blank_mode == FB_BLANK_POWERDOWN) ? 0x01 : 0x00; 1055 svga_wseq_mask(par->state.vgabase, 0x14, data, 0x01); 1056 1057 return 0; 1058 } 1059 1060 1061 /* Pan the display */ 1062 1063 static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 1064 { 1065 struct s3fb_info *par = info->par; 1066 unsigned int offset; 1067 1068 /* Calculate the offset */ 1069 if (info->var.bits_per_pixel == 0) { 1070 offset = (var->yoffset / 16) * (info->var.xres_virtual / 2) 1071 + (var->xoffset / 2); 1072 offset = offset >> 2; 1073 } else { 1074 offset = (var->yoffset * info->fix.line_length) + 1075 (var->xoffset * info->var.bits_per_pixel / 8); 1076 offset = offset >> 2; 1077 } 1078 1079 /* Set the offset */ 1080 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset); 1081 1082 return 0; 1083 } 1084 1085 /* Get capabilities of accelerator based on the mode */ 1086 1087 static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps, 1088 struct fb_var_screeninfo *var) 1089 { 1090 int i; 1091 1092 if (var->bits_per_pixel == 0) { 1093 /* can only support 256 8x16 bitmap */ 1094 bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH); 1095 set_bit(8 - 1, caps->x); 1096 bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT); 1097 set_bit(16 - 1, caps->y); 1098 caps->len = 256; 1099 } else { 1100 if (var->bits_per_pixel == 4 && (var->nonstd & 1) != 0) { 1101 bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH); 1102 for (i = 8; i <= FB_MAX_BLIT_WIDTH; i += 8) 1103 set_bit(i - 1, caps->x); 1104 } else { 1105 bitmap_fill(caps->x, FB_MAX_BLIT_WIDTH); 1106 } 1107 bitmap_fill(caps->y, FB_MAX_BLIT_HEIGHT); 1108 caps->len = ~(u32)0; 1109 } 1110 } 1111 1112 /* ------------------------------------------------------------------------- */ 1113 1114 /* Frame buffer operations */ 1115 1116 static const struct fb_ops s3fb_ops = { 1117 .owner = THIS_MODULE, 1118 .fb_open = s3fb_open, 1119 .fb_release = s3fb_release, 1120 __FB_DEFAULT_IOMEM_OPS_RDWR, 1121 .fb_check_var = s3fb_check_var, 1122 .fb_set_par = s3fb_set_par, 1123 .fb_setcolreg = s3fb_setcolreg, 1124 .fb_blank = s3fb_blank, 1125 .fb_pan_display = s3fb_pan_display, 1126 .fb_fillrect = s3fb_fillrect, 1127 .fb_copyarea = cfb_copyarea, 1128 .fb_imageblit = s3fb_imageblit, 1129 __FB_DEFAULT_IOMEM_OPS_MMAP, 1130 .fb_get_caps = s3fb_get_caps, 1131 }; 1132 1133 /* ------------------------------------------------------------------------- */ 1134 1135 static int s3_identification(struct s3fb_info *par) 1136 { 1137 int chip = par->chip; 1138 1139 if (chip == CHIP_XXX_TRIO) { 1140 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30); 1141 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e); 1142 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f); 1143 1144 if ((cr30 == 0xE0) || (cr30 == 0xE1)) { 1145 if (cr2e == 0x10) 1146 return CHIP_732_TRIO32; 1147 if (cr2e == 0x11) { 1148 if (! (cr2f & 0x40)) 1149 return CHIP_764_TRIO64; 1150 else 1151 return CHIP_765_TRIO64VP; 1152 } 1153 } 1154 } 1155 1156 if (chip == CHIP_XXX_TRIO64V2_DXGX) { 1157 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); 1158 1159 if (! (cr6f & 0x01)) 1160 return CHIP_775_TRIO64V2_DX; 1161 else 1162 return CHIP_785_TRIO64V2_GX; 1163 } 1164 1165 if (chip == CHIP_XXX_VIRGE_DXGX) { 1166 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); 1167 1168 if (! (cr6f & 0x01)) 1169 return CHIP_375_VIRGE_DX; 1170 else 1171 return CHIP_385_VIRGE_GX; 1172 } 1173 1174 if (chip == CHIP_36X_TRIO3D_1X_2X) { 1175 switch (vga_rcrt(par->state.vgabase, 0x2f)) { 1176 case 0x00: 1177 return CHIP_360_TRIO3D_1X; 1178 case 0x01: 1179 return CHIP_362_TRIO3D_2X; 1180 case 0x02: 1181 return CHIP_368_TRIO3D_2X; 1182 } 1183 } 1184 1185 return CHIP_UNKNOWN; 1186 } 1187 1188 1189 /* PCI probe */ 1190 1191 static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 1192 { 1193 struct pci_bus_region bus_reg; 1194 struct resource vga_res; 1195 struct fb_info *info; 1196 struct s3fb_info *par; 1197 int rc; 1198 u8 regval, cr38, cr39; 1199 bool found = false; 1200 1201 /* Ignore secondary VGA device because there is no VGA arbitration */ 1202 if (! svga_primary_device(dev)) { 1203 dev_info(&(dev->dev), "ignoring secondary device\n"); 1204 return -ENODEV; 1205 } 1206 1207 rc = aperture_remove_conflicting_pci_devices(dev, "s3fb"); 1208 if (rc) 1209 return rc; 1210 1211 /* Allocate and fill driver data structure */ 1212 info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev)); 1213 if (!info) 1214 return -ENOMEM; 1215 1216 par = info->par; 1217 mutex_init(&par->open_lock); 1218 1219 info->flags = FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN; 1220 info->fbops = &s3fb_ops; 1221 1222 /* Prepare PCI device */ 1223 rc = pci_enable_device(dev); 1224 if (rc < 0) { 1225 dev_err(info->device, "cannot enable PCI device\n"); 1226 goto err_enable_device; 1227 } 1228 1229 rc = pci_request_regions(dev, "s3fb"); 1230 if (rc < 0) { 1231 dev_err(info->device, "cannot reserve framebuffer region\n"); 1232 goto err_request_regions; 1233 } 1234 1235 1236 info->fix.smem_start = pci_resource_start(dev, 0); 1237 info->fix.smem_len = pci_resource_len(dev, 0); 1238 1239 /* Map physical IO memory address into kernel space */ 1240 info->screen_base = pci_iomap_wc(dev, 0, 0); 1241 if (! info->screen_base) { 1242 rc = -ENOMEM; 1243 dev_err(info->device, "iomap for framebuffer failed\n"); 1244 goto err_iomap; 1245 } 1246 1247 bus_reg.start = 0; 1248 bus_reg.end = 64 * 1024; 1249 1250 vga_res.flags = IORESOURCE_IO; 1251 1252 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 1253 1254 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start; 1255 1256 /* Unlock regs */ 1257 cr38 = vga_rcrt(par->state.vgabase, 0x38); 1258 cr39 = vga_rcrt(par->state.vgabase, 0x39); 1259 vga_wseq(par->state.vgabase, 0x08, 0x06); 1260 vga_wcrt(par->state.vgabase, 0x38, 0x48); 1261 vga_wcrt(par->state.vgabase, 0x39, 0xA5); 1262 1263 /* Identify chip type */ 1264 par->chip = id->driver_data & CHIP_MASK; 1265 par->rev = vga_rcrt(par->state.vgabase, 0x2f); 1266 if (par->chip & CHIP_UNDECIDED_FLAG) 1267 par->chip = s3_identification(par); 1268 1269 /* Find how many physical memory there is on card */ 1270 /* 0x36 register is accessible even if other registers are locked */ 1271 regval = vga_rcrt(par->state.vgabase, 0x36); 1272 if (par->chip == CHIP_360_TRIO3D_1X || 1273 par->chip == CHIP_362_TRIO3D_2X || 1274 par->chip == CHIP_368_TRIO3D_2X || 1275 par->chip == CHIP_365_TRIO3D) { 1276 switch ((regval & 0xE0) >> 5) { 1277 case 0: /* 8MB -- only 4MB usable for display */ 1278 case 1: /* 4MB with 32-bit bus */ 1279 case 2: /* 4MB */ 1280 info->screen_size = 4 << 20; 1281 break; 1282 case 4: /* 2MB on 365 Trio3D */ 1283 case 6: /* 2MB */ 1284 info->screen_size = 2 << 20; 1285 break; 1286 } 1287 } else if (par->chip == CHIP_357_VIRGE_GX2 || 1288 par->chip == CHIP_359_VIRGE_GX2P || 1289 par->chip == CHIP_260_VIRGE_MX) { 1290 switch ((regval & 0xC0) >> 6) { 1291 case 1: /* 4MB */ 1292 info->screen_size = 4 << 20; 1293 break; 1294 case 3: /* 2MB */ 1295 info->screen_size = 2 << 20; 1296 break; 1297 } 1298 } else if (par->chip == CHIP_988_VIRGE_VX) { 1299 switch ((regval & 0x60) >> 5) { 1300 case 0: /* 2MB */ 1301 info->screen_size = 2 << 20; 1302 break; 1303 case 1: /* 4MB */ 1304 info->screen_size = 4 << 20; 1305 break; 1306 case 2: /* 6MB */ 1307 info->screen_size = 6 << 20; 1308 break; 1309 case 3: /* 8MB */ 1310 info->screen_size = 8 << 20; 1311 break; 1312 } 1313 /* off-screen memory */ 1314 regval = vga_rcrt(par->state.vgabase, 0x37); 1315 switch ((regval & 0x60) >> 5) { 1316 case 1: /* 4MB */ 1317 info->screen_size -= 4 << 20; 1318 break; 1319 case 2: /* 2MB */ 1320 info->screen_size -= 2 << 20; 1321 break; 1322 } 1323 } else 1324 info->screen_size = s3_memsizes[regval >> 5] << 10; 1325 info->fix.smem_len = info->screen_size; 1326 1327 /* Find MCLK frequency */ 1328 regval = vga_rseq(par->state.vgabase, 0x10); 1329 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); 1330 par->mclk_freq = par->mclk_freq >> (regval >> 5); 1331 1332 /* Restore locks */ 1333 vga_wcrt(par->state.vgabase, 0x38, cr38); 1334 vga_wcrt(par->state.vgabase, 0x39, cr39); 1335 1336 strcpy(info->fix.id, s3_names [par->chip]); 1337 info->fix.mmio_start = 0; 1338 info->fix.mmio_len = 0; 1339 info->fix.type = FB_TYPE_PACKED_PIXELS; 1340 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1341 info->fix.ypanstep = 0; 1342 info->fix.accel = FB_ACCEL_NONE; 1343 info->pseudo_palette = (void*) (par->pseudo_palette); 1344 info->var.bits_per_pixel = 8; 1345 1346 #ifdef CONFIG_FB_S3_DDC 1347 /* Enable MMIO if needed */ 1348 if (s3fb_ddc_needs_mmio(par->chip)) { 1349 par->mmio = ioremap(info->fix.smem_start + MMIO_OFFSET, MMIO_SIZE); 1350 if (par->mmio) 1351 svga_wcrt_mask(par->state.vgabase, 0x53, 0x08, 0x08); /* enable MMIO */ 1352 else 1353 dev_err(info->device, "unable to map MMIO at 0x%lx, disabling DDC", 1354 info->fix.smem_start + MMIO_OFFSET); 1355 } 1356 if (!s3fb_ddc_needs_mmio(par->chip) || par->mmio) 1357 if (s3fb_setup_ddc_bus(info) == 0) { 1358 u8 *edid = fb_ddc_read(&par->ddc_adapter); 1359 par->ddc_registered = true; 1360 if (edid) { 1361 fb_edid_to_monspecs(edid, &info->monspecs); 1362 kfree(edid); 1363 if (!info->monspecs.modedb) 1364 dev_err(info->device, "error getting mode database\n"); 1365 else { 1366 const struct fb_videomode *m; 1367 1368 fb_videomode_to_modelist(info->monspecs.modedb, 1369 info->monspecs.modedb_len, 1370 &info->modelist); 1371 m = fb_find_best_display(&info->monspecs, &info->modelist); 1372 if (m) { 1373 fb_videomode_to_var(&info->var, m); 1374 /* fill all other info->var's fields */ 1375 if (s3fb_check_var(&info->var, info) == 0) 1376 found = true; 1377 } 1378 } 1379 } 1380 } 1381 #endif 1382 if (!mode_option && !found) 1383 mode_option = "640x480-8@60"; 1384 1385 /* Prepare startup mode */ 1386 if (mode_option) { 1387 rc = fb_find_mode(&info->var, info, mode_option, 1388 info->monspecs.modedb, info->monspecs.modedb_len, 1389 NULL, info->var.bits_per_pixel); 1390 if (!rc || rc == 4) { 1391 rc = -EINVAL; 1392 dev_err(info->device, "mode %s not found\n", mode_option); 1393 fb_destroy_modedb(info->monspecs.modedb); 1394 info->monspecs.modedb = NULL; 1395 goto err_find_mode; 1396 } 1397 } 1398 1399 fb_destroy_modedb(info->monspecs.modedb); 1400 info->monspecs.modedb = NULL; 1401 1402 /* maximize virtual vertical size for fast scrolling */ 1403 info->var.yres_virtual = info->fix.smem_len * 8 / 1404 (info->var.bits_per_pixel * info->var.xres_virtual); 1405 if (info->var.yres_virtual < info->var.yres) { 1406 dev_err(info->device, "virtual vertical size smaller than real\n"); 1407 rc = -EINVAL; 1408 goto err_find_mode; 1409 } 1410 1411 rc = fb_alloc_cmap(&info->cmap, 256, 0); 1412 if (rc < 0) { 1413 dev_err(info->device, "cannot allocate colormap\n"); 1414 goto err_alloc_cmap; 1415 } 1416 1417 rc = register_framebuffer(info); 1418 if (rc < 0) { 1419 dev_err(info->device, "cannot register framebuffer\n"); 1420 goto err_reg_fb; 1421 } 1422 1423 fb_info(info, "%s on %s, %d MB RAM, %d MHz MCLK\n", 1424 info->fix.id, pci_name(dev), 1425 info->fix.smem_len >> 20, (par->mclk_freq + 500) / 1000); 1426 1427 if (par->chip == CHIP_UNKNOWN) 1428 fb_info(info, "unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", 1429 vga_rcrt(par->state.vgabase, 0x2d), 1430 vga_rcrt(par->state.vgabase, 0x2e), 1431 vga_rcrt(par->state.vgabase, 0x2f), 1432 vga_rcrt(par->state.vgabase, 0x30)); 1433 1434 /* Record a reference to the driver data */ 1435 pci_set_drvdata(dev, info); 1436 1437 if (mtrr) 1438 par->wc_cookie = arch_phys_wc_add(info->fix.smem_start, 1439 info->fix.smem_len); 1440 1441 return 0; 1442 1443 /* Error handling */ 1444 err_reg_fb: 1445 fb_dealloc_cmap(&info->cmap); 1446 err_alloc_cmap: 1447 err_find_mode: 1448 #ifdef CONFIG_FB_S3_DDC 1449 if (par->ddc_registered) 1450 i2c_del_adapter(&par->ddc_adapter); 1451 if (par->mmio) 1452 iounmap(par->mmio); 1453 #endif 1454 pci_iounmap(dev, info->screen_base); 1455 err_iomap: 1456 pci_release_regions(dev); 1457 err_request_regions: 1458 /* pci_disable_device(dev); */ 1459 err_enable_device: 1460 framebuffer_release(info); 1461 return rc; 1462 } 1463 1464 1465 /* PCI remove */ 1466 1467 static void s3_pci_remove(struct pci_dev *dev) 1468 { 1469 struct fb_info *info = pci_get_drvdata(dev); 1470 struct s3fb_info __maybe_unused *par; 1471 1472 if (info) { 1473 par = info->par; 1474 arch_phys_wc_del(par->wc_cookie); 1475 unregister_framebuffer(info); 1476 fb_dealloc_cmap(&info->cmap); 1477 1478 #ifdef CONFIG_FB_S3_DDC 1479 if (par->ddc_registered) 1480 i2c_del_adapter(&par->ddc_adapter); 1481 if (par->mmio) 1482 iounmap(par->mmio); 1483 #endif 1484 1485 pci_iounmap(dev, info->screen_base); 1486 pci_release_regions(dev); 1487 /* pci_disable_device(dev); */ 1488 1489 framebuffer_release(info); 1490 } 1491 } 1492 1493 /* PCI suspend */ 1494 1495 static int __maybe_unused s3_pci_suspend(struct device *dev) 1496 { 1497 struct fb_info *info = dev_get_drvdata(dev); 1498 struct s3fb_info *par = info->par; 1499 1500 dev_info(info->device, "suspend\n"); 1501 1502 console_lock(); 1503 mutex_lock(&(par->open_lock)); 1504 1505 if (par->ref_count == 0) { 1506 mutex_unlock(&(par->open_lock)); 1507 console_unlock(); 1508 return 0; 1509 } 1510 1511 fb_set_suspend(info, 1); 1512 svga_wseq_mask(par->state.vgabase, 0x18, 0x20, 0x20); 1513 svga_wseq_mask(par->state.vgabase, 0x14, 0x01, 0x01); 1514 1515 mutex_unlock(&(par->open_lock)); 1516 console_unlock(); 1517 1518 return 0; 1519 } 1520 1521 1522 /* PCI resume */ 1523 1524 static int __maybe_unused s3_pci_resume(struct device *dev) 1525 { 1526 struct fb_info *info = dev_get_drvdata(dev); 1527 struct s3fb_info *par = info->par; 1528 1529 dev_info(info->device, "resume\n"); 1530 1531 console_lock(); 1532 mutex_lock(&(par->open_lock)); 1533 1534 if (par->ref_count == 0) { 1535 mutex_unlock(&(par->open_lock)); 1536 console_unlock(); 1537 return 0; 1538 } 1539 1540 vga_wseq(par->state.vgabase, 0x08, 0x06); 1541 svga_wseq_mask(par->state.vgabase, 0x18, 0x00, 0x20); 1542 svga_wseq_mask(par->state.vgabase, 0x14, 0x00, 0x01); 1543 s3fb_set_par(info); 1544 fb_set_suspend(info, 0); 1545 1546 mutex_unlock(&(par->open_lock)); 1547 console_unlock(); 1548 1549 return 0; 1550 } 1551 1552 static const struct dev_pm_ops s3_pci_pm_ops = { 1553 #ifdef CONFIG_PM_SLEEP 1554 .suspend = s3_pci_suspend, 1555 .resume = s3_pci_resume, 1556 .freeze = NULL, 1557 .thaw = s3_pci_resume, 1558 .poweroff = s3_pci_suspend, 1559 .restore = s3_pci_resume, 1560 #endif 1561 }; 1562 1563 /* List of boards that we are trying to support */ 1564 1565 static const struct pci_device_id s3_devices[] = { 1566 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8810), .driver_data = CHIP_XXX_TRIO}, 1567 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8811), .driver_data = CHIP_XXX_TRIO}, 1568 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8812), .driver_data = CHIP_M65_AURORA64VP}, 1569 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8814), .driver_data = CHIP_767_TRIO64UVP}, 1570 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8901), .driver_data = CHIP_XXX_TRIO64V2_DXGX}, 1571 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8902), .driver_data = CHIP_551_PLATO_PX}, 1572 1573 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE}, 1574 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX}, 1575 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX}, 1576 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2}, 1577 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P}, 1578 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1579 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1580 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, 1581 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8C01), .driver_data = CHIP_260_VIRGE_MX}, 1582 1583 {0, 0, 0, 0, 0, 0, 0} 1584 }; 1585 1586 1587 MODULE_DEVICE_TABLE(pci, s3_devices); 1588 1589 static struct pci_driver s3fb_pci_driver = { 1590 .name = "s3fb", 1591 .id_table = s3_devices, 1592 .probe = s3_pci_probe, 1593 .remove = s3_pci_remove, 1594 .driver.pm = &s3_pci_pm_ops, 1595 }; 1596 1597 /* Parse user specified options */ 1598 1599 #ifndef MODULE 1600 static int __init s3fb_setup(char *options) 1601 { 1602 char *opt; 1603 1604 if (!options || !*options) 1605 return 0; 1606 1607 while ((opt = strsep(&options, ",")) != NULL) { 1608 1609 if (!*opt) 1610 continue; 1611 else if (!strncmp(opt, "mtrr:", 5)) 1612 mtrr = simple_strtoul(opt + 5, NULL, 0); 1613 else if (!strncmp(opt, "fasttext:", 9)) 1614 fasttext = simple_strtoul(opt + 9, NULL, 0); 1615 else 1616 mode_option = opt; 1617 } 1618 1619 return 0; 1620 } 1621 #endif 1622 1623 /* Cleanup */ 1624 1625 static void __exit s3fb_cleanup(void) 1626 { 1627 pr_debug("s3fb: cleaning up\n"); 1628 pci_unregister_driver(&s3fb_pci_driver); 1629 } 1630 1631 /* Driver Initialisation */ 1632 1633 static int __init s3fb_init(void) 1634 { 1635 1636 #ifndef MODULE 1637 char *option = NULL; 1638 #endif 1639 1640 if (fb_modesetting_disabled("s3fb")) 1641 return -ENODEV; 1642 1643 #ifndef MODULE 1644 if (fb_get_options("s3fb", &option)) 1645 return -ENODEV; 1646 s3fb_setup(option); 1647 #endif 1648 1649 pr_debug("s3fb: initializing\n"); 1650 return pci_register_driver(&s3fb_pci_driver); 1651 } 1652 1653 /* ------------------------------------------------------------------------- */ 1654 1655 /* Modularization */ 1656 1657 module_init(s3fb_init); 1658 module_exit(s3fb_cleanup); 1659