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