1 /* 2 * drivers/video/imsttfb.c -- frame buffer device for IMS TwinTurbo 3 * 4 * This file is derived from the powermac console "imstt" driver: 5 * Copyright (C) 1997 Sigurdur Asgeirsson 6 * With additional hacking by Jeffrey Kuskin (jsk@mojave.stanford.edu) 7 * Modified by Danilo Beuche 1998 8 * Some register values added by Damien Doligez, INRIA Rocquencourt 9 * Various cleanups by Paul Mundt (lethal@chaoticdreams.org) 10 * 11 * This file was written by Ryan Nielsen (ran@krazynet.com) 12 * Most of the frame buffer device stuff was copied from atyfb.c 13 * 14 * This file is subject to the terms and conditions of the GNU General Public 15 * License. See the file COPYING in the main directory of this archive for 16 * more details. 17 */ 18 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include <linux/errno.h> 22 #include <linux/string.h> 23 #include <linux/mm.h> 24 #include <linux/vmalloc.h> 25 #include <linux/delay.h> 26 #include <linux/interrupt.h> 27 #include <linux/fb.h> 28 #include <linux/init.h> 29 #include <linux/pci.h> 30 #include <asm/io.h> 31 #include <linux/uaccess.h> 32 33 #if defined(CONFIG_PPC) 34 #include <linux/nvram.h> 35 #include <asm/prom.h> 36 #include "macmodes.h" 37 #endif 38 39 #ifndef __powerpc__ 40 #define eieio() /* Enforce In-order Execution of I/O */ 41 #endif 42 43 /* TwinTurbo (Cosmo) registers */ 44 enum { 45 S1SA = 0, /* 0x00 */ 46 S2SA = 1, /* 0x04 */ 47 SP = 2, /* 0x08 */ 48 DSA = 3, /* 0x0C */ 49 CNT = 4, /* 0x10 */ 50 DP_OCTL = 5, /* 0x14 */ 51 CLR = 6, /* 0x18 */ 52 BI = 8, /* 0x20 */ 53 MBC = 9, /* 0x24 */ 54 BLTCTL = 10, /* 0x28 */ 55 56 /* Scan Timing Generator Registers */ 57 HES = 12, /* 0x30 */ 58 HEB = 13, /* 0x34 */ 59 HSB = 14, /* 0x38 */ 60 HT = 15, /* 0x3C */ 61 VES = 16, /* 0x40 */ 62 VEB = 17, /* 0x44 */ 63 VSB = 18, /* 0x48 */ 64 VT = 19, /* 0x4C */ 65 HCIV = 20, /* 0x50 */ 66 VCIV = 21, /* 0x54 */ 67 TCDR = 22, /* 0x58 */ 68 VIL = 23, /* 0x5C */ 69 STGCTL = 24, /* 0x60 */ 70 71 /* Screen Refresh Generator Registers */ 72 SSR = 25, /* 0x64 */ 73 HRIR = 26, /* 0x68 */ 74 SPR = 27, /* 0x6C */ 75 CMR = 28, /* 0x70 */ 76 SRGCTL = 29, /* 0x74 */ 77 78 /* RAM Refresh Generator Registers */ 79 RRCIV = 30, /* 0x78 */ 80 RRSC = 31, /* 0x7C */ 81 RRCR = 34, /* 0x88 */ 82 83 /* System Registers */ 84 GIOE = 32, /* 0x80 */ 85 GIO = 33, /* 0x84 */ 86 SCR = 35, /* 0x8C */ 87 SSTATUS = 36, /* 0x90 */ 88 PRC = 37, /* 0x94 */ 89 90 #if 0 91 /* PCI Registers */ 92 DVID = 0x00000000L, 93 SC = 0x00000004L, 94 CCR = 0x00000008L, 95 OG = 0x0000000CL, 96 BARM = 0x00000010L, 97 BARER = 0x00000030L, 98 #endif 99 }; 100 101 /* IBM 624 RAMDAC Direct Registers */ 102 enum { 103 PADDRW = 0x00, 104 PDATA = 0x04, 105 PPMASK = 0x08, 106 PADDRR = 0x0c, 107 PIDXLO = 0x10, 108 PIDXHI = 0x14, 109 PIDXDATA= 0x18, 110 PIDXCTL = 0x1c 111 }; 112 113 /* IBM 624 RAMDAC Indirect Registers */ 114 enum { 115 CLKCTL = 0x02, /* (0x01) Miscellaneous Clock Control */ 116 SYNCCTL = 0x03, /* (0x00) Sync Control */ 117 HSYNCPOS = 0x04, /* (0x00) Horizontal Sync Position */ 118 PWRMNGMT = 0x05, /* (0x00) Power Management */ 119 DACOP = 0x06, /* (0x02) DAC Operation */ 120 PALETCTL = 0x07, /* (0x00) Palette Control */ 121 SYSCLKCTL = 0x08, /* (0x01) System Clock Control */ 122 PIXFMT = 0x0a, /* () Pixel Format [bpp >> 3 + 2] */ 123 BPP8 = 0x0b, /* () 8 Bits/Pixel Control */ 124 BPP16 = 0x0c, /* () 16 Bits/Pixel Control [bit 1=1 for 565] */ 125 BPP24 = 0x0d, /* () 24 Bits/Pixel Control */ 126 BPP32 = 0x0e, /* () 32 Bits/Pixel Control */ 127 PIXCTL1 = 0x10, /* (0x05) Pixel PLL Control 1 */ 128 PIXCTL2 = 0x11, /* (0x00) Pixel PLL Control 2 */ 129 SYSCLKN = 0x15, /* () System Clock N (System PLL Reference Divider) */ 130 SYSCLKM = 0x16, /* () System Clock M (System PLL VCO Divider) */ 131 SYSCLKP = 0x17, /* () System Clock P */ 132 SYSCLKC = 0x18, /* () System Clock C */ 133 /* 134 * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1) 135 * c is charge pump bias which depends on the VCO frequency 136 */ 137 PIXM0 = 0x20, /* () Pixel M 0 */ 138 PIXN0 = 0x21, /* () Pixel N 0 */ 139 PIXP0 = 0x22, /* () Pixel P 0 */ 140 PIXC0 = 0x23, /* () Pixel C 0 */ 141 CURSCTL = 0x30, /* (0x00) Cursor Control */ 142 CURSXLO = 0x31, /* () Cursor X position, low 8 bits */ 143 CURSXHI = 0x32, /* () Cursor X position, high 8 bits */ 144 CURSYLO = 0x33, /* () Cursor Y position, low 8 bits */ 145 CURSYHI = 0x34, /* () Cursor Y position, high 8 bits */ 146 CURSHOTX = 0x35, /* () Cursor Hot Spot X */ 147 CURSHOTY = 0x36, /* () Cursor Hot Spot Y */ 148 CURSACCTL = 0x37, /* () Advanced Cursor Control Enable */ 149 CURSACATTR = 0x38, /* () Advanced Cursor Attribute */ 150 CURS1R = 0x40, /* () Cursor 1 Red */ 151 CURS1G = 0x41, /* () Cursor 1 Green */ 152 CURS1B = 0x42, /* () Cursor 1 Blue */ 153 CURS2R = 0x43, /* () Cursor 2 Red */ 154 CURS2G = 0x44, /* () Cursor 2 Green */ 155 CURS2B = 0x45, /* () Cursor 2 Blue */ 156 CURS3R = 0x46, /* () Cursor 3 Red */ 157 CURS3G = 0x47, /* () Cursor 3 Green */ 158 CURS3B = 0x48, /* () Cursor 3 Blue */ 159 BORDR = 0x60, /* () Border Color Red */ 160 BORDG = 0x61, /* () Border Color Green */ 161 BORDB = 0x62, /* () Border Color Blue */ 162 MISCTL1 = 0x70, /* (0x00) Miscellaneous Control 1 */ 163 MISCTL2 = 0x71, /* (0x00) Miscellaneous Control 2 */ 164 MISCTL3 = 0x72, /* (0x00) Miscellaneous Control 3 */ 165 KEYCTL = 0x78 /* (0x00) Key Control/DB Operation */ 166 }; 167 168 /* TI TVP 3030 RAMDAC Direct Registers */ 169 enum { 170 TVPADDRW = 0x00, /* 0 Palette/Cursor RAM Write Address/Index */ 171 TVPPDATA = 0x04, /* 1 Palette Data RAM Data */ 172 TVPPMASK = 0x08, /* 2 Pixel Read-Mask */ 173 TVPPADRR = 0x0c, /* 3 Palette/Cursor RAM Read Address */ 174 TVPCADRW = 0x10, /* 4 Cursor/Overscan Color Write Address */ 175 TVPCDATA = 0x14, /* 5 Cursor/Overscan Color Data */ 176 /* 6 reserved */ 177 TVPCADRR = 0x1c, /* 7 Cursor/Overscan Color Read Address */ 178 /* 8 reserved */ 179 TVPDCCTL = 0x24, /* 9 Direct Cursor Control */ 180 TVPIDATA = 0x28, /* 10 Index Data */ 181 TVPCRDAT = 0x2c, /* 11 Cursor RAM Data */ 182 TVPCXPOL = 0x30, /* 12 Cursor-Position X LSB */ 183 TVPCXPOH = 0x34, /* 13 Cursor-Position X MSB */ 184 TVPCYPOL = 0x38, /* 14 Cursor-Position Y LSB */ 185 TVPCYPOH = 0x3c, /* 15 Cursor-Position Y MSB */ 186 }; 187 188 /* TI TVP 3030 RAMDAC Indirect Registers */ 189 enum { 190 TVPIRREV = 0x01, /* Silicon Revision [RO] */ 191 TVPIRICC = 0x06, /* Indirect Cursor Control (0x00) */ 192 TVPIRBRC = 0x07, /* Byte Router Control (0xe4) */ 193 TVPIRLAC = 0x0f, /* Latch Control (0x06) */ 194 TVPIRTCC = 0x18, /* True Color Control (0x80) */ 195 TVPIRMXC = 0x19, /* Multiplex Control (0x98) */ 196 TVPIRCLS = 0x1a, /* Clock Selection (0x07) */ 197 TVPIRPPG = 0x1c, /* Palette Page (0x00) */ 198 TVPIRGEC = 0x1d, /* General Control (0x00) */ 199 TVPIRMIC = 0x1e, /* Miscellaneous Control (0x00) */ 200 TVPIRPLA = 0x2c, /* PLL Address */ 201 TVPIRPPD = 0x2d, /* Pixel Clock PLL Data */ 202 TVPIRMPD = 0x2e, /* Memory Clock PLL Data */ 203 TVPIRLPD = 0x2f, /* Loop Clock PLL Data */ 204 TVPIRCKL = 0x30, /* Color-Key Overlay Low */ 205 TVPIRCKH = 0x31, /* Color-Key Overlay High */ 206 TVPIRCRL = 0x32, /* Color-Key Red Low */ 207 TVPIRCRH = 0x33, /* Color-Key Red High */ 208 TVPIRCGL = 0x34, /* Color-Key Green Low */ 209 TVPIRCGH = 0x35, /* Color-Key Green High */ 210 TVPIRCBL = 0x36, /* Color-Key Blue Low */ 211 TVPIRCBH = 0x37, /* Color-Key Blue High */ 212 TVPIRCKC = 0x38, /* Color-Key Control (0x00) */ 213 TVPIRMLC = 0x39, /* MCLK/Loop Clock Control (0x18) */ 214 TVPIRSEN = 0x3a, /* Sense Test (0x00) */ 215 TVPIRTMD = 0x3b, /* Test Mode Data */ 216 TVPIRRML = 0x3c, /* CRC Remainder LSB [RO] */ 217 TVPIRRMM = 0x3d, /* CRC Remainder MSB [RO] */ 218 TVPIRRMS = 0x3e, /* CRC Bit Select [WO] */ 219 TVPIRDID = 0x3f, /* Device ID [RO] (0x30) */ 220 TVPIRRES = 0xff /* Software Reset [WO] */ 221 }; 222 223 struct initvalues { 224 __u8 addr, value; 225 }; 226 227 static struct initvalues ibm_initregs[] = { 228 { CLKCTL, 0x21 }, 229 { SYNCCTL, 0x00 }, 230 { HSYNCPOS, 0x00 }, 231 { PWRMNGMT, 0x00 }, 232 { DACOP, 0x02 }, 233 { PALETCTL, 0x00 }, 234 { SYSCLKCTL, 0x01 }, 235 236 /* 237 * Note that colors in X are correct only if all video data is 238 * passed through the palette in the DAC. That is, "indirect 239 * color" must be configured. This is the case for the IBM DAC 240 * used in the 2MB and 4MB cards, at least. 241 */ 242 { BPP8, 0x00 }, 243 { BPP16, 0x01 }, 244 { BPP24, 0x00 }, 245 { BPP32, 0x00 }, 246 247 { PIXCTL1, 0x05 }, 248 { PIXCTL2, 0x00 }, 249 { SYSCLKN, 0x08 }, 250 { SYSCLKM, 0x4f }, 251 { SYSCLKP, 0x00 }, 252 { SYSCLKC, 0x00 }, 253 { CURSCTL, 0x00 }, 254 { CURSACCTL, 0x01 }, 255 { CURSACATTR, 0xa8 }, 256 { CURS1R, 0xff }, 257 { CURS1G, 0xff }, 258 { CURS1B, 0xff }, 259 { CURS2R, 0xff }, 260 { CURS2G, 0xff }, 261 { CURS2B, 0xff }, 262 { CURS3R, 0xff }, 263 { CURS3G, 0xff }, 264 { CURS3B, 0xff }, 265 { BORDR, 0xff }, 266 { BORDG, 0xff }, 267 { BORDB, 0xff }, 268 { MISCTL1, 0x01 }, 269 { MISCTL2, 0x45 }, 270 { MISCTL3, 0x00 }, 271 { KEYCTL, 0x00 } 272 }; 273 274 static struct initvalues tvp_initregs[] = { 275 { TVPIRICC, 0x00 }, 276 { TVPIRBRC, 0xe4 }, 277 { TVPIRLAC, 0x06 }, 278 { TVPIRTCC, 0x80 }, 279 { TVPIRMXC, 0x4d }, 280 { TVPIRCLS, 0x05 }, 281 { TVPIRPPG, 0x00 }, 282 { TVPIRGEC, 0x00 }, 283 { TVPIRMIC, 0x08 }, 284 { TVPIRCKL, 0xff }, 285 { TVPIRCKH, 0xff }, 286 { TVPIRCRL, 0xff }, 287 { TVPIRCRH, 0xff }, 288 { TVPIRCGL, 0xff }, 289 { TVPIRCGH, 0xff }, 290 { TVPIRCBL, 0xff }, 291 { TVPIRCBH, 0xff }, 292 { TVPIRCKC, 0x00 }, 293 { TVPIRPLA, 0x00 }, 294 { TVPIRPPD, 0xc0 }, 295 { TVPIRPPD, 0xd5 }, 296 { TVPIRPPD, 0xea }, 297 { TVPIRPLA, 0x00 }, 298 { TVPIRMPD, 0xb9 }, 299 { TVPIRMPD, 0x3a }, 300 { TVPIRMPD, 0xb1 }, 301 { TVPIRPLA, 0x00 }, 302 { TVPIRLPD, 0xc1 }, 303 { TVPIRLPD, 0x3d }, 304 { TVPIRLPD, 0xf3 }, 305 }; 306 307 struct imstt_regvals { 308 __u32 pitch; 309 __u16 hes, heb, hsb, ht, ves, veb, vsb, vt, vil; 310 __u8 pclk_m, pclk_n, pclk_p; 311 /* Values of the tvp which change depending on colormode x resolution */ 312 __u8 mlc[3]; /* Memory Loop Config 0x39 */ 313 __u8 lckl_p[3]; /* P value of LCKL PLL */ 314 }; 315 316 struct imstt_par { 317 struct imstt_regvals init; 318 __u32 __iomem *dc_regs; 319 unsigned long cmap_regs_phys; 320 __u8 *cmap_regs; 321 __u32 ramdac; 322 __u32 palette[16]; 323 }; 324 325 enum { 326 IBM = 0, 327 TVP = 1 328 }; 329 330 #define USE_NV_MODES 1 331 #define INIT_BPP 8 332 #define INIT_XRES 640 333 #define INIT_YRES 480 334 335 static int inverse = 0; 336 static char fontname[40] __initdata = { 0 }; 337 #if defined(CONFIG_PPC) 338 static signed char init_vmode = -1, init_cmode = -1; 339 #endif 340 341 static struct imstt_regvals tvp_reg_init_2 = { 342 512, 343 0x0002, 0x0006, 0x0026, 0x0028, 0x0003, 0x0016, 0x0196, 0x0197, 0x0196, 344 0xec, 0x2a, 0xf3, 345 { 0x3c, 0x3b, 0x39 }, { 0xf3, 0xf3, 0xf3 } 346 }; 347 348 static struct imstt_regvals tvp_reg_init_6 = { 349 640, 350 0x0004, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d, 0x020a, 351 0xef, 0x2e, 0xb2, 352 { 0x39, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 } 353 }; 354 355 static struct imstt_regvals tvp_reg_init_12 = { 356 800, 357 0x0005, 0x000e, 0x0040, 0x0042, 0x0003, 0x018, 0x270, 0x271, 0x270, 358 0xf6, 0x2e, 0xf2, 359 { 0x3a, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 } 360 }; 361 362 static struct imstt_regvals tvp_reg_init_13 = { 363 832, 364 0x0004, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b, 0x0000, 365 0xfe, 0x3e, 0xf1, 366 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 } 367 }; 368 369 static struct imstt_regvals tvp_reg_init_17 = { 370 1024, 371 0x0006, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324, 0x0000, 372 0xfc, 0x3a, 0xf1, 373 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 } 374 }; 375 376 static struct imstt_regvals tvp_reg_init_18 = { 377 1152, 378 0x0009, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a, 0x0000, 379 0xfd, 0x3a, 0xf1, 380 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 } 381 }; 382 383 static struct imstt_regvals tvp_reg_init_19 = { 384 1280, 385 0x0009, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7, 386 0xf7, 0x36, 0xf0, 387 { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 } 388 }; 389 390 static struct imstt_regvals tvp_reg_init_20 = { 391 1280, 392 0x0009, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a, 0x0000, 393 0xf0, 0x2d, 0xf0, 394 { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 } 395 }; 396 397 /* 398 * PCI driver prototypes 399 */ 400 static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 401 static void imsttfb_remove(struct pci_dev *pdev); 402 403 /* 404 * Register access 405 */ 406 static inline u32 read_reg_le32(volatile u32 __iomem *base, int regindex) 407 { 408 #ifdef __powerpc__ 409 return in_le32(base + regindex); 410 #else 411 return readl(base + regindex); 412 #endif 413 } 414 415 static inline void write_reg_le32(volatile u32 __iomem *base, int regindex, u32 val) 416 { 417 #ifdef __powerpc__ 418 out_le32(base + regindex, val); 419 #else 420 writel(val, base + regindex); 421 #endif 422 } 423 424 static __u32 425 getclkMHz(struct imstt_par *par) 426 { 427 __u32 clk_m, clk_n, clk_p; 428 429 clk_m = par->init.pclk_m; 430 clk_n = par->init.pclk_n; 431 clk_p = par->init.pclk_p; 432 433 return 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1)); 434 } 435 436 static void 437 setclkMHz(struct imstt_par *par, __u32 MHz) 438 { 439 __u32 clk_m, clk_n, x, stage, spilled; 440 441 clk_m = clk_n = 0; 442 stage = spilled = 0; 443 for (;;) { 444 switch (stage) { 445 case 0: 446 clk_m++; 447 break; 448 case 1: 449 clk_n++; 450 break; 451 } 452 x = 20 * (clk_m + 1) / (clk_n + 1); 453 if (x == MHz) 454 break; 455 if (x > MHz) { 456 spilled = 1; 457 stage = 1; 458 } else if (spilled && x < MHz) { 459 stage = 0; 460 } 461 } 462 463 par->init.pclk_m = clk_m; 464 par->init.pclk_n = clk_n; 465 par->init.pclk_p = 0; 466 } 467 468 static struct imstt_regvals * 469 compute_imstt_regvals_ibm(struct imstt_par *par, int xres, int yres) 470 { 471 struct imstt_regvals *init = &par->init; 472 __u32 MHz, hes, heb, veb, htp, vtp; 473 474 switch (xres) { 475 case 640: 476 hes = 0x0008; heb = 0x0012; veb = 0x002a; htp = 10; vtp = 2; 477 MHz = 30 /* .25 */ ; 478 break; 479 case 832: 480 hes = 0x0005; heb = 0x0020; veb = 0x0028; htp = 8; vtp = 3; 481 MHz = 57 /* .27_ */ ; 482 break; 483 case 1024: 484 hes = 0x000a; heb = 0x001c; veb = 0x0020; htp = 8; vtp = 3; 485 MHz = 80; 486 break; 487 case 1152: 488 hes = 0x0012; heb = 0x0022; veb = 0x0031; htp = 4; vtp = 3; 489 MHz = 101 /* .6_ */ ; 490 break; 491 case 1280: 492 hes = 0x0012; heb = 0x002f; veb = 0x0029; htp = 4; vtp = 1; 493 MHz = yres == 960 ? 126 : 135; 494 break; 495 case 1600: 496 hes = 0x0018; heb = 0x0040; veb = 0x002a; htp = 4; vtp = 3; 497 MHz = 200; 498 break; 499 default: 500 return NULL; 501 } 502 503 setclkMHz(par, MHz); 504 505 init->hes = hes; 506 init->heb = heb; 507 init->hsb = init->heb + (xres >> 3); 508 init->ht = init->hsb + htp; 509 init->ves = 0x0003; 510 init->veb = veb; 511 init->vsb = init->veb + yres; 512 init->vt = init->vsb + vtp; 513 init->vil = init->vsb; 514 515 init->pitch = xres; 516 return init; 517 } 518 519 static struct imstt_regvals * 520 compute_imstt_regvals_tvp(struct imstt_par *par, int xres, int yres) 521 { 522 struct imstt_regvals *init; 523 524 switch (xres) { 525 case 512: 526 init = &tvp_reg_init_2; 527 break; 528 case 640: 529 init = &tvp_reg_init_6; 530 break; 531 case 800: 532 init = &tvp_reg_init_12; 533 break; 534 case 832: 535 init = &tvp_reg_init_13; 536 break; 537 case 1024: 538 init = &tvp_reg_init_17; 539 break; 540 case 1152: 541 init = &tvp_reg_init_18; 542 break; 543 case 1280: 544 init = yres == 960 ? &tvp_reg_init_19 : &tvp_reg_init_20; 545 break; 546 default: 547 return NULL; 548 } 549 par->init = *init; 550 return init; 551 } 552 553 static struct imstt_regvals * 554 compute_imstt_regvals (struct imstt_par *par, u_int xres, u_int yres) 555 { 556 if (par->ramdac == IBM) 557 return compute_imstt_regvals_ibm(par, xres, yres); 558 else 559 return compute_imstt_regvals_tvp(par, xres, yres); 560 } 561 562 static void 563 set_imstt_regvals_ibm (struct imstt_par *par, u_int bpp) 564 { 565 struct imstt_regvals *init = &par->init; 566 __u8 pformat = (bpp >> 3) + 2; 567 568 par->cmap_regs[PIDXHI] = 0; eieio(); 569 par->cmap_regs[PIDXLO] = PIXM0; eieio(); 570 par->cmap_regs[PIDXDATA] = init->pclk_m;eieio(); 571 par->cmap_regs[PIDXLO] = PIXN0; eieio(); 572 par->cmap_regs[PIDXDATA] = init->pclk_n;eieio(); 573 par->cmap_regs[PIDXLO] = PIXP0; eieio(); 574 par->cmap_regs[PIDXDATA] = init->pclk_p;eieio(); 575 par->cmap_regs[PIDXLO] = PIXC0; eieio(); 576 par->cmap_regs[PIDXDATA] = 0x02; eieio(); 577 578 par->cmap_regs[PIDXLO] = PIXFMT; eieio(); 579 par->cmap_regs[PIDXDATA] = pformat; eieio(); 580 } 581 582 static void 583 set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp) 584 { 585 struct imstt_regvals *init = &par->init; 586 __u8 tcc, mxc, lckl_n, mic; 587 __u8 mlc, lckl_p; 588 589 switch (bpp) { 590 default: 591 case 8: 592 tcc = 0x80; 593 mxc = 0x4d; 594 lckl_n = 0xc1; 595 mlc = init->mlc[0]; 596 lckl_p = init->lckl_p[0]; 597 break; 598 case 16: 599 tcc = 0x44; 600 mxc = 0x55; 601 lckl_n = 0xe1; 602 mlc = init->mlc[1]; 603 lckl_p = init->lckl_p[1]; 604 break; 605 case 24: 606 tcc = 0x5e; 607 mxc = 0x5d; 608 lckl_n = 0xf1; 609 mlc = init->mlc[2]; 610 lckl_p = init->lckl_p[2]; 611 break; 612 case 32: 613 tcc = 0x46; 614 mxc = 0x5d; 615 lckl_n = 0xf1; 616 mlc = init->mlc[2]; 617 lckl_p = init->lckl_p[2]; 618 break; 619 } 620 mic = 0x08; 621 622 par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); 623 par->cmap_regs[TVPIDATA] = 0x00; eieio(); 624 par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); 625 par->cmap_regs[TVPIDATA] = init->pclk_m; eieio(); 626 par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); 627 par->cmap_regs[TVPIDATA] = init->pclk_n; eieio(); 628 par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio(); 629 par->cmap_regs[TVPIDATA] = init->pclk_p; eieio(); 630 631 par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); 632 par->cmap_regs[TVPIDATA] = tcc; eieio(); 633 par->cmap_regs[TVPADDRW] = TVPIRMXC; eieio(); 634 par->cmap_regs[TVPIDATA] = mxc; eieio(); 635 par->cmap_regs[TVPADDRW] = TVPIRMIC; eieio(); 636 par->cmap_regs[TVPIDATA] = mic; eieio(); 637 638 par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); 639 par->cmap_regs[TVPIDATA] = 0x00; eieio(); 640 par->cmap_regs[TVPADDRW] = TVPIRLPD; eieio(); 641 par->cmap_regs[TVPIDATA] = lckl_n; eieio(); 642 643 par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); 644 par->cmap_regs[TVPIDATA] = 0x15; eieio(); 645 par->cmap_regs[TVPADDRW] = TVPIRMLC; eieio(); 646 par->cmap_regs[TVPIDATA] = mlc; eieio(); 647 648 par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio(); 649 par->cmap_regs[TVPIDATA] = 0x2a; eieio(); 650 par->cmap_regs[TVPADDRW] = TVPIRLPD; eieio(); 651 par->cmap_regs[TVPIDATA] = lckl_p; eieio(); 652 } 653 654 static void 655 set_imstt_regvals (struct fb_info *info, u_int bpp) 656 { 657 struct imstt_par *par = info->par; 658 struct imstt_regvals *init = &par->init; 659 __u32 ctl, pitch, byteswap, scr; 660 661 if (par->ramdac == IBM) 662 set_imstt_regvals_ibm(par, bpp); 663 else 664 set_imstt_regvals_tvp(par, bpp); 665 666 /* 667 * From what I (jsk) can gather poking around with MacsBug, 668 * bits 8 and 9 in the SCR register control endianness 669 * correction (byte swapping). These bits must be set according 670 * to the color depth as follows: 671 * Color depth Bit 9 Bit 8 672 * ========== ===== ===== 673 * 8bpp 0 0 674 * 16bpp 0 1 675 * 32bpp 1 1 676 */ 677 switch (bpp) { 678 default: 679 case 8: 680 ctl = 0x17b1; 681 pitch = init->pitch >> 2; 682 byteswap = 0x000; 683 break; 684 case 16: 685 ctl = 0x17b3; 686 pitch = init->pitch >> 1; 687 byteswap = 0x100; 688 break; 689 case 24: 690 ctl = 0x17b9; 691 pitch = init->pitch - (init->pitch >> 2); 692 byteswap = 0x200; 693 break; 694 case 32: 695 ctl = 0x17b5; 696 pitch = init->pitch; 697 byteswap = 0x300; 698 break; 699 } 700 if (par->ramdac == TVP) 701 ctl -= 0x30; 702 703 write_reg_le32(par->dc_regs, HES, init->hes); 704 write_reg_le32(par->dc_regs, HEB, init->heb); 705 write_reg_le32(par->dc_regs, HSB, init->hsb); 706 write_reg_le32(par->dc_regs, HT, init->ht); 707 write_reg_le32(par->dc_regs, VES, init->ves); 708 write_reg_le32(par->dc_regs, VEB, init->veb); 709 write_reg_le32(par->dc_regs, VSB, init->vsb); 710 write_reg_le32(par->dc_regs, VT, init->vt); 711 write_reg_le32(par->dc_regs, VIL, init->vil); 712 write_reg_le32(par->dc_regs, HCIV, 1); 713 write_reg_le32(par->dc_regs, VCIV, 1); 714 write_reg_le32(par->dc_regs, TCDR, 4); 715 write_reg_le32(par->dc_regs, RRCIV, 1); 716 write_reg_le32(par->dc_regs, RRSC, 0x980); 717 write_reg_le32(par->dc_regs, RRCR, 0x11); 718 719 if (par->ramdac == IBM) { 720 write_reg_le32(par->dc_regs, HRIR, 0x0100); 721 write_reg_le32(par->dc_regs, CMR, 0x00ff); 722 write_reg_le32(par->dc_regs, SRGCTL, 0x0073); 723 } else { 724 write_reg_le32(par->dc_regs, HRIR, 0x0200); 725 write_reg_le32(par->dc_regs, CMR, 0x01ff); 726 write_reg_le32(par->dc_regs, SRGCTL, 0x0003); 727 } 728 729 switch (info->fix.smem_len) { 730 case 0x200000: 731 scr = 0x059d | byteswap; 732 break; 733 /* case 0x400000: 734 case 0x800000: */ 735 default: 736 pitch >>= 1; 737 scr = 0x150dd | byteswap; 738 break; 739 } 740 741 write_reg_le32(par->dc_regs, SCR, scr); 742 write_reg_le32(par->dc_regs, SPR, pitch); 743 write_reg_le32(par->dc_regs, STGCTL, ctl); 744 } 745 746 static inline void 747 set_offset (struct fb_var_screeninfo *var, struct fb_info *info) 748 { 749 struct imstt_par *par = info->par; 750 __u32 off = var->yoffset * (info->fix.line_length >> 3) 751 + ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3); 752 write_reg_le32(par->dc_regs, SSR, off); 753 } 754 755 static inline void 756 set_555 (struct imstt_par *par) 757 { 758 if (par->ramdac == IBM) { 759 par->cmap_regs[PIDXHI] = 0; eieio(); 760 par->cmap_regs[PIDXLO] = BPP16; eieio(); 761 par->cmap_regs[PIDXDATA] = 0x01; eieio(); 762 } else { 763 par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); 764 par->cmap_regs[TVPIDATA] = 0x44; eieio(); 765 } 766 } 767 768 static inline void 769 set_565 (struct imstt_par *par) 770 { 771 if (par->ramdac == IBM) { 772 par->cmap_regs[PIDXHI] = 0; eieio(); 773 par->cmap_regs[PIDXLO] = BPP16; eieio(); 774 par->cmap_regs[PIDXDATA] = 0x03; eieio(); 775 } else { 776 par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio(); 777 par->cmap_regs[TVPIDATA] = 0x45; eieio(); 778 } 779 } 780 781 static int 782 imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 783 { 784 if ((var->bits_per_pixel != 8 && var->bits_per_pixel != 16 785 && var->bits_per_pixel != 24 && var->bits_per_pixel != 32) 786 || var->xres_virtual < var->xres || var->yres_virtual < var->yres 787 || var->nonstd 788 || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) 789 return -EINVAL; 790 791 if ((var->xres * var->yres) * (var->bits_per_pixel >> 3) > info->fix.smem_len 792 || (var->xres_virtual * var->yres_virtual) * (var->bits_per_pixel >> 3) > info->fix.smem_len) 793 return -EINVAL; 794 795 switch (var->bits_per_pixel) { 796 case 8: 797 var->red.offset = 0; 798 var->red.length = 8; 799 var->green.offset = 0; 800 var->green.length = 8; 801 var->blue.offset = 0; 802 var->blue.length = 8; 803 var->transp.offset = 0; 804 var->transp.length = 0; 805 break; 806 case 16: /* RGB 555 or 565 */ 807 if (var->green.length != 6) 808 var->red.offset = 10; 809 var->red.length = 5; 810 var->green.offset = 5; 811 if (var->green.length != 6) 812 var->green.length = 5; 813 var->blue.offset = 0; 814 var->blue.length = 5; 815 var->transp.offset = 0; 816 var->transp.length = 0; 817 break; 818 case 24: /* RGB 888 */ 819 var->red.offset = 16; 820 var->red.length = 8; 821 var->green.offset = 8; 822 var->green.length = 8; 823 var->blue.offset = 0; 824 var->blue.length = 8; 825 var->transp.offset = 0; 826 var->transp.length = 0; 827 break; 828 case 32: /* RGBA 8888 */ 829 var->red.offset = 16; 830 var->red.length = 8; 831 var->green.offset = 8; 832 var->green.length = 8; 833 var->blue.offset = 0; 834 var->blue.length = 8; 835 var->transp.offset = 24; 836 var->transp.length = 8; 837 break; 838 } 839 840 if (var->yres == var->yres_virtual) { 841 __u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2)); 842 var->yres_virtual = ((vram << 3) / var->bits_per_pixel) / var->xres_virtual; 843 if (var->yres_virtual < var->yres) 844 var->yres_virtual = var->yres; 845 } 846 847 var->red.msb_right = 0; 848 var->green.msb_right = 0; 849 var->blue.msb_right = 0; 850 var->transp.msb_right = 0; 851 var->height = -1; 852 var->width = -1; 853 var->vmode = FB_VMODE_NONINTERLACED; 854 var->left_margin = var->right_margin = 16; 855 var->upper_margin = var->lower_margin = 16; 856 var->hsync_len = var->vsync_len = 8; 857 return 0; 858 } 859 860 static int 861 imsttfb_set_par(struct fb_info *info) 862 { 863 struct imstt_par *par = info->par; 864 865 if (!compute_imstt_regvals(par, info->var.xres, info->var.yres)) 866 return -EINVAL; 867 868 if (info->var.green.length == 6) 869 set_565(par); 870 else 871 set_555(par); 872 set_imstt_regvals(info, info->var.bits_per_pixel); 873 info->var.pixclock = 1000000 / getclkMHz(par); 874 return 0; 875 } 876 877 static int 878 imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, 879 u_int transp, struct fb_info *info) 880 { 881 struct imstt_par *par = info->par; 882 u_int bpp = info->var.bits_per_pixel; 883 884 if (regno > 255) 885 return 1; 886 887 red >>= 8; 888 green >>= 8; 889 blue >>= 8; 890 891 /* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */ 892 if (0 && bpp == 16) /* screws up X */ 893 par->cmap_regs[PADDRW] = regno << 3; 894 else 895 par->cmap_regs[PADDRW] = regno; 896 eieio(); 897 898 par->cmap_regs[PDATA] = red; eieio(); 899 par->cmap_regs[PDATA] = green; eieio(); 900 par->cmap_regs[PDATA] = blue; eieio(); 901 902 if (regno < 16) 903 switch (bpp) { 904 case 16: 905 par->palette[regno] = 906 (regno << (info->var.green.length == 907 5 ? 10 : 11)) | (regno << 5) | regno; 908 break; 909 case 24: 910 par->palette[regno] = 911 (regno << 16) | (regno << 8) | regno; 912 break; 913 case 32: { 914 int i = (regno << 8) | regno; 915 par->palette[regno] = (i << 16) |i; 916 break; 917 } 918 } 919 return 0; 920 } 921 922 static int 923 imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 924 { 925 if (var->xoffset + info->var.xres > info->var.xres_virtual 926 || var->yoffset + info->var.yres > info->var.yres_virtual) 927 return -EINVAL; 928 929 info->var.xoffset = var->xoffset; 930 info->var.yoffset = var->yoffset; 931 set_offset(var, info); 932 return 0; 933 } 934 935 static int 936 imsttfb_blank(int blank, struct fb_info *info) 937 { 938 struct imstt_par *par = info->par; 939 __u32 ctrl; 940 941 ctrl = read_reg_le32(par->dc_regs, STGCTL); 942 if (blank > 0) { 943 switch (blank) { 944 case FB_BLANK_NORMAL: 945 case FB_BLANK_POWERDOWN: 946 ctrl &= ~0x00000380; 947 if (par->ramdac == IBM) { 948 par->cmap_regs[PIDXHI] = 0; eieio(); 949 par->cmap_regs[PIDXLO] = MISCTL2; eieio(); 950 par->cmap_regs[PIDXDATA] = 0x55; eieio(); 951 par->cmap_regs[PIDXLO] = MISCTL1; eieio(); 952 par->cmap_regs[PIDXDATA] = 0x11; eieio(); 953 par->cmap_regs[PIDXLO] = SYNCCTL; eieio(); 954 par->cmap_regs[PIDXDATA] = 0x0f; eieio(); 955 par->cmap_regs[PIDXLO] = PWRMNGMT; eieio(); 956 par->cmap_regs[PIDXDATA] = 0x1f; eieio(); 957 par->cmap_regs[PIDXLO] = CLKCTL; eieio(); 958 par->cmap_regs[PIDXDATA] = 0xc0; 959 } 960 break; 961 case FB_BLANK_VSYNC_SUSPEND: 962 ctrl &= ~0x00000020; 963 break; 964 case FB_BLANK_HSYNC_SUSPEND: 965 ctrl &= ~0x00000010; 966 break; 967 } 968 } else { 969 if (par->ramdac == IBM) { 970 ctrl |= 0x000017b0; 971 par->cmap_regs[PIDXHI] = 0; eieio(); 972 par->cmap_regs[PIDXLO] = CLKCTL; eieio(); 973 par->cmap_regs[PIDXDATA] = 0x01; eieio(); 974 par->cmap_regs[PIDXLO] = PWRMNGMT; eieio(); 975 par->cmap_regs[PIDXDATA] = 0x00; eieio(); 976 par->cmap_regs[PIDXLO] = SYNCCTL; eieio(); 977 par->cmap_regs[PIDXDATA] = 0x00; eieio(); 978 par->cmap_regs[PIDXLO] = MISCTL1; eieio(); 979 par->cmap_regs[PIDXDATA] = 0x01; eieio(); 980 par->cmap_regs[PIDXLO] = MISCTL2; eieio(); 981 par->cmap_regs[PIDXDATA] = 0x45; eieio(); 982 } else 983 ctrl |= 0x00001780; 984 } 985 write_reg_le32(par->dc_regs, STGCTL, ctrl); 986 return 0; 987 } 988 989 static void 990 imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 991 { 992 struct imstt_par *par = info->par; 993 __u32 Bpp, line_pitch, bgc, dx, dy, width, height; 994 995 bgc = rect->color; 996 bgc |= (bgc << 8); 997 bgc |= (bgc << 16); 998 999 Bpp = info->var.bits_per_pixel >> 3, 1000 line_pitch = info->fix.line_length; 1001 1002 dy = rect->dy * line_pitch; 1003 dx = rect->dx * Bpp; 1004 height = rect->height; 1005 height--; 1006 width = rect->width * Bpp; 1007 width--; 1008 1009 if (rect->rop == ROP_COPY) { 1010 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1011 write_reg_le32(par->dc_regs, DSA, dy + dx); 1012 write_reg_le32(par->dc_regs, CNT, (height << 16) | width); 1013 write_reg_le32(par->dc_regs, DP_OCTL, line_pitch); 1014 write_reg_le32(par->dc_regs, BI, 0xffffffff); 1015 write_reg_le32(par->dc_regs, MBC, 0xffffffff); 1016 write_reg_le32(par->dc_regs, CLR, bgc); 1017 write_reg_le32(par->dc_regs, BLTCTL, 0x840); /* 0x200000 */ 1018 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1019 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40); 1020 } else { 1021 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1022 write_reg_le32(par->dc_regs, DSA, dy + dx); 1023 write_reg_le32(par->dc_regs, S1SA, dy + dx); 1024 write_reg_le32(par->dc_regs, CNT, (height << 16) | width); 1025 write_reg_le32(par->dc_regs, DP_OCTL, line_pitch); 1026 write_reg_le32(par->dc_regs, SP, line_pitch); 1027 write_reg_le32(par->dc_regs, BLTCTL, 0x40005); 1028 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1029 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40); 1030 } 1031 } 1032 1033 static void 1034 imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 1035 { 1036 struct imstt_par *par = info->par; 1037 __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl; 1038 __u32 cnt, bltctl, sx, sy, dx, dy, height, width; 1039 1040 Bpp = info->var.bits_per_pixel >> 3, 1041 1042 sx = area->sx * Bpp; 1043 sy = area->sy; 1044 dx = area->dx * Bpp; 1045 dy = area->dy; 1046 height = area->height; 1047 height--; 1048 width = area->width * Bpp; 1049 width--; 1050 1051 line_pitch = info->fix.line_length; 1052 bltctl = 0x05; 1053 sp = line_pitch << 16; 1054 cnt = height << 16; 1055 1056 if (sy < dy) { 1057 sy += height; 1058 dy += height; 1059 sp |= -(line_pitch) & 0xffff; 1060 dp_octl = -(line_pitch) & 0xffff; 1061 } else { 1062 sp |= line_pitch; 1063 dp_octl = line_pitch; 1064 } 1065 if (sx < dx) { 1066 sx += width; 1067 dx += width; 1068 bltctl |= 0x80; 1069 cnt |= -(width) & 0xffff; 1070 } else { 1071 cnt |= width; 1072 } 1073 fb_offset_old = sy * line_pitch + sx; 1074 fb_offset_new = dy * line_pitch + dx; 1075 1076 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1077 write_reg_le32(par->dc_regs, S1SA, fb_offset_old); 1078 write_reg_le32(par->dc_regs, SP, sp); 1079 write_reg_le32(par->dc_regs, DSA, fb_offset_new); 1080 write_reg_le32(par->dc_regs, CNT, cnt); 1081 write_reg_le32(par->dc_regs, DP_OCTL, dp_octl); 1082 write_reg_le32(par->dc_regs, BLTCTL, bltctl); 1083 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80); 1084 while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40); 1085 } 1086 1087 #if 0 1088 static int 1089 imsttfb_load_cursor_image(struct imstt_par *par, int width, int height, __u8 fgc) 1090 { 1091 u_int x, y; 1092 1093 if (width > 32 || height > 32) 1094 return -EINVAL; 1095 1096 if (par->ramdac == IBM) { 1097 par->cmap_regs[PIDXHI] = 1; eieio(); 1098 for (x = 0; x < 0x100; x++) { 1099 par->cmap_regs[PIDXLO] = x; eieio(); 1100 par->cmap_regs[PIDXDATA] = 0x00; eieio(); 1101 } 1102 par->cmap_regs[PIDXHI] = 1; eieio(); 1103 for (y = 0; y < height; y++) 1104 for (x = 0; x < width >> 2; x++) { 1105 par->cmap_regs[PIDXLO] = x + y * 8; eieio(); 1106 par->cmap_regs[PIDXDATA] = 0xff; eieio(); 1107 } 1108 par->cmap_regs[PIDXHI] = 0; eieio(); 1109 par->cmap_regs[PIDXLO] = CURS1R; eieio(); 1110 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1111 par->cmap_regs[PIDXLO] = CURS1G; eieio(); 1112 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1113 par->cmap_regs[PIDXLO] = CURS1B; eieio(); 1114 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1115 par->cmap_regs[PIDXLO] = CURS2R; eieio(); 1116 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1117 par->cmap_regs[PIDXLO] = CURS2G; eieio(); 1118 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1119 par->cmap_regs[PIDXLO] = CURS2B; eieio(); 1120 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1121 par->cmap_regs[PIDXLO] = CURS3R; eieio(); 1122 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1123 par->cmap_regs[PIDXLO] = CURS3G; eieio(); 1124 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1125 par->cmap_regs[PIDXLO] = CURS3B; eieio(); 1126 par->cmap_regs[PIDXDATA] = fgc; eieio(); 1127 } else { 1128 par->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); 1129 par->cmap_regs[TVPIDATA] &= 0x03; eieio(); 1130 par->cmap_regs[TVPADDRW] = 0; eieio(); 1131 for (x = 0; x < 0x200; x++) { 1132 par->cmap_regs[TVPCRDAT] = 0x00; eieio(); 1133 } 1134 for (x = 0; x < 0x200; x++) { 1135 par->cmap_regs[TVPCRDAT] = 0xff; eieio(); 1136 } 1137 par->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); 1138 par->cmap_regs[TVPIDATA] &= 0x03; eieio(); 1139 for (y = 0; y < height; y++) 1140 for (x = 0; x < width >> 3; x++) { 1141 par->cmap_regs[TVPADDRW] = x + y * 8; eieio(); 1142 par->cmap_regs[TVPCRDAT] = 0xff; eieio(); 1143 } 1144 par->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); 1145 par->cmap_regs[TVPIDATA] |= 0x08; eieio(); 1146 for (y = 0; y < height; y++) 1147 for (x = 0; x < width >> 3; x++) { 1148 par->cmap_regs[TVPADDRW] = x + y * 8; eieio(); 1149 par->cmap_regs[TVPCRDAT] = 0xff; eieio(); 1150 } 1151 par->cmap_regs[TVPCADRW] = 0x00; eieio(); 1152 for (x = 0; x < 12; x++) { 1153 par->cmap_regs[TVPCDATA] = fgc; 1154 eieio(); 1155 } 1156 } 1157 return 1; 1158 } 1159 1160 static void 1161 imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on) 1162 { 1163 if (par->ramdac == IBM) { 1164 par->cmap_regs[PIDXHI] = 0; eieio(); 1165 if (!on) { 1166 par->cmap_regs[PIDXLO] = CURSCTL; eieio(); 1167 par->cmap_regs[PIDXDATA] = 0x00; eieio(); 1168 } else { 1169 par->cmap_regs[PIDXLO] = CURSXHI; eieio(); 1170 par->cmap_regs[PIDXDATA] = d->dx >> 8; eieio(); 1171 par->cmap_regs[PIDXLO] = CURSXLO; eieio(); 1172 par->cmap_regs[PIDXDATA] = d->dx & 0xff;eieio(); 1173 par->cmap_regs[PIDXLO] = CURSYHI; eieio(); 1174 par->cmap_regs[PIDXDATA] = d->dy >> 8; eieio(); 1175 par->cmap_regs[PIDXLO] = CURSYLO; eieio(); 1176 par->cmap_regs[PIDXDATA] = d->dy & 0xff;eieio(); 1177 par->cmap_regs[PIDXLO] = CURSCTL; eieio(); 1178 par->cmap_regs[PIDXDATA] = 0x02; eieio(); 1179 } 1180 } else { 1181 if (!on) { 1182 par->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); 1183 par->cmap_regs[TVPIDATA] = 0x00; eieio(); 1184 } else { 1185 __u16 x = d->dx + 0x40, y = d->dy + 0x40; 1186 1187 par->cmap_regs[TVPCXPOH] = x >> 8; eieio(); 1188 par->cmap_regs[TVPCXPOL] = x & 0xff; eieio(); 1189 par->cmap_regs[TVPCYPOH] = y >> 8; eieio(); 1190 par->cmap_regs[TVPCYPOL] = y & 0xff; eieio(); 1191 par->cmap_regs[TVPADDRW] = TVPIRICC; eieio(); 1192 par->cmap_regs[TVPIDATA] = 0x02; eieio(); 1193 } 1194 } 1195 } 1196 1197 static int 1198 imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1199 { 1200 struct imstt_par *par = info->par; 1201 u32 flags = cursor->set, fg, bg, xx, yy; 1202 1203 if (cursor->dest == NULL && cursor->rop == ROP_XOR) 1204 return 1; 1205 1206 imstt_set_cursor(info, cursor, 0); 1207 1208 if (flags & FB_CUR_SETPOS) { 1209 xx = cursor->image.dx - info->var.xoffset; 1210 yy = cursor->image.dy - info->var.yoffset; 1211 } 1212 1213 if (flags & FB_CUR_SETSIZE) { 1214 } 1215 1216 if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) { 1217 int fg_idx = cursor->image.fg_color; 1218 int width = (cursor->image.width+7)/8; 1219 u8 *dat = (u8 *) cursor->image.data; 1220 u8 *dst = (u8 *) cursor->dest; 1221 u8 *msk = (u8 *) cursor->mask; 1222 1223 switch (cursor->rop) { 1224 case ROP_XOR: 1225 for (i = 0; i < cursor->image.height; i++) { 1226 for (j = 0; j < width; j++) { 1227 d_idx = i * MAX_CURS/8 + j; 1228 data[d_idx] = byte_rev[dat[s_idx] ^ 1229 dst[s_idx]]; 1230 mask[d_idx] = byte_rev[msk[s_idx]]; 1231 s_idx++; 1232 } 1233 } 1234 break; 1235 case ROP_COPY: 1236 default: 1237 for (i = 0; i < cursor->image.height; i++) { 1238 for (j = 0; j < width; j++) { 1239 d_idx = i * MAX_CURS/8 + j; 1240 data[d_idx] = byte_rev[dat[s_idx]]; 1241 mask[d_idx] = byte_rev[msk[s_idx]]; 1242 s_idx++; 1243 } 1244 } 1245 break; 1246 } 1247 1248 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) | 1249 ((info->cmap.green[fg_idx] & 0xf8) << 2) | 1250 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15; 1251 1252 imsttfb_load_cursor_image(par, xx, yy, fgc); 1253 } 1254 if (cursor->enable) 1255 imstt_set_cursor(info, cursor, 1); 1256 return 0; 1257 } 1258 #endif 1259 1260 #define FBIMSTT_SETREG 0x545401 1261 #define FBIMSTT_GETREG 0x545402 1262 #define FBIMSTT_SETCMAPREG 0x545403 1263 #define FBIMSTT_GETCMAPREG 0x545404 1264 #define FBIMSTT_SETIDXREG 0x545405 1265 #define FBIMSTT_GETIDXREG 0x545406 1266 1267 static int 1268 imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) 1269 { 1270 struct imstt_par *par = info->par; 1271 void __user *argp = (void __user *)arg; 1272 __u32 reg[2]; 1273 __u8 idx[2]; 1274 1275 switch (cmd) { 1276 case FBIMSTT_SETREG: 1277 if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0])) 1278 return -EFAULT; 1279 write_reg_le32(par->dc_regs, reg[0], reg[1]); 1280 return 0; 1281 case FBIMSTT_GETREG: 1282 if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0])) 1283 return -EFAULT; 1284 reg[1] = read_reg_le32(par->dc_regs, reg[0]); 1285 if (copy_to_user((void __user *)(arg + 4), ®[1], 4)) 1286 return -EFAULT; 1287 return 0; 1288 case FBIMSTT_SETCMAPREG: 1289 if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0])) 1290 return -EFAULT; 1291 write_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0], reg[1]); 1292 return 0; 1293 case FBIMSTT_GETCMAPREG: 1294 if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0])) 1295 return -EFAULT; 1296 reg[1] = read_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0]); 1297 if (copy_to_user((void __user *)(arg + 4), ®[1], 4)) 1298 return -EFAULT; 1299 return 0; 1300 case FBIMSTT_SETIDXREG: 1301 if (copy_from_user(idx, argp, 2)) 1302 return -EFAULT; 1303 par->cmap_regs[PIDXHI] = 0; eieio(); 1304 par->cmap_regs[PIDXLO] = idx[0]; eieio(); 1305 par->cmap_regs[PIDXDATA] = idx[1]; eieio(); 1306 return 0; 1307 case FBIMSTT_GETIDXREG: 1308 if (copy_from_user(idx, argp, 1)) 1309 return -EFAULT; 1310 par->cmap_regs[PIDXHI] = 0; eieio(); 1311 par->cmap_regs[PIDXLO] = idx[0]; eieio(); 1312 idx[1] = par->cmap_regs[PIDXDATA]; 1313 if (copy_to_user((void __user *)(arg + 1), &idx[1], 1)) 1314 return -EFAULT; 1315 return 0; 1316 default: 1317 return -ENOIOCTLCMD; 1318 } 1319 } 1320 1321 static const struct pci_device_id imsttfb_pci_tbl[] = { 1322 { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT128, 1323 PCI_ANY_ID, PCI_ANY_ID, 0, 0, IBM }, 1324 { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT3D, 1325 PCI_ANY_ID, PCI_ANY_ID, 0, 0, TVP }, 1326 { 0, } 1327 }; 1328 1329 MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl); 1330 1331 static struct pci_driver imsttfb_pci_driver = { 1332 .name = "imsttfb", 1333 .id_table = imsttfb_pci_tbl, 1334 .probe = imsttfb_probe, 1335 .remove = imsttfb_remove, 1336 }; 1337 1338 static struct fb_ops imsttfb_ops = { 1339 .owner = THIS_MODULE, 1340 .fb_check_var = imsttfb_check_var, 1341 .fb_set_par = imsttfb_set_par, 1342 .fb_setcolreg = imsttfb_setcolreg, 1343 .fb_pan_display = imsttfb_pan_display, 1344 .fb_blank = imsttfb_blank, 1345 .fb_fillrect = imsttfb_fillrect, 1346 .fb_copyarea = imsttfb_copyarea, 1347 .fb_imageblit = cfb_imageblit, 1348 .fb_ioctl = imsttfb_ioctl, 1349 }; 1350 1351 static void init_imstt(struct fb_info *info) 1352 { 1353 struct imstt_par *par = info->par; 1354 __u32 i, tmp, *ip, *end; 1355 1356 tmp = read_reg_le32(par->dc_regs, PRC); 1357 if (par->ramdac == IBM) 1358 info->fix.smem_len = (tmp & 0x0004) ? 0x400000 : 0x200000; 1359 else 1360 info->fix.smem_len = 0x800000; 1361 1362 ip = (__u32 *)info->screen_base; 1363 end = (__u32 *)(info->screen_base + info->fix.smem_len); 1364 while (ip < end) 1365 *ip++ = 0; 1366 1367 /* initialize the card */ 1368 tmp = read_reg_le32(par->dc_regs, STGCTL); 1369 write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1); 1370 write_reg_le32(par->dc_regs, SSR, 0); 1371 1372 /* set default values for DAC registers */ 1373 if (par->ramdac == IBM) { 1374 par->cmap_regs[PPMASK] = 0xff; 1375 eieio(); 1376 par->cmap_regs[PIDXHI] = 0; 1377 eieio(); 1378 for (i = 0; i < ARRAY_SIZE(ibm_initregs); i++) { 1379 par->cmap_regs[PIDXLO] = ibm_initregs[i].addr; 1380 eieio(); 1381 par->cmap_regs[PIDXDATA] = ibm_initregs[i].value; 1382 eieio(); 1383 } 1384 } else { 1385 for (i = 0; i < ARRAY_SIZE(tvp_initregs); i++) { 1386 par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr; 1387 eieio(); 1388 par->cmap_regs[TVPIDATA] = tvp_initregs[i].value; 1389 eieio(); 1390 } 1391 } 1392 1393 #if USE_NV_MODES && defined(CONFIG_PPC32) 1394 { 1395 int vmode = init_vmode, cmode = init_cmode; 1396 1397 if (vmode == -1) { 1398 vmode = nvram_read_byte(NV_VMODE); 1399 if (vmode <= 0 || vmode > VMODE_MAX) 1400 vmode = VMODE_640_480_67; 1401 } 1402 if (cmode == -1) { 1403 cmode = nvram_read_byte(NV_CMODE); 1404 if (cmode < CMODE_8 || cmode > CMODE_32) 1405 cmode = CMODE_8; 1406 } 1407 if (mac_vmode_to_var(vmode, cmode, &info->var)) { 1408 info->var.xres = info->var.xres_virtual = INIT_XRES; 1409 info->var.yres = info->var.yres_virtual = INIT_YRES; 1410 info->var.bits_per_pixel = INIT_BPP; 1411 } 1412 } 1413 #else 1414 info->var.xres = info->var.xres_virtual = INIT_XRES; 1415 info->var.yres = info->var.yres_virtual = INIT_YRES; 1416 info->var.bits_per_pixel = INIT_BPP; 1417 #endif 1418 1419 if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len 1420 || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { 1421 printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); 1422 framebuffer_release(info); 1423 return; 1424 } 1425 1426 sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP"); 1427 info->fix.mmio_len = 0x1000; 1428 info->fix.accel = FB_ACCEL_IMS_TWINTURBO; 1429 info->fix.type = FB_TYPE_PACKED_PIXELS; 1430 info->fix.visual = info->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR 1431 : FB_VISUAL_DIRECTCOLOR; 1432 info->fix.line_length = info->var.xres * (info->var.bits_per_pixel >> 3); 1433 info->fix.xpanstep = 8; 1434 info->fix.ypanstep = 1; 1435 info->fix.ywrapstep = 0; 1436 1437 info->var.accel_flags = FB_ACCELF_TEXT; 1438 1439 // if (par->ramdac == IBM) 1440 // imstt_cursor_init(info); 1441 if (info->var.green.length == 6) 1442 set_565(par); 1443 else 1444 set_555(par); 1445 set_imstt_regvals(info, info->var.bits_per_pixel); 1446 1447 info->var.pixclock = 1000000 / getclkMHz(par); 1448 1449 info->fbops = &imsttfb_ops; 1450 info->flags = FBINFO_DEFAULT | 1451 FBINFO_HWACCEL_COPYAREA | 1452 FBINFO_HWACCEL_FILLRECT | 1453 FBINFO_HWACCEL_YPAN; 1454 1455 fb_alloc_cmap(&info->cmap, 0, 0); 1456 1457 if (register_framebuffer(info) < 0) { 1458 framebuffer_release(info); 1459 return; 1460 } 1461 1462 tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8; 1463 fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n", 1464 info->fix.id, info->fix.smem_len >> 20, tmp); 1465 } 1466 1467 static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1468 { 1469 unsigned long addr, size; 1470 struct imstt_par *par; 1471 struct fb_info *info; 1472 struct device_node *dp; 1473 1474 dp = pci_device_to_OF_node(pdev); 1475 if(dp) 1476 printk(KERN_INFO "%s: OF name %s\n",__func__, dp->name); 1477 else if (IS_ENABLED(CONFIG_OF)) 1478 printk(KERN_ERR "imsttfb: no OF node for pci device\n"); 1479 1480 info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev); 1481 1482 if (!info) { 1483 printk(KERN_ERR "imsttfb: Can't allocate memory\n"); 1484 return -ENOMEM; 1485 } 1486 1487 par = info->par; 1488 1489 addr = pci_resource_start (pdev, 0); 1490 size = pci_resource_len (pdev, 0); 1491 1492 if (!request_mem_region(addr, size, "imsttfb")) { 1493 printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); 1494 framebuffer_release(info); 1495 return -ENODEV; 1496 } 1497 1498 switch (pdev->device) { 1499 case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */ 1500 par->ramdac = IBM; 1501 if (dp && ((strcmp(dp->name, "IMS,tt128mb8") == 0) || 1502 (strcmp(dp->name, "IMS,tt128mb8A") == 0))) 1503 par->ramdac = TVP; 1504 break; 1505 case PCI_DEVICE_ID_IMS_TT3D: /* IMS,tt3d */ 1506 par->ramdac = TVP; 1507 break; 1508 default: 1509 printk(KERN_INFO "imsttfb: Device 0x%x unknown, " 1510 "contact maintainer.\n", pdev->device); 1511 release_mem_region(addr, size); 1512 framebuffer_release(info); 1513 return -ENODEV; 1514 } 1515 1516 info->fix.smem_start = addr; 1517 info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 1518 0x400000 : 0x800000); 1519 info->fix.mmio_start = addr + 0x800000; 1520 par->dc_regs = ioremap(addr + 0x800000, 0x1000); 1521 par->cmap_regs_phys = addr + 0x840000; 1522 par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); 1523 info->pseudo_palette = par->palette; 1524 init_imstt(info); 1525 1526 pci_set_drvdata(pdev, info); 1527 return 0; 1528 } 1529 1530 static void imsttfb_remove(struct pci_dev *pdev) 1531 { 1532 struct fb_info *info = pci_get_drvdata(pdev); 1533 struct imstt_par *par = info->par; 1534 int size = pci_resource_len(pdev, 0); 1535 1536 unregister_framebuffer(info); 1537 iounmap(par->cmap_regs); 1538 iounmap(par->dc_regs); 1539 iounmap(info->screen_base); 1540 release_mem_region(info->fix.smem_start, size); 1541 framebuffer_release(info); 1542 } 1543 1544 #ifndef MODULE 1545 static int __init 1546 imsttfb_setup(char *options) 1547 { 1548 char *this_opt; 1549 1550 if (!options || !*options) 1551 return 0; 1552 1553 while ((this_opt = strsep(&options, ",")) != NULL) { 1554 if (!strncmp(this_opt, "font:", 5)) { 1555 char *p; 1556 int i; 1557 1558 p = this_opt + 5; 1559 for (i = 0; i < sizeof(fontname) - 1; i++) 1560 if (!*p || *p == ' ' || *p == ',') 1561 break; 1562 memcpy(fontname, this_opt + 5, i); 1563 fontname[i] = 0; 1564 } else if (!strncmp(this_opt, "inverse", 7)) { 1565 inverse = 1; 1566 fb_invert_cmaps(); 1567 } 1568 #if defined(CONFIG_PPC) 1569 else if (!strncmp(this_opt, "vmode:", 6)) { 1570 int vmode = simple_strtoul(this_opt+6, NULL, 0); 1571 if (vmode > 0 && vmode <= VMODE_MAX) 1572 init_vmode = vmode; 1573 } else if (!strncmp(this_opt, "cmode:", 6)) { 1574 int cmode = simple_strtoul(this_opt+6, NULL, 0); 1575 switch (cmode) { 1576 case CMODE_8: 1577 case 8: 1578 init_cmode = CMODE_8; 1579 break; 1580 case CMODE_16: 1581 case 15: 1582 case 16: 1583 init_cmode = CMODE_16; 1584 break; 1585 case CMODE_32: 1586 case 24: 1587 case 32: 1588 init_cmode = CMODE_32; 1589 break; 1590 } 1591 } 1592 #endif 1593 } 1594 return 0; 1595 } 1596 1597 #endif /* MODULE */ 1598 1599 static int __init imsttfb_init(void) 1600 { 1601 #ifndef MODULE 1602 char *option = NULL; 1603 1604 if (fb_get_options("imsttfb", &option)) 1605 return -ENODEV; 1606 1607 imsttfb_setup(option); 1608 #endif 1609 return pci_register_driver(&imsttfb_pci_driver); 1610 } 1611 1612 static void __exit imsttfb_exit(void) 1613 { 1614 pci_unregister_driver(&imsttfb_pci_driver); 1615 } 1616 1617 MODULE_LICENSE("GPL"); 1618 1619 module_init(imsttfb_init); 1620 module_exit(imsttfb_exit); 1621 1622