1 /* 2 * ATI Frame Buffer Device Driver Core 3 * 4 * Copyright (C) 2004 Alex Kern <alex.kern@gmx.de> 5 * Copyright (C) 1997-2001 Geert Uytterhoeven 6 * Copyright (C) 1998 Bernd Harries 7 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) 8 * 9 * This driver supports the following ATI graphics chips: 10 * - ATI Mach64 11 * 12 * To do: add support for 13 * - ATI Rage128 (from aty128fb.c) 14 * - ATI Radeon (from radeonfb.c) 15 * 16 * This driver is partly based on the PowerMac console driver: 17 * 18 * Copyright (C) 1996 Paul Mackerras 19 * 20 * and on the PowerMac ATI/mach64 display driver: 21 * 22 * Copyright (C) 1997 Michael AK Tesch 23 * 24 * with work by Jon Howell 25 * Harry AC Eaton 26 * Anthony Tong <atong@uiuc.edu> 27 * 28 * Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern 29 * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug. 30 * 31 * This file is subject to the terms and conditions of the GNU General Public 32 * License. See the file COPYING in the main directory of this archive for 33 * more details. 34 * 35 * Many thanks to Nitya from ATI devrel for support and patience ! 36 */ 37 38 /****************************************************************************** 39 40 TODO: 41 42 - cursor support on all cards and all ramdacs. 43 - cursor parameters controlable via ioctl()s. 44 - guess PLL and MCLK based on the original PLL register values initialized 45 by Open Firmware (if they are initialized). BIOS is done 46 47 (Anyone with Mac to help with this?) 48 49 ******************************************************************************/ 50 51 #include <linux/compat.h> 52 #include <linux/module.h> 53 #include <linux/moduleparam.h> 54 #include <linux/kernel.h> 55 #include <linux/errno.h> 56 #include <linux/string.h> 57 #include <linux/mm.h> 58 #include <linux/slab.h> 59 #include <linux/vmalloc.h> 60 #include <linux/delay.h> 61 #include <linux/compiler.h> 62 #include <linux/console.h> 63 #include <linux/fb.h> 64 #include <linux/init.h> 65 #include <linux/pci.h> 66 #include <linux/interrupt.h> 67 #include <linux/spinlock.h> 68 #include <linux/wait.h> 69 #include <linux/backlight.h> 70 #include <linux/reboot.h> 71 #include <linux/dmi.h> 72 73 #include <asm/io.h> 74 #include <linux/uaccess.h> 75 76 #include <video/mach64.h> 77 #include "atyfb.h" 78 #include "ati_ids.h" 79 80 #ifdef __powerpc__ 81 #include <asm/machdep.h> 82 #include "../macmodes.h" 83 #endif 84 #ifdef __sparc__ 85 #include <asm/fbio.h> 86 #include <asm/oplib.h> 87 #include <asm/prom.h> 88 #endif 89 90 #ifdef CONFIG_ADB_PMU 91 #include <linux/adb.h> 92 #include <linux/pmu.h> 93 #endif 94 #ifdef CONFIG_BOOTX_TEXT 95 #include <asm/btext.h> 96 #endif 97 #ifdef CONFIG_PMAC_BACKLIGHT 98 #include <asm/backlight.h> 99 #endif 100 101 /* 102 * Debug flags. 103 */ 104 #undef DEBUG 105 /*#define DEBUG*/ 106 107 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */ 108 /* - must be large enough to catch all GUI-Regs */ 109 /* - must be aligned to a PAGE boundary */ 110 #define GUI_RESERVE (1 * PAGE_SIZE) 111 112 /* FIXME: remove the FAIL definition */ 113 #define FAIL(msg) do { \ 114 if (!(var->activate & FB_ACTIVATE_TEST)) \ 115 printk(KERN_CRIT "atyfb: " msg "\n"); \ 116 return -EINVAL; \ 117 } while (0) 118 #define FAIL_MAX(msg, x, _max_) do { \ 119 if (x > _max_) { \ 120 if (!(var->activate & FB_ACTIVATE_TEST)) \ 121 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \ 122 return -EINVAL; \ 123 } \ 124 } while (0) 125 #ifdef DEBUG 126 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args) 127 #else 128 #define DPRINTK(fmt, args...) no_printk(fmt, ##args) 129 #endif 130 131 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args) 132 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) 133 134 #if defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_GENERIC_LCD) || \ 135 defined(CONFIG_FB_ATY_BACKLIGHT) || defined (CONFIG_PPC_PMAC) 136 static const u32 lt_lcd_regs[] = { 137 CNFG_PANEL_LG, 138 LCD_GEN_CNTL_LG, 139 DSTN_CONTROL_LG, 140 HFB_PITCH_ADDR_LG, 141 HORZ_STRETCHING_LG, 142 VERT_STRETCHING_LG, 143 0, /* EXT_VERT_STRETCH */ 144 LT_GIO_LG, 145 POWER_MANAGEMENT_LG 146 }; 147 148 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) 149 { 150 if (M64_HAS(LT_LCD_REGS)) { 151 aty_st_le32(lt_lcd_regs[index], val, par); 152 } else { 153 unsigned long temp; 154 155 /* write addr byte */ 156 temp = aty_ld_le32(LCD_INDEX, par); 157 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par); 158 /* write the register value */ 159 aty_st_le32(LCD_DATA, val, par); 160 } 161 } 162 163 u32 aty_ld_lcd(int index, const struct atyfb_par *par) 164 { 165 if (M64_HAS(LT_LCD_REGS)) { 166 return aty_ld_le32(lt_lcd_regs[index], par); 167 } else { 168 unsigned long temp; 169 170 /* write addr byte */ 171 temp = aty_ld_le32(LCD_INDEX, par); 172 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par); 173 /* read the register value */ 174 return aty_ld_le32(LCD_DATA, par); 175 } 176 } 177 #else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) || 178 defined(CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */ 179 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) 180 { } 181 182 u32 aty_ld_lcd(int index, const struct atyfb_par *par) 183 { 184 return 0; 185 } 186 #endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) || 187 defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_PPC_PMAC) */ 188 189 #ifdef CONFIG_FB_ATY_GENERIC_LCD 190 /* 191 * ATIReduceRatio -- 192 * 193 * Reduce a fraction by factoring out the largest common divider of the 194 * fraction's numerator and denominator. 195 */ 196 static void ATIReduceRatio(int *Numerator, int *Denominator) 197 { 198 int Multiplier, Divider, Remainder; 199 200 Multiplier = *Numerator; 201 Divider = *Denominator; 202 203 while ((Remainder = Multiplier % Divider)) { 204 Multiplier = Divider; 205 Divider = Remainder; 206 } 207 208 *Numerator /= Divider; 209 *Denominator /= Divider; 210 } 211 #endif 212 /* 213 * The Hardware parameters for each card 214 */ 215 216 struct pci_mmap_map { 217 unsigned long voff; 218 unsigned long poff; 219 unsigned long size; 220 unsigned long prot_flag; 221 unsigned long prot_mask; 222 }; 223 224 static const struct fb_fix_screeninfo atyfb_fix = { 225 .id = "ATY Mach64", 226 .type = FB_TYPE_PACKED_PIXELS, 227 .visual = FB_VISUAL_PSEUDOCOLOR, 228 .xpanstep = 8, 229 .ypanstep = 1, 230 }; 231 232 /* 233 * Frame buffer device API 234 */ 235 236 static int atyfb_open(struct fb_info *info, int user); 237 static int atyfb_release(struct fb_info *info, int user); 238 static int atyfb_check_var(struct fb_var_screeninfo *var, 239 struct fb_info *info); 240 static int atyfb_set_par(struct fb_info *info); 241 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 242 u_int transp, struct fb_info *info); 243 static int atyfb_pan_display(struct fb_var_screeninfo *var, 244 struct fb_info *info); 245 static int atyfb_blank(int blank, struct fb_info *info); 246 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); 247 #ifdef CONFIG_COMPAT 248 static int atyfb_compat_ioctl(struct fb_info *info, u_int cmd, u_long arg) 249 { 250 return atyfb_ioctl(info, cmd, (u_long)compat_ptr(arg)); 251 } 252 #endif 253 254 #ifdef __sparc__ 255 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); 256 #endif 257 static int atyfb_sync(struct fb_info *info); 258 259 /* 260 * Internal routines 261 */ 262 263 static int aty_init(struct fb_info *info); 264 265 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); 266 267 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); 268 static int aty_var_to_crtc(const struct fb_info *info, 269 const struct fb_var_screeninfo *var, 270 struct crtc *crtc); 271 static int aty_crtc_to_var(const struct crtc *crtc, 272 struct fb_var_screeninfo *var); 273 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); 274 #ifdef CONFIG_PPC 275 static int read_aty_sense(const struct atyfb_par *par); 276 #endif 277 278 static DEFINE_MUTEX(reboot_lock); 279 static struct fb_info *reboot_info; 280 281 /* 282 * Interface used by the world 283 */ 284 285 static struct fb_var_screeninfo default_var = { 286 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 287 640, 480, 640, 480, 0, 0, 8, 0, 288 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 289 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2, 290 0, FB_VMODE_NONINTERLACED 291 }; 292 293 static const struct fb_videomode defmode = { 294 /* 640x480 @ 60 Hz, 31.5 kHz hsync */ 295 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 296 0, FB_VMODE_NONINTERLACED 297 }; 298 299 static struct fb_ops atyfb_ops = { 300 .owner = THIS_MODULE, 301 .fb_open = atyfb_open, 302 .fb_release = atyfb_release, 303 .fb_check_var = atyfb_check_var, 304 .fb_set_par = atyfb_set_par, 305 .fb_setcolreg = atyfb_setcolreg, 306 .fb_pan_display = atyfb_pan_display, 307 .fb_blank = atyfb_blank, 308 .fb_ioctl = atyfb_ioctl, 309 #ifdef CONFIG_COMPAT 310 .fb_compat_ioctl = atyfb_compat_ioctl, 311 #endif 312 .fb_fillrect = atyfb_fillrect, 313 .fb_copyarea = atyfb_copyarea, 314 .fb_imageblit = atyfb_imageblit, 315 #ifdef __sparc__ 316 .fb_mmap = atyfb_mmap, 317 #endif 318 .fb_sync = atyfb_sync, 319 }; 320 321 static bool noaccel; 322 static bool nomtrr; 323 static int vram; 324 static int pll; 325 static int mclk; 326 static int xclk; 327 static int comp_sync = -1; 328 static char *mode; 329 static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT); 330 331 #ifdef CONFIG_PPC 332 static int default_vmode = VMODE_CHOOSE; 333 static int default_cmode = CMODE_CHOOSE; 334 335 module_param_named(vmode, default_vmode, int, 0); 336 MODULE_PARM_DESC(vmode, "int: video mode for mac"); 337 module_param_named(cmode, default_cmode, int, 0); 338 MODULE_PARM_DESC(cmode, "int: color mode for mac"); 339 #endif 340 341 #ifdef CONFIG_ATARI 342 static unsigned int mach64_count = 0; 343 static unsigned long phys_vmembase[FB_MAX] = { 0, }; 344 static unsigned long phys_size[FB_MAX] = { 0, }; 345 static unsigned long phys_guiregbase[FB_MAX] = { 0, }; 346 #endif 347 348 /* top -> down is an evolution of mach64 chipset, any corrections? */ 349 #define ATI_CHIP_88800GX (M64F_GX) 350 #define ATI_CHIP_88800CX (M64F_GX) 351 352 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO) 353 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO) 354 355 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO) 356 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT) 357 358 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP) 359 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL) 360 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP) 361 362 /* FIXME what is this chip? */ 363 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP) 364 365 /* make sets shorter */ 366 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT) 367 368 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL) 369 /*#define ATI_CHIP_264GTDVD ?*/ 370 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL) 371 372 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE) 373 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 374 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 375 376 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) 377 #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) 378 379 static struct { 380 u16 pci_id; 381 const char *name; 382 int pll, mclk, xclk, ecp_max; 383 u32 features; 384 } aty_chips[] = { 385 #ifdef CONFIG_FB_ATY_GX 386 /* Mach64 GX */ 387 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX }, 388 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX }, 389 #endif /* CONFIG_FB_ATY_GX */ 390 391 #ifdef CONFIG_FB_ATY_CT 392 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT }, 393 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET }, 394 395 /* FIXME what is this chip? */ 396 { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT }, 397 398 { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT }, 399 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT }, 400 401 { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 }, 402 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB }, 403 404 { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, 405 406 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 }, 407 408 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, 409 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, 410 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, 411 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, 412 413 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, 414 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, 415 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, 416 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, 417 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, 418 419 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, 420 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, 421 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, 422 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 }, 423 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, 424 425 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, 426 { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, 427 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, 428 { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, 429 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, 430 { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL }, 431 432 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, 433 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, 434 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, 435 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, 436 #endif /* CONFIG_FB_ATY_CT */ 437 }; 438 439 /* 440 * Last page of 8 MB (4 MB on ISA) aperture is MMIO, 441 * unless the auxiliary register aperture is used. 442 */ 443 static void aty_fudge_framebuffer_len(struct fb_info *info) 444 { 445 struct atyfb_par *par = (struct atyfb_par *) info->par; 446 447 if (!par->aux_start && 448 (info->fix.smem_len == 0x800000 || 449 (par->bus_type == ISA && info->fix.smem_len == 0x400000))) 450 info->fix.smem_len -= GUI_RESERVE; 451 } 452 453 static int correct_chipset(struct atyfb_par *par) 454 { 455 u8 rev; 456 u16 type; 457 u32 chip_id; 458 const char *name; 459 int i; 460 461 for (i = (int)ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) 462 if (par->pci_id == aty_chips[i].pci_id) 463 break; 464 465 if (i < 0) 466 return -ENODEV; 467 468 name = aty_chips[i].name; 469 par->pll_limits.pll_max = aty_chips[i].pll; 470 par->pll_limits.mclk = aty_chips[i].mclk; 471 par->pll_limits.xclk = aty_chips[i].xclk; 472 par->pll_limits.ecp_max = aty_chips[i].ecp_max; 473 par->features = aty_chips[i].features; 474 475 chip_id = aty_ld_le32(CNFG_CHIP_ID, par); 476 type = chip_id & CFG_CHIP_TYPE; 477 rev = (chip_id & CFG_CHIP_REV) >> 24; 478 479 switch (par->pci_id) { 480 #ifdef CONFIG_FB_ATY_GX 481 case PCI_CHIP_MACH64GX: 482 if (type != 0x00d7) 483 return -ENODEV; 484 break; 485 case PCI_CHIP_MACH64CX: 486 if (type != 0x0057) 487 return -ENODEV; 488 break; 489 #endif 490 #ifdef CONFIG_FB_ATY_CT 491 case PCI_CHIP_MACH64VT: 492 switch (rev & 0x07) { 493 case 0x00: 494 switch (rev & 0xc0) { 495 case 0x00: 496 name = "ATI264VT (A3) (Mach64 VT)"; 497 par->pll_limits.pll_max = 170; 498 par->pll_limits.mclk = 67; 499 par->pll_limits.xclk = 67; 500 par->pll_limits.ecp_max = 80; 501 par->features = ATI_CHIP_264VT; 502 break; 503 case 0x40: 504 name = "ATI264VT2 (A4) (Mach64 VT)"; 505 par->pll_limits.pll_max = 200; 506 par->pll_limits.mclk = 67; 507 par->pll_limits.xclk = 67; 508 par->pll_limits.ecp_max = 80; 509 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; 510 break; 511 } 512 break; 513 case 0x01: 514 name = "ATI264VT3 (B1) (Mach64 VT)"; 515 par->pll_limits.pll_max = 200; 516 par->pll_limits.mclk = 67; 517 par->pll_limits.xclk = 67; 518 par->pll_limits.ecp_max = 80; 519 par->features = ATI_CHIP_264VTB; 520 break; 521 case 0x02: 522 name = "ATI264VT3 (B2) (Mach64 VT)"; 523 par->pll_limits.pll_max = 200; 524 par->pll_limits.mclk = 67; 525 par->pll_limits.xclk = 67; 526 par->pll_limits.ecp_max = 80; 527 par->features = ATI_CHIP_264VT3; 528 break; 529 } 530 break; 531 case PCI_CHIP_MACH64GT: 532 switch (rev & 0x07) { 533 case 0x01: 534 name = "3D RAGE II (Mach64 GT)"; 535 par->pll_limits.pll_max = 170; 536 par->pll_limits.mclk = 67; 537 par->pll_limits.xclk = 67; 538 par->pll_limits.ecp_max = 80; 539 par->features = ATI_CHIP_264GTB; 540 break; 541 case 0x02: 542 name = "3D RAGE II+ (Mach64 GT)"; 543 par->pll_limits.pll_max = 200; 544 par->pll_limits.mclk = 67; 545 par->pll_limits.xclk = 67; 546 par->pll_limits.ecp_max = 100; 547 par->features = ATI_CHIP_264GTB; 548 break; 549 } 550 break; 551 #endif 552 } 553 554 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev); 555 return 0; 556 } 557 558 static char ram_dram[] __maybe_unused = "DRAM"; 559 static char ram_resv[] __maybe_unused = "RESV"; 560 #ifdef CONFIG_FB_ATY_GX 561 static char ram_vram[] = "VRAM"; 562 #endif /* CONFIG_FB_ATY_GX */ 563 #ifdef CONFIG_FB_ATY_CT 564 static char ram_edo[] = "EDO"; 565 static char ram_sdram[] = "SDRAM (1:1)"; 566 static char ram_sgram[] = "SGRAM (1:1)"; 567 static char ram_sdram32[] = "SDRAM (2:1) (32-bit)"; 568 static char ram_wram[] = "WRAM"; 569 static char ram_off[] = "OFF"; 570 #endif /* CONFIG_FB_ATY_CT */ 571 572 573 #ifdef CONFIG_FB_ATY_GX 574 static char *aty_gx_ram[8] = { 575 ram_dram, ram_vram, ram_vram, ram_dram, 576 ram_dram, ram_vram, ram_vram, ram_resv 577 }; 578 #endif /* CONFIG_FB_ATY_GX */ 579 580 #ifdef CONFIG_FB_ATY_CT 581 static char *aty_ct_ram[8] = { 582 ram_off, ram_dram, ram_edo, ram_edo, 583 ram_sdram, ram_sgram, ram_wram, ram_resv 584 }; 585 static char *aty_xl_ram[8] = { 586 ram_off, ram_dram, ram_edo, ram_edo, 587 ram_sdram, ram_sgram, ram_sdram32, ram_resv 588 }; 589 #endif /* CONFIG_FB_ATY_CT */ 590 591 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, 592 struct atyfb_par *par) 593 { 594 u32 pixclock = var->pixclock; 595 #ifdef CONFIG_FB_ATY_GENERIC_LCD 596 u32 lcd_on_off; 597 par->pll.ct.xres = 0; 598 if (par->lcd_table != 0) { 599 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par); 600 if (lcd_on_off & LCD_ON) { 601 par->pll.ct.xres = var->xres; 602 pixclock = par->lcd_pixclock; 603 } 604 } 605 #endif 606 return pixclock; 607 } 608 609 #if defined(CONFIG_PPC) 610 611 /* 612 * Apple monitor sense 613 */ 614 615 static int read_aty_sense(const struct atyfb_par *par) 616 { 617 int sense, i; 618 619 aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */ 620 __delay(200); 621 aty_st_le32(GP_IO, 0, par); /* turn off outputs */ 622 __delay(2000); 623 i = aty_ld_le32(GP_IO, par); /* get primary sense value */ 624 sense = ((i & 0x3000) >> 3) | (i & 0x100); 625 626 /* drive each sense line low in turn and collect the other 2 */ 627 aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */ 628 __delay(2000); 629 i = aty_ld_le32(GP_IO, par); 630 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4); 631 aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */ 632 __delay(200); 633 634 aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */ 635 __delay(2000); 636 i = aty_ld_le32(GP_IO, par); 637 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6); 638 aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */ 639 __delay(200); 640 641 aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */ 642 __delay(2000); 643 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12; 644 aty_st_le32(GP_IO, 0, par); /* turn off outputs */ 645 return sense; 646 } 647 648 #endif /* defined(CONFIG_PPC) */ 649 650 /* ------------------------------------------------------------------------- */ 651 652 /* 653 * CRTC programming 654 */ 655 656 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) 657 { 658 #ifdef CONFIG_FB_ATY_GENERIC_LCD 659 if (par->lcd_table != 0) { 660 if (!M64_HAS(LT_LCD_REGS)) { 661 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); 662 aty_st_le32(LCD_INDEX, crtc->lcd_index, par); 663 } 664 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); 665 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); 666 667 668 /* switch to non shadow registers */ 669 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & 670 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); 671 672 /* save stretching */ 673 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); 674 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par); 675 if (!M64_HAS(LT_LCD_REGS)) 676 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par); 677 } 678 #endif 679 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 680 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 681 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par); 682 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par); 683 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par); 684 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par); 685 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 686 687 #ifdef CONFIG_FB_ATY_GENERIC_LCD 688 if (par->lcd_table != 0) { 689 /* switch to shadow registers */ 690 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | 691 SHADOW_EN | SHADOW_RW_EN, par); 692 693 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 694 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 695 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par); 696 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par); 697 698 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); 699 } 700 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 701 } 702 703 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) 704 { 705 #ifdef CONFIG_FB_ATY_GENERIC_LCD 706 if (par->lcd_table != 0) { 707 /* stop CRTC */ 708 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & 709 ~(CRTC_EXT_DISP_EN | CRTC_EN), par); 710 711 /* update non-shadow registers first */ 712 aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); 713 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & 714 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); 715 716 /* temporarily disable stretching */ 717 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching & 718 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); 719 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching & 720 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 | 721 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par); 722 } 723 #endif 724 /* turn off CRT */ 725 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par); 726 727 DPRINTK("setting up CRTC\n"); 728 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n", 729 ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3), 730 (((crtc->v_tot_disp >> 16) & 0x7ff) + 1), 731 (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P', 732 (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P', 733 (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N'); 734 735 DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp); 736 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid); 737 DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp); 738 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid); 739 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch); 740 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline); 741 DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl); 742 743 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par); 744 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par); 745 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par); 746 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par); 747 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par); 748 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par); 749 750 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par); 751 #if 0 752 FIXME 753 if (par->accel_flags & FB_ACCELF_TEXT) 754 aty_init_engine(par, info); 755 #endif 756 #ifdef CONFIG_FB_ATY_GENERIC_LCD 757 /* after setting the CRTC registers we should set the LCD registers. */ 758 if (par->lcd_table != 0) { 759 /* switch to shadow registers */ 760 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | 761 SHADOW_EN | SHADOW_RW_EN, par); 762 763 DPRINTK("set shadow CRT to %ix%i %c%c\n", 764 ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3), 765 (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1), 766 (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P', 767 (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P'); 768 769 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", 770 crtc->shadow_h_tot_disp); 771 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", 772 crtc->shadow_h_sync_strt_wid); 773 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", 774 crtc->shadow_v_tot_disp); 775 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", 776 crtc->shadow_v_sync_strt_wid); 777 778 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par); 779 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par); 780 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par); 781 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par); 782 783 /* restore CRTC selection & shadow state and enable stretching */ 784 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl); 785 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching); 786 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching); 787 if (!M64_HAS(LT_LCD_REGS)) 788 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); 789 790 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); 791 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par); 792 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par); 793 if (!M64_HAS(LT_LCD_REGS)) { 794 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); 795 aty_ld_le32(LCD_INDEX, par); 796 aty_st_le32(LCD_INDEX, crtc->lcd_index, par); 797 } 798 } 799 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 800 } 801 802 static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) 803 { 804 u32 line_length = vxres * bpp / 8; 805 806 if (par->ram_type == SGRAM || 807 (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) 808 line_length = (line_length + 63) & ~63; 809 810 return line_length; 811 } 812 813 static int aty_var_to_crtc(const struct fb_info *info, 814 const struct fb_var_screeninfo *var, 815 struct crtc *crtc) 816 { 817 struct atyfb_par *par = (struct atyfb_par *) info->par; 818 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp; 819 u32 sync, vmode; 820 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; 821 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; 822 u32 pix_width, dp_pix_width, dp_chain_mask; 823 u32 line_length; 824 825 /* input */ 826 xres = (var->xres + 7) & ~7; 827 yres = var->yres; 828 vxres = (var->xres_virtual + 7) & ~7; 829 vyres = var->yres_virtual; 830 xoffset = (var->xoffset + 7) & ~7; 831 yoffset = var->yoffset; 832 bpp = var->bits_per_pixel; 833 if (bpp == 16) 834 bpp = (var->green.length == 5) ? 15 : 16; 835 sync = var->sync; 836 vmode = var->vmode; 837 838 /* convert (and round up) and validate */ 839 if (vxres < xres + xoffset) 840 vxres = xres + xoffset; 841 h_disp = xres; 842 843 if (vyres < yres + yoffset) 844 vyres = yres + yoffset; 845 v_disp = yres; 846 847 if (bpp <= 8) { 848 bpp = 8; 849 pix_width = CRTC_PIX_WIDTH_8BPP; 850 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | 851 BYTE_ORDER_LSB_TO_MSB; 852 dp_chain_mask = DP_CHAIN_8BPP; 853 } else if (bpp <= 15) { 854 bpp = 16; 855 pix_width = CRTC_PIX_WIDTH_15BPP; 856 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP | 857 BYTE_ORDER_LSB_TO_MSB; 858 dp_chain_mask = DP_CHAIN_15BPP; 859 } else if (bpp <= 16) { 860 bpp = 16; 861 pix_width = CRTC_PIX_WIDTH_16BPP; 862 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP | 863 BYTE_ORDER_LSB_TO_MSB; 864 dp_chain_mask = DP_CHAIN_16BPP; 865 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) { 866 bpp = 24; 867 pix_width = CRTC_PIX_WIDTH_24BPP; 868 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | 869 BYTE_ORDER_LSB_TO_MSB; 870 dp_chain_mask = DP_CHAIN_24BPP; 871 } else if (bpp <= 32) { 872 bpp = 32; 873 pix_width = CRTC_PIX_WIDTH_32BPP; 874 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP | 875 BYTE_ORDER_LSB_TO_MSB; 876 dp_chain_mask = DP_CHAIN_32BPP; 877 } else 878 FAIL("invalid bpp"); 879 880 line_length = calc_line_length(par, vxres, bpp); 881 882 if (vyres * line_length > info->fix.smem_len) 883 FAIL("not enough video RAM"); 884 885 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; 886 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; 887 888 if ((xres > 1920) || (yres > 1200)) { 889 FAIL("MACH64 chips are designed for max 1920x1200\n" 890 "select another resolution."); 891 } 892 h_sync_strt = h_disp + var->right_margin; 893 h_sync_end = h_sync_strt + var->hsync_len; 894 h_sync_dly = var->right_margin & 7; 895 h_total = h_sync_end + h_sync_dly + var->left_margin; 896 897 v_sync_strt = v_disp + var->lower_margin; 898 v_sync_end = v_sync_strt + var->vsync_len; 899 v_total = v_sync_end + var->upper_margin; 900 901 #ifdef CONFIG_FB_ATY_GENERIC_LCD 902 if (par->lcd_table != 0) { 903 if (!M64_HAS(LT_LCD_REGS)) { 904 u32 lcd_index = aty_ld_le32(LCD_INDEX, par); 905 crtc->lcd_index = lcd_index & 906 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | 907 LCD_SRC_SEL | CRTC2_DISPLAY_DIS); 908 aty_st_le32(LCD_INDEX, lcd_index, par); 909 } 910 911 if (!M64_HAS(MOBIL_BUS)) 912 crtc->lcd_index |= CRTC2_DISPLAY_DIS; 913 914 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000; 915 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT; 916 917 crtc->lcd_gen_cntl &= 918 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN | 919 /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/ 920 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); 921 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT; 922 923 if ((crtc->lcd_gen_cntl & LCD_ON) && 924 ((xres > par->lcd_width) || (yres > par->lcd_height))) { 925 /* 926 * We cannot display the mode on the LCD. If the CRT is 927 * enabled we can turn off the LCD. 928 * If the CRT is off, it isn't a good idea to switch it 929 * on; we don't know if one is connected. So it's better 930 * to fail then. 931 */ 932 if (crtc->lcd_gen_cntl & CRT_ON) { 933 if (!(var->activate & FB_ACTIVATE_TEST)) 934 PRINTKI("Disable LCD panel, because video mode does not fit.\n"); 935 crtc->lcd_gen_cntl &= ~LCD_ON; 936 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/ 937 } else { 938 if (!(var->activate & FB_ACTIVATE_TEST)) 939 PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n"); 940 return -EINVAL; 941 } 942 } 943 } 944 945 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) { 946 int VScan = 1; 947 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5 948 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 }; 949 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */ 950 951 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); 952 953 /* 954 * This is horror! When we simulate, say 640x480 on an 800x600 955 * LCD monitor, the CRTC should be programmed 800x600 values for 956 * the non visible part, but 640x480 for the visible part. 957 * This code has been tested on a laptop with it's 1400x1050 LCD 958 * monitor and a conventional monitor both switched on. 959 * Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, 960 * works with little glitches also with DOUBLESCAN modes 961 */ 962 if (yres < par->lcd_height) { 963 VScan = par->lcd_height / yres; 964 if (VScan > 1) { 965 VScan = 2; 966 vmode |= FB_VMODE_DOUBLE; 967 } 968 } 969 970 h_sync_strt = h_disp + par->lcd_right_margin; 971 h_sync_end = h_sync_strt + par->lcd_hsync_len; 972 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly; 973 h_total = h_disp + par->lcd_hblank_len; 974 975 v_sync_strt = v_disp + par->lcd_lower_margin / VScan; 976 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan; 977 v_total = v_disp + par->lcd_vblank_len / VScan; 978 } 979 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 980 981 h_disp = (h_disp >> 3) - 1; 982 h_sync_strt = (h_sync_strt >> 3) - 1; 983 h_sync_end = (h_sync_end >> 3) - 1; 984 h_total = (h_total >> 3) - 1; 985 h_sync_wid = h_sync_end - h_sync_strt; 986 987 FAIL_MAX("h_disp too large", h_disp, 0xff); 988 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff); 989 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/ 990 if (h_sync_wid > 0x1f) 991 h_sync_wid = 0x1f; 992 FAIL_MAX("h_total too large", h_total, 0x1ff); 993 994 if (vmode & FB_VMODE_DOUBLE) { 995 v_disp <<= 1; 996 v_sync_strt <<= 1; 997 v_sync_end <<= 1; 998 v_total <<= 1; 999 } 1000 1001 v_disp--; 1002 v_sync_strt--; 1003 v_sync_end--; 1004 v_total--; 1005 v_sync_wid = v_sync_end - v_sync_strt; 1006 1007 FAIL_MAX("v_disp too large", v_disp, 0x7ff); 1008 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff); 1009 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/ 1010 if (v_sync_wid > 0x1f) 1011 v_sync_wid = 0x1f; 1012 FAIL_MAX("v_total too large", v_total, 0x7ff); 1013 1014 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0; 1015 1016 /* output */ 1017 crtc->vxres = vxres; 1018 crtc->vyres = vyres; 1019 crtc->xoffset = xoffset; 1020 crtc->yoffset = yoffset; 1021 crtc->bpp = bpp; 1022 crtc->off_pitch = 1023 ((yoffset * line_length + xoffset * bpp / 8) / 8) | 1024 ((line_length / bpp) << 22); 1025 crtc->vline_crnt_vline = 0; 1026 1027 crtc->h_tot_disp = h_total | (h_disp << 16); 1028 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) | 1029 ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) | 1030 (h_sync_pol << 21); 1031 crtc->v_tot_disp = v_total | (v_disp << 16); 1032 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) | 1033 (v_sync_pol << 21); 1034 1035 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */ 1036 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync; 1037 crtc->gen_cntl |= CRTC_VGA_LINEAR; 1038 1039 /* Enable doublescan mode if requested */ 1040 if (vmode & FB_VMODE_DOUBLE) 1041 crtc->gen_cntl |= CRTC_DBL_SCAN_EN; 1042 /* Enable interlaced mode if requested */ 1043 if (vmode & FB_VMODE_INTERLACED) 1044 crtc->gen_cntl |= CRTC_INTERLACE_EN; 1045 #ifdef CONFIG_FB_ATY_GENERIC_LCD 1046 if (par->lcd_table != 0) { 1047 u32 vdisplay = yres; 1048 if (vmode & FB_VMODE_DOUBLE) 1049 vdisplay <<= 1; 1050 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); 1051 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | 1052 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ 1053 USE_SHADOWED_VEND | 1054 USE_SHADOWED_ROWCUR | 1055 SHADOW_EN | SHADOW_RW_EN); 1056 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR/* | LOCK_8DOT*/; 1057 1058 /* MOBILITY M1 tested, FIXME: LT */ 1059 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); 1060 if (!M64_HAS(LT_LCD_REGS)) 1061 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) & 1062 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); 1063 1064 crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO | 1065 HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | 1066 HORZ_STRETCH_MODE | HORZ_STRETCH_EN); 1067 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { 1068 do { 1069 /* 1070 * The horizontal blender misbehaves when 1071 * HDisplay is less than a certain threshold 1072 * (440 for a 1024-wide panel). It doesn't 1073 * stretch such modes enough. Use pixel 1074 * replication instead of blending to stretch 1075 * modes that can be made to exactly fit the 1076 * panel width. The undocumented "NoLCDBlend" 1077 * option allows the pixel-replicated mode to 1078 * be slightly wider or narrower than the 1079 * panel width. It also causes a mode that is 1080 * exactly half as wide as the panel to be 1081 * pixel-replicated, rather than blended. 1082 */ 1083 int HDisplay = xres & ~7; 1084 int nStretch = par->lcd_width / HDisplay; 1085 int Remainder = par->lcd_width % HDisplay; 1086 1087 if ((!Remainder && ((nStretch > 2))) || 1088 (((HDisplay * 16) / par->lcd_width) < 7)) { 1089 static const char StretchLoops[] = { 10, 12, 13, 15, 16 }; 1090 int horz_stretch_loop = -1, BestRemainder; 1091 int Numerator = HDisplay, Denominator = par->lcd_width; 1092 int Index = 5; 1093 ATIReduceRatio(&Numerator, &Denominator); 1094 1095 BestRemainder = (Numerator * 16) / Denominator; 1096 while (--Index >= 0) { 1097 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) % 1098 Denominator; 1099 if (Remainder < BestRemainder) { 1100 horz_stretch_loop = Index; 1101 if (!(BestRemainder = Remainder)) 1102 break; 1103 } 1104 } 1105 1106 if ((horz_stretch_loop >= 0) && !BestRemainder) { 1107 int horz_stretch_ratio = 0, Accumulator = 0; 1108 int reuse_previous = 1; 1109 1110 Index = StretchLoops[horz_stretch_loop]; 1111 1112 while (--Index >= 0) { 1113 if (Accumulator > 0) 1114 horz_stretch_ratio |= reuse_previous; 1115 else 1116 Accumulator += Denominator; 1117 Accumulator -= Numerator; 1118 reuse_previous <<= 1; 1119 } 1120 1121 crtc->horz_stretching |= (HORZ_STRETCH_EN | 1122 ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) | 1123 (horz_stretch_ratio & HORZ_STRETCH_RATIO)); 1124 break; /* Out of the do { ... } while (0) */ 1125 } 1126 } 1127 1128 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN | 1129 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND)); 1130 } while (0); 1131 } 1132 1133 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) { 1134 crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN | 1135 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); 1136 1137 if (!M64_HAS(LT_LCD_REGS) && 1138 xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800)) 1139 crtc->ext_vert_stretch |= VERT_STRETCH_MODE; 1140 } else { 1141 /* 1142 * Don't use vertical blending if the mode is too wide 1143 * or not vertically stretched. 1144 */ 1145 crtc->vert_stretching = 0; 1146 } 1147 /* copy to shadow crtc */ 1148 crtc->shadow_h_tot_disp = crtc->h_tot_disp; 1149 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid; 1150 crtc->shadow_v_tot_disp = crtc->v_tot_disp; 1151 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid; 1152 } 1153 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 1154 1155 if (M64_HAS(MAGIC_FIFO)) { 1156 /* FIXME: display FIFO low watermark values */ 1157 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM); 1158 } 1159 crtc->dp_pix_width = dp_pix_width; 1160 crtc->dp_chain_mask = dp_chain_mask; 1161 1162 return 0; 1163 } 1164 1165 static int aty_crtc_to_var(const struct crtc *crtc, 1166 struct fb_var_screeninfo *var) 1167 { 1168 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync; 1169 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol; 1170 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync; 1171 u32 pix_width; 1172 u32 double_scan, interlace; 1173 1174 /* input */ 1175 h_total = crtc->h_tot_disp & 0x1ff; 1176 h_disp = (crtc->h_tot_disp >> 16) & 0xff; 1177 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100); 1178 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7; 1179 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f; 1180 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1; 1181 v_total = crtc->v_tot_disp & 0x7ff; 1182 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff; 1183 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff; 1184 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f; 1185 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1; 1186 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0; 1187 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK; 1188 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN; 1189 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN; 1190 1191 /* convert */ 1192 xres = (h_disp + 1) * 8; 1193 yres = v_disp + 1; 1194 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly; 1195 right = (h_sync_strt - h_disp) * 8 + h_sync_dly; 1196 hslen = h_sync_wid * 8; 1197 upper = v_total - v_sync_strt - v_sync_wid; 1198 lower = v_sync_strt - v_disp; 1199 vslen = v_sync_wid; 1200 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) | 1201 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | 1202 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); 1203 1204 switch (pix_width) { 1205 case CRTC_PIX_WIDTH_8BPP: 1206 bpp = 8; 1207 var->red.offset = 0; 1208 var->red.length = 8; 1209 var->green.offset = 0; 1210 var->green.length = 8; 1211 var->blue.offset = 0; 1212 var->blue.length = 8; 1213 var->transp.offset = 0; 1214 var->transp.length = 0; 1215 break; 1216 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */ 1217 bpp = 16; 1218 var->red.offset = 10; 1219 var->red.length = 5; 1220 var->green.offset = 5; 1221 var->green.length = 5; 1222 var->blue.offset = 0; 1223 var->blue.length = 5; 1224 var->transp.offset = 0; 1225 var->transp.length = 0; 1226 break; 1227 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */ 1228 bpp = 16; 1229 var->red.offset = 11; 1230 var->red.length = 5; 1231 var->green.offset = 5; 1232 var->green.length = 6; 1233 var->blue.offset = 0; 1234 var->blue.length = 5; 1235 var->transp.offset = 0; 1236 var->transp.length = 0; 1237 break; 1238 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */ 1239 bpp = 24; 1240 var->red.offset = 16; 1241 var->red.length = 8; 1242 var->green.offset = 8; 1243 var->green.length = 8; 1244 var->blue.offset = 0; 1245 var->blue.length = 8; 1246 var->transp.offset = 0; 1247 var->transp.length = 0; 1248 break; 1249 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */ 1250 bpp = 32; 1251 var->red.offset = 16; 1252 var->red.length = 8; 1253 var->green.offset = 8; 1254 var->green.length = 8; 1255 var->blue.offset = 0; 1256 var->blue.length = 8; 1257 var->transp.offset = 24; 1258 var->transp.length = 8; 1259 break; 1260 default: 1261 PRINTKE("Invalid pixel width\n"); 1262 return -EINVAL; 1263 } 1264 1265 /* output */ 1266 var->xres = xres; 1267 var->yres = yres; 1268 var->xres_virtual = crtc->vxres; 1269 var->yres_virtual = crtc->vyres; 1270 var->bits_per_pixel = bpp; 1271 var->left_margin = left; 1272 var->right_margin = right; 1273 var->upper_margin = upper; 1274 var->lower_margin = lower; 1275 var->hsync_len = hslen; 1276 var->vsync_len = vslen; 1277 var->sync = sync; 1278 var->vmode = FB_VMODE_NONINTERLACED; 1279 /* 1280 * In double scan mode, the vertical parameters are doubled, 1281 * so we need to halve them to get the right values. 1282 * In interlaced mode the values are already correct, 1283 * so no correction is necessary. 1284 */ 1285 if (interlace) 1286 var->vmode = FB_VMODE_INTERLACED; 1287 1288 if (double_scan) { 1289 var->vmode = FB_VMODE_DOUBLE; 1290 var->yres >>= 1; 1291 var->upper_margin >>= 1; 1292 var->lower_margin >>= 1; 1293 var->vsync_len >>= 1; 1294 } 1295 1296 return 0; 1297 } 1298 1299 /* ------------------------------------------------------------------------- */ 1300 1301 static int atyfb_set_par(struct fb_info *info) 1302 { 1303 struct atyfb_par *par = (struct atyfb_par *) info->par; 1304 struct fb_var_screeninfo *var = &info->var; 1305 u32 tmp, pixclock; 1306 int err; 1307 #ifdef DEBUG 1308 struct fb_var_screeninfo debug; 1309 u32 pixclock_in_ps; 1310 #endif 1311 if (par->asleep) 1312 return 0; 1313 1314 err = aty_var_to_crtc(info, var, &par->crtc); 1315 if (err) 1316 return err; 1317 1318 pixclock = atyfb_get_pixclock(var, par); 1319 1320 if (pixclock == 0) { 1321 PRINTKE("Invalid pixclock\n"); 1322 return -EINVAL; 1323 } else { 1324 err = par->pll_ops->var_to_pll(info, pixclock, 1325 var->bits_per_pixel, &par->pll); 1326 if (err) 1327 return err; 1328 } 1329 1330 par->accel_flags = var->accel_flags; /* hack */ 1331 1332 if (var->accel_flags) { 1333 atyfb_ops.fb_sync = atyfb_sync; 1334 info->flags &= ~FBINFO_HWACCEL_DISABLED; 1335 } else { 1336 atyfb_ops.fb_sync = NULL; 1337 info->flags |= FBINFO_HWACCEL_DISABLED; 1338 } 1339 1340 if (par->blitter_may_be_busy) 1341 wait_for_idle(par); 1342 1343 aty_set_crtc(par, &par->crtc); 1344 par->dac_ops->set_dac(info, &par->pll, 1345 var->bits_per_pixel, par->accel_flags); 1346 par->pll_ops->set_pll(info, &par->pll); 1347 1348 #ifdef DEBUG 1349 if (par->pll_ops && par->pll_ops->pll_to_var) 1350 pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll); 1351 else 1352 pixclock_in_ps = 0; 1353 1354 if (0 == pixclock_in_ps) { 1355 PRINTKE("ALERT ops->pll_to_var get 0\n"); 1356 pixclock_in_ps = pixclock; 1357 } 1358 1359 memset(&debug, 0, sizeof(debug)); 1360 if (!aty_crtc_to_var(&par->crtc, &debug)) { 1361 u32 hSync, vRefresh; 1362 u32 h_disp, h_sync_strt, h_sync_end, h_total; 1363 u32 v_disp, v_sync_strt, v_sync_end, v_total; 1364 1365 h_disp = debug.xres; 1366 h_sync_strt = h_disp + debug.right_margin; 1367 h_sync_end = h_sync_strt + debug.hsync_len; 1368 h_total = h_sync_end + debug.left_margin; 1369 v_disp = debug.yres; 1370 v_sync_strt = v_disp + debug.lower_margin; 1371 v_sync_end = v_sync_strt + debug.vsync_len; 1372 v_total = v_sync_end + debug.upper_margin; 1373 1374 hSync = 1000000000 / (pixclock_in_ps * h_total); 1375 vRefresh = (hSync * 1000) / v_total; 1376 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) 1377 vRefresh *= 2; 1378 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) 1379 vRefresh /= 2; 1380 1381 DPRINTK("atyfb_set_par\n"); 1382 DPRINTK(" Set Visible Mode to %ix%i-%i\n", 1383 var->xres, var->yres, var->bits_per_pixel); 1384 DPRINTK(" Virtual resolution %ix%i, " 1385 "pixclock_in_ps %i (calculated %i)\n", 1386 var->xres_virtual, var->yres_virtual, 1387 pixclock, pixclock_in_ps); 1388 DPRINTK(" Dot clock: %i MHz\n", 1389 1000000 / pixclock_in_ps); 1390 DPRINTK(" Horizontal sync: %i kHz\n", hSync); 1391 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh); 1392 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n", 1393 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps, 1394 h_disp, h_sync_strt, h_sync_end, h_total, 1395 v_disp, v_sync_strt, v_sync_end, v_total); 1396 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n", 1397 pixclock_in_ps, 1398 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len, 1399 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len); 1400 } 1401 #endif /* DEBUG */ 1402 1403 if (!M64_HAS(INTEGRATED)) { 1404 /* Don't forget MEM_CNTL */ 1405 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff; 1406 switch (var->bits_per_pixel) { 1407 case 8: 1408 tmp |= 0x02000000; 1409 break; 1410 case 16: 1411 tmp |= 0x03000000; 1412 break; 1413 case 32: 1414 tmp |= 0x06000000; 1415 break; 1416 } 1417 aty_st_le32(MEM_CNTL, tmp, par); 1418 } else { 1419 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff; 1420 if (!M64_HAS(MAGIC_POSTDIV)) 1421 tmp |= par->mem_refresh_rate << 20; 1422 switch (var->bits_per_pixel) { 1423 case 8: 1424 case 24: 1425 tmp |= 0x00000000; 1426 break; 1427 case 16: 1428 tmp |= 0x04000000; 1429 break; 1430 case 32: 1431 tmp |= 0x08000000; 1432 break; 1433 } 1434 if (M64_HAS(CT_BUS)) { 1435 aty_st_le32(DAC_CNTL, 0x87010184, par); 1436 aty_st_le32(BUS_CNTL, 0x680000f9, par); 1437 } else if (M64_HAS(VT_BUS)) { 1438 aty_st_le32(DAC_CNTL, 0x87010184, par); 1439 aty_st_le32(BUS_CNTL, 0x680000f9, par); 1440 } else if (M64_HAS(MOBIL_BUS)) { 1441 aty_st_le32(DAC_CNTL, 0x80010102, par); 1442 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par); 1443 } else { 1444 /* GT */ 1445 aty_st_le32(DAC_CNTL, 0x86010102, par); 1446 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par); 1447 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par); 1448 } 1449 aty_st_le32(MEM_CNTL, tmp, par); 1450 } 1451 aty_st_8(DAC_MASK, 0xff, par); 1452 1453 info->fix.line_length = calc_line_length(par, var->xres_virtual, 1454 var->bits_per_pixel); 1455 1456 info->fix.visual = var->bits_per_pixel <= 8 ? 1457 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 1458 1459 /* Initialize the graphics engine */ 1460 if (par->accel_flags & FB_ACCELF_TEXT) 1461 aty_init_engine(par, info); 1462 1463 #ifdef CONFIG_BOOTX_TEXT 1464 btext_update_display(info->fix.smem_start, 1465 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8, 1466 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1, 1467 var->bits_per_pixel, 1468 par->crtc.vxres * var->bits_per_pixel / 8); 1469 #endif /* CONFIG_BOOTX_TEXT */ 1470 #ifdef DEBUG 1471 { 1472 /* dump non shadow CRTC, pll, LCD registers */ 1473 int i; u32 base; 1474 1475 /* CRTC registers */ 1476 base = 0x2000; 1477 printk("debug atyfb: Mach64 non-shadow register values:"); 1478 for (i = 0; i < 256; i = i+4) { 1479 if (i % 16 == 0) { 1480 pr_cont("\n"); 1481 printk("debug atyfb: 0x%04X: ", base + i); 1482 } 1483 pr_cont(" %08X", aty_ld_le32(i, par)); 1484 } 1485 pr_cont("\n\n"); 1486 1487 #ifdef CONFIG_FB_ATY_CT 1488 /* PLL registers */ 1489 base = 0x00; 1490 printk("debug atyfb: Mach64 PLL register values:"); 1491 for (i = 0; i < 64; i++) { 1492 if (i % 16 == 0) { 1493 pr_cont("\n"); 1494 printk("debug atyfb: 0x%02X: ", base + i); 1495 } 1496 if (i % 4 == 0) 1497 pr_cont(" "); 1498 pr_cont("%02X", aty_ld_pll_ct(i, par)); 1499 } 1500 pr_cont("\n\n"); 1501 #endif /* CONFIG_FB_ATY_CT */ 1502 1503 #ifdef CONFIG_FB_ATY_GENERIC_LCD 1504 if (par->lcd_table != 0) { 1505 /* LCD registers */ 1506 base = 0x00; 1507 printk("debug atyfb: LCD register values:"); 1508 if (M64_HAS(LT_LCD_REGS)) { 1509 for (i = 0; i <= POWER_MANAGEMENT; i++) { 1510 if (i == EXT_VERT_STRETCH) 1511 continue; 1512 pr_cont("\ndebug atyfb: 0x%04X: ", 1513 lt_lcd_regs[i]); 1514 pr_cont(" %08X", aty_ld_lcd(i, par)); 1515 } 1516 } else { 1517 for (i = 0; i < 64; i++) { 1518 if (i % 4 == 0) 1519 pr_cont("\ndebug atyfb: 0x%02X: ", 1520 base + i); 1521 pr_cont(" %08X", aty_ld_lcd(i, par)); 1522 } 1523 } 1524 pr_cont("\n\n"); 1525 } 1526 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 1527 } 1528 #endif /* DEBUG */ 1529 return 0; 1530 } 1531 1532 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1533 { 1534 struct atyfb_par *par = (struct atyfb_par *) info->par; 1535 int err; 1536 struct crtc crtc; 1537 union aty_pll pll; 1538 u32 pixclock; 1539 1540 memcpy(&pll, &par->pll, sizeof(pll)); 1541 1542 err = aty_var_to_crtc(info, var, &crtc); 1543 if (err) 1544 return err; 1545 1546 pixclock = atyfb_get_pixclock(var, par); 1547 1548 if (pixclock == 0) { 1549 if (!(var->activate & FB_ACTIVATE_TEST)) 1550 PRINTKE("Invalid pixclock\n"); 1551 return -EINVAL; 1552 } else { 1553 err = par->pll_ops->var_to_pll(info, pixclock, 1554 var->bits_per_pixel, &pll); 1555 if (err) 1556 return err; 1557 } 1558 1559 if (var->accel_flags & FB_ACCELF_TEXT) 1560 info->var.accel_flags = FB_ACCELF_TEXT; 1561 else 1562 info->var.accel_flags = 0; 1563 1564 aty_crtc_to_var(&crtc, var); 1565 var->pixclock = par->pll_ops->pll_to_var(info, &pll); 1566 return 0; 1567 } 1568 1569 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) 1570 { 1571 u32 xoffset = info->var.xoffset; 1572 u32 yoffset = info->var.yoffset; 1573 u32 line_length = info->fix.line_length; 1574 u32 bpp = info->var.bits_per_pixel; 1575 1576 par->crtc.off_pitch = 1577 ((yoffset * line_length + xoffset * bpp / 8) / 8) | 1578 ((line_length / bpp) << 22); 1579 } 1580 1581 1582 /* 1583 * Open/Release the frame buffer device 1584 */ 1585 1586 static int atyfb_open(struct fb_info *info, int user) 1587 { 1588 struct atyfb_par *par = (struct atyfb_par *) info->par; 1589 1590 if (user) { 1591 par->open++; 1592 #ifdef __sparc__ 1593 par->mmaped = 0; 1594 #endif 1595 } 1596 return 0; 1597 } 1598 1599 static irqreturn_t aty_irq(int irq, void *dev_id) 1600 { 1601 struct atyfb_par *par = dev_id; 1602 int handled = 0; 1603 u32 int_cntl; 1604 1605 spin_lock(&par->int_lock); 1606 1607 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par); 1608 1609 if (int_cntl & CRTC_VBLANK_INT) { 1610 /* clear interrupt */ 1611 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | 1612 CRTC_VBLANK_INT_AK, par); 1613 par->vblank.count++; 1614 if (par->vblank.pan_display) { 1615 par->vblank.pan_display = 0; 1616 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par); 1617 } 1618 wake_up_interruptible(&par->vblank.wait); 1619 handled = 1; 1620 } 1621 1622 spin_unlock(&par->int_lock); 1623 1624 return IRQ_RETVAL(handled); 1625 } 1626 1627 static int aty_enable_irq(struct atyfb_par *par, int reenable) 1628 { 1629 u32 int_cntl; 1630 1631 if (!test_and_set_bit(0, &par->irq_flags)) { 1632 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) { 1633 clear_bit(0, &par->irq_flags); 1634 return -EINVAL; 1635 } 1636 spin_lock_irq(&par->int_lock); 1637 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; 1638 /* clear interrupt */ 1639 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par); 1640 /* enable interrupt */ 1641 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par); 1642 spin_unlock_irq(&par->int_lock); 1643 } else if (reenable) { 1644 spin_lock_irq(&par->int_lock); 1645 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; 1646 if (!(int_cntl & CRTC_VBLANK_INT_EN)) { 1647 printk("atyfb: someone disabled IRQ [%08x]\n", 1648 int_cntl); 1649 /* re-enable interrupt */ 1650 aty_st_le32(CRTC_INT_CNTL, int_cntl | 1651 CRTC_VBLANK_INT_EN, par); 1652 } 1653 spin_unlock_irq(&par->int_lock); 1654 } 1655 1656 return 0; 1657 } 1658 1659 static int aty_disable_irq(struct atyfb_par *par) 1660 { 1661 u32 int_cntl; 1662 1663 if (test_and_clear_bit(0, &par->irq_flags)) { 1664 if (par->vblank.pan_display) { 1665 par->vblank.pan_display = 0; 1666 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par); 1667 } 1668 spin_lock_irq(&par->int_lock); 1669 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; 1670 /* disable interrupt */ 1671 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par); 1672 spin_unlock_irq(&par->int_lock); 1673 free_irq(par->irq, par); 1674 } 1675 1676 return 0; 1677 } 1678 1679 static int atyfb_release(struct fb_info *info, int user) 1680 { 1681 struct atyfb_par *par = (struct atyfb_par *) info->par; 1682 #ifdef __sparc__ 1683 int was_mmaped; 1684 #endif 1685 1686 if (!user) 1687 return 0; 1688 1689 par->open--; 1690 mdelay(1); 1691 wait_for_idle(par); 1692 1693 if (par->open) 1694 return 0; 1695 1696 #ifdef __sparc__ 1697 was_mmaped = par->mmaped; 1698 1699 par->mmaped = 0; 1700 1701 if (was_mmaped) { 1702 struct fb_var_screeninfo var; 1703 1704 /* 1705 * Now reset the default display config, we have 1706 * no idea what the program(s) which mmap'd the 1707 * chip did to the configuration, nor whether it 1708 * restored it correctly. 1709 */ 1710 var = default_var; 1711 if (noaccel) 1712 var.accel_flags &= ~FB_ACCELF_TEXT; 1713 else 1714 var.accel_flags |= FB_ACCELF_TEXT; 1715 if (var.yres == var.yres_virtual) { 1716 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); 1717 var.yres_virtual = 1718 ((videoram * 8) / var.bits_per_pixel) / 1719 var.xres_virtual; 1720 if (var.yres_virtual < var.yres) 1721 var.yres_virtual = var.yres; 1722 } 1723 } 1724 #endif 1725 aty_disable_irq(par); 1726 1727 return 0; 1728 } 1729 1730 /* 1731 * Pan or Wrap the Display 1732 * 1733 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag 1734 */ 1735 1736 static int atyfb_pan_display(struct fb_var_screeninfo *var, 1737 struct fb_info *info) 1738 { 1739 struct atyfb_par *par = (struct atyfb_par *) info->par; 1740 u32 xres, yres, xoffset, yoffset; 1741 1742 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8; 1743 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1; 1744 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) 1745 yres >>= 1; 1746 xoffset = (var->xoffset + 7) & ~7; 1747 yoffset = var->yoffset; 1748 if (xoffset + xres > par->crtc.vxres || 1749 yoffset + yres > par->crtc.vyres) 1750 return -EINVAL; 1751 info->var.xoffset = xoffset; 1752 info->var.yoffset = yoffset; 1753 if (par->asleep) 1754 return 0; 1755 1756 set_off_pitch(par, info); 1757 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) { 1758 par->vblank.pan_display = 1; 1759 } else { 1760 par->vblank.pan_display = 0; 1761 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par); 1762 } 1763 1764 return 0; 1765 } 1766 1767 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc) 1768 { 1769 struct aty_interrupt *vbl; 1770 unsigned int count; 1771 int ret; 1772 1773 switch (crtc) { 1774 case 0: 1775 vbl = &par->vblank; 1776 break; 1777 default: 1778 return -ENODEV; 1779 } 1780 1781 ret = aty_enable_irq(par, 0); 1782 if (ret) 1783 return ret; 1784 1785 count = vbl->count; 1786 ret = wait_event_interruptible_timeout(vbl->wait, 1787 count != vbl->count, HZ/10); 1788 if (ret < 0) 1789 return ret; 1790 if (ret == 0) { 1791 aty_enable_irq(par, 1); 1792 return -ETIMEDOUT; 1793 } 1794 1795 return 0; 1796 } 1797 1798 1799 #ifdef DEBUG 1800 #define ATYIO_CLKR 0x41545900 /* ATY\00 */ 1801 #define ATYIO_CLKW 0x41545901 /* ATY\01 */ 1802 1803 struct atyclk { 1804 u32 ref_clk_per; 1805 u8 pll_ref_div; 1806 u8 mclk_fb_div; 1807 u8 mclk_post_div; /* 1,2,3,4,8 */ 1808 u8 mclk_fb_mult; /* 2 or 4 */ 1809 u8 xclk_post_div; /* 1,2,3,4,8 */ 1810 u8 vclk_fb_div; 1811 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */ 1812 u32 dsp_xclks_per_row; /* 0-16383 */ 1813 u32 dsp_loop_latency; /* 0-15 */ 1814 u32 dsp_precision; /* 0-7 */ 1815 u32 dsp_on; /* 0-2047 */ 1816 u32 dsp_off; /* 0-2047 */ 1817 }; 1818 1819 #define ATYIO_FEATR 0x41545902 /* ATY\02 */ 1820 #define ATYIO_FEATW 0x41545903 /* ATY\03 */ 1821 #endif 1822 1823 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) 1824 { 1825 struct atyfb_par *par = (struct atyfb_par *) info->par; 1826 #ifdef __sparc__ 1827 struct fbtype fbtyp; 1828 #endif 1829 1830 switch (cmd) { 1831 #ifdef __sparc__ 1832 case FBIOGTYPE: 1833 fbtyp.fb_type = FBTYPE_PCI_GENERIC; 1834 fbtyp.fb_width = par->crtc.vxres; 1835 fbtyp.fb_height = par->crtc.vyres; 1836 fbtyp.fb_depth = info->var.bits_per_pixel; 1837 fbtyp.fb_cmsize = info->cmap.len; 1838 fbtyp.fb_size = info->fix.smem_len; 1839 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, 1840 sizeof(fbtyp))) 1841 return -EFAULT; 1842 break; 1843 #endif /* __sparc__ */ 1844 1845 case FBIO_WAITFORVSYNC: 1846 { 1847 u32 crtc; 1848 1849 if (get_user(crtc, (__u32 __user *) arg)) 1850 return -EFAULT; 1851 1852 return aty_waitforvblank(par, crtc); 1853 } 1854 1855 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) 1856 case ATYIO_CLKR: 1857 if (M64_HAS(INTEGRATED)) { 1858 struct atyclk clk = { 0 }; 1859 union aty_pll *pll = &par->pll; 1860 u32 dsp_config = pll->ct.dsp_config; 1861 u32 dsp_on_off = pll->ct.dsp_on_off; 1862 clk.ref_clk_per = par->ref_clk_per; 1863 clk.pll_ref_div = pll->ct.pll_ref_div; 1864 clk.mclk_fb_div = pll->ct.mclk_fb_div; 1865 clk.mclk_post_div = pll->ct.mclk_post_div_real; 1866 clk.mclk_fb_mult = pll->ct.mclk_fb_mult; 1867 clk.xclk_post_div = pll->ct.xclk_post_div_real; 1868 clk.vclk_fb_div = pll->ct.vclk_fb_div; 1869 clk.vclk_post_div = pll->ct.vclk_post_div_real; 1870 clk.dsp_xclks_per_row = dsp_config & 0x3fff; 1871 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf; 1872 clk.dsp_precision = (dsp_config >> 20) & 7; 1873 clk.dsp_off = dsp_on_off & 0x7ff; 1874 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff; 1875 if (copy_to_user((struct atyclk __user *) arg, &clk, 1876 sizeof(clk))) 1877 return -EFAULT; 1878 } else 1879 return -EINVAL; 1880 break; 1881 case ATYIO_CLKW: 1882 if (M64_HAS(INTEGRATED)) { 1883 struct atyclk clk; 1884 union aty_pll *pll = &par->pll; 1885 if (copy_from_user(&clk, (struct atyclk __user *) arg, 1886 sizeof(clk))) 1887 return -EFAULT; 1888 par->ref_clk_per = clk.ref_clk_per; 1889 pll->ct.pll_ref_div = clk.pll_ref_div; 1890 pll->ct.mclk_fb_div = clk.mclk_fb_div; 1891 pll->ct.mclk_post_div_real = clk.mclk_post_div; 1892 pll->ct.mclk_fb_mult = clk.mclk_fb_mult; 1893 pll->ct.xclk_post_div_real = clk.xclk_post_div; 1894 pll->ct.vclk_fb_div = clk.vclk_fb_div; 1895 pll->ct.vclk_post_div_real = clk.vclk_post_div; 1896 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) | 1897 ((clk.dsp_loop_latency & 0xf) << 16) | 1898 ((clk.dsp_precision & 7) << 20); 1899 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | 1900 ((clk.dsp_on & 0x7ff) << 16); 1901 /*aty_calc_pll_ct(info, &pll->ct);*/ 1902 aty_set_pll_ct(info, pll); 1903 } else 1904 return -EINVAL; 1905 break; 1906 case ATYIO_FEATR: 1907 if (get_user(par->features, (u32 __user *) arg)) 1908 return -EFAULT; 1909 break; 1910 case ATYIO_FEATW: 1911 if (put_user(par->features, (u32 __user *) arg)) 1912 return -EFAULT; 1913 break; 1914 #endif /* DEBUG && CONFIG_FB_ATY_CT */ 1915 default: 1916 return -EINVAL; 1917 } 1918 return 0; 1919 } 1920 1921 static int atyfb_sync(struct fb_info *info) 1922 { 1923 struct atyfb_par *par = (struct atyfb_par *) info->par; 1924 1925 if (par->blitter_may_be_busy) 1926 wait_for_idle(par); 1927 return 0; 1928 } 1929 1930 #ifdef __sparc__ 1931 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) 1932 { 1933 struct atyfb_par *par = (struct atyfb_par *) info->par; 1934 unsigned int size, page, map_size = 0; 1935 unsigned long map_offset = 0; 1936 unsigned long off; 1937 int i; 1938 1939 if (!par->mmap_map) 1940 return -ENXIO; 1941 1942 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) 1943 return -EINVAL; 1944 1945 off = vma->vm_pgoff << PAGE_SHIFT; 1946 size = vma->vm_end - vma->vm_start; 1947 1948 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ 1949 1950 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) || 1951 ((off == info->fix.smem_len) && (size == PAGE_SIZE))) 1952 off += 0x8000000000000000UL; 1953 1954 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */ 1955 1956 /* Each page, see which map applies */ 1957 for (page = 0; page < size;) { 1958 map_size = 0; 1959 for (i = 0; par->mmap_map[i].size; i++) { 1960 unsigned long start = par->mmap_map[i].voff; 1961 unsigned long end = start + par->mmap_map[i].size; 1962 unsigned long offset = off + page; 1963 1964 if (start > offset) 1965 continue; 1966 if (offset >= end) 1967 continue; 1968 1969 map_size = par->mmap_map[i].size - (offset - start); 1970 map_offset = par->mmap_map[i].poff + (offset - start); 1971 break; 1972 } 1973 if (!map_size) { 1974 page += PAGE_SIZE; 1975 continue; 1976 } 1977 if (page + map_size > size) 1978 map_size = size - page; 1979 1980 pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); 1981 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; 1982 1983 if (remap_pfn_range(vma, vma->vm_start + page, 1984 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot)) 1985 return -EAGAIN; 1986 1987 page += map_size; 1988 } 1989 1990 if (!map_size) 1991 return -EINVAL; 1992 1993 if (!par->mmaped) 1994 par->mmaped = 1; 1995 return 0; 1996 } 1997 #endif /* __sparc__ */ 1998 1999 2000 2001 #if defined(CONFIG_PCI) 2002 2003 #ifdef CONFIG_PPC_PMAC 2004 /* Power management routines. Those are used for PowerBook sleep. 2005 */ 2006 static int aty_power_mgmt(int sleep, struct atyfb_par *par) 2007 { 2008 u32 pm; 2009 int timeout; 2010 2011 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2012 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG; 2013 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2014 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2015 2016 timeout = 2000; 2017 if (sleep) { 2018 /* Sleep */ 2019 pm &= ~PWR_MGT_ON; 2020 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2021 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2022 udelay(10); 2023 pm &= ~(PWR_BLON | AUTO_PWR_UP); 2024 pm |= SUSPEND_NOW; 2025 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2026 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2027 udelay(10); 2028 pm |= PWR_MGT_ON; 2029 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2030 do { 2031 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2032 mdelay(1); 2033 if ((--timeout) == 0) 2034 break; 2035 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND); 2036 } else { 2037 /* Wakeup */ 2038 pm &= ~PWR_MGT_ON; 2039 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2040 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2041 udelay(10); 2042 pm &= ~SUSPEND_NOW; 2043 pm |= (PWR_BLON | AUTO_PWR_UP); 2044 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2045 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2046 udelay(10); 2047 pm |= PWR_MGT_ON; 2048 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2049 do { 2050 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2051 mdelay(1); 2052 if ((--timeout) == 0) 2053 break; 2054 } while ((pm & PWR_MGT_STATUS_MASK) != 0); 2055 } 2056 mdelay(500); 2057 2058 return timeout ? 0 : -EIO; 2059 } 2060 #endif /* CONFIG_PPC_PMAC */ 2061 2062 static int atyfb_pci_suspend_late(struct device *dev, pm_message_t state) 2063 { 2064 struct pci_dev *pdev = to_pci_dev(dev); 2065 struct fb_info *info = pci_get_drvdata(pdev); 2066 struct atyfb_par *par = (struct atyfb_par *) info->par; 2067 2068 if (state.event == pdev->dev.power.power_state.event) 2069 return 0; 2070 2071 console_lock(); 2072 2073 fb_set_suspend(info, 1); 2074 2075 /* Idle & reset engine */ 2076 wait_for_idle(par); 2077 aty_reset_engine(par); 2078 2079 /* Blank display and LCD */ 2080 atyfb_blank(FB_BLANK_POWERDOWN, info); 2081 2082 par->asleep = 1; 2083 par->lock_blank = 1; 2084 2085 /* 2086 * Because we may change PCI D state ourselves, we need to 2087 * first save the config space content so the core can 2088 * restore it properly on resume. 2089 */ 2090 2091 #ifdef CONFIG_PPC_PMAC 2092 /* Set chip to "suspend" mode */ 2093 if (machine_is(powermac) && aty_power_mgmt(1, par)) { 2094 par->asleep = 0; 2095 par->lock_blank = 0; 2096 atyfb_blank(FB_BLANK_UNBLANK, info); 2097 fb_set_suspend(info, 0); 2098 console_unlock(); 2099 return -EIO; 2100 } 2101 #endif 2102 2103 console_unlock(); 2104 2105 pdev->dev.power.power_state = state; 2106 2107 return 0; 2108 } 2109 2110 static int __maybe_unused atyfb_pci_suspend(struct device *dev) 2111 { 2112 return atyfb_pci_suspend_late(dev, PMSG_SUSPEND); 2113 } 2114 2115 static int __maybe_unused atyfb_pci_hibernate(struct device *dev) 2116 { 2117 return atyfb_pci_suspend_late(dev, PMSG_HIBERNATE); 2118 } 2119 2120 static int __maybe_unused atyfb_pci_freeze(struct device *dev) 2121 { 2122 return atyfb_pci_suspend_late(dev, PMSG_FREEZE); 2123 } 2124 2125 static void aty_resume_chip(struct fb_info *info) 2126 { 2127 struct atyfb_par *par = info->par; 2128 2129 aty_st_le32(MEM_CNTL, par->mem_cntl, par); 2130 2131 if (par->pll_ops->resume_pll) 2132 par->pll_ops->resume_pll(info, &par->pll); 2133 2134 if (par->aux_start) 2135 aty_st_le32(BUS_CNTL, 2136 aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); 2137 } 2138 2139 static int __maybe_unused atyfb_pci_resume(struct device *dev) 2140 { 2141 struct pci_dev *pdev = to_pci_dev(dev); 2142 struct fb_info *info = pci_get_drvdata(pdev); 2143 struct atyfb_par *par = (struct atyfb_par *) info->par; 2144 2145 if (pdev->dev.power.power_state.event == PM_EVENT_ON) 2146 return 0; 2147 2148 console_lock(); 2149 2150 /* 2151 * PCI state will have been restored by the core, so 2152 * we should be in D0 now with our config space fully 2153 * restored 2154 */ 2155 2156 #ifdef CONFIG_PPC_PMAC 2157 if (machine_is(powermac) && 2158 pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) 2159 aty_power_mgmt(0, par); 2160 #endif 2161 2162 aty_resume_chip(info); 2163 2164 par->asleep = 0; 2165 2166 /* Restore display */ 2167 atyfb_set_par(info); 2168 2169 /* Refresh */ 2170 fb_set_suspend(info, 0); 2171 2172 /* Unblank */ 2173 par->lock_blank = 0; 2174 atyfb_blank(FB_BLANK_UNBLANK, info); 2175 2176 console_unlock(); 2177 2178 pdev->dev.power.power_state = PMSG_ON; 2179 2180 return 0; 2181 } 2182 2183 static const struct dev_pm_ops atyfb_pci_pm_ops = { 2184 #ifdef CONFIG_PM_SLEEP 2185 .suspend = atyfb_pci_suspend, 2186 .resume = atyfb_pci_resume, 2187 .freeze = atyfb_pci_freeze, 2188 .thaw = atyfb_pci_resume, 2189 .poweroff = atyfb_pci_hibernate, 2190 .restore = atyfb_pci_resume, 2191 #endif /* CONFIG_PM_SLEEP */ 2192 }; 2193 2194 #endif /* defined(CONFIG_PCI) */ 2195 2196 /* Backlight */ 2197 #ifdef CONFIG_FB_ATY_BACKLIGHT 2198 #define MAX_LEVEL 0xFF 2199 2200 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) 2201 { 2202 struct fb_info *info = pci_get_drvdata(par->pdev); 2203 int atylevel; 2204 2205 /* Get and convert the value */ 2206 /* No locking of bl_curve since we read a single value */ 2207 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; 2208 2209 if (atylevel < 0) 2210 atylevel = 0; 2211 else if (atylevel > MAX_LEVEL) 2212 atylevel = MAX_LEVEL; 2213 2214 return atylevel; 2215 } 2216 2217 static int aty_bl_update_status(struct backlight_device *bd) 2218 { 2219 struct atyfb_par *par = bl_get_data(bd); 2220 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); 2221 int level; 2222 2223 if (bd->props.power != FB_BLANK_UNBLANK || 2224 bd->props.fb_blank != FB_BLANK_UNBLANK) 2225 level = 0; 2226 else 2227 level = bd->props.brightness; 2228 2229 reg |= (BLMOD_EN | BIASMOD_EN); 2230 if (level > 0) { 2231 reg &= ~BIAS_MOD_LEVEL_MASK; 2232 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT); 2233 } else { 2234 reg &= ~BIAS_MOD_LEVEL_MASK; 2235 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT); 2236 } 2237 aty_st_lcd(LCD_MISC_CNTL, reg, par); 2238 2239 return 0; 2240 } 2241 2242 static const struct backlight_ops aty_bl_data = { 2243 .update_status = aty_bl_update_status, 2244 }; 2245 2246 static void aty_bl_init(struct atyfb_par *par) 2247 { 2248 struct backlight_properties props; 2249 struct fb_info *info = pci_get_drvdata(par->pdev); 2250 struct backlight_device *bd; 2251 char name[12]; 2252 2253 #ifdef CONFIG_PMAC_BACKLIGHT 2254 if (!pmac_has_backlight_type("ati")) 2255 return; 2256 #endif 2257 2258 snprintf(name, sizeof(name), "atybl%d", info->node); 2259 2260 memset(&props, 0, sizeof(struct backlight_properties)); 2261 props.type = BACKLIGHT_RAW; 2262 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 2263 bd = backlight_device_register(name, info->dev, par, &aty_bl_data, 2264 &props); 2265 if (IS_ERR(bd)) { 2266 info->bl_dev = NULL; 2267 printk(KERN_WARNING "aty: Backlight registration failed\n"); 2268 goto error; 2269 } 2270 2271 info->bl_dev = bd; 2272 fb_bl_default_curve(info, 0, 2273 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, 2274 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); 2275 2276 bd->props.brightness = bd->props.max_brightness; 2277 bd->props.power = FB_BLANK_UNBLANK; 2278 backlight_update_status(bd); 2279 2280 printk("aty: Backlight initialized (%s)\n", name); 2281 2282 return; 2283 2284 error: 2285 return; 2286 } 2287 2288 #ifdef CONFIG_PCI 2289 static void aty_bl_exit(struct backlight_device *bd) 2290 { 2291 backlight_device_unregister(bd); 2292 printk("aty: Backlight unloaded\n"); 2293 } 2294 #endif /* CONFIG_PCI */ 2295 2296 #endif /* CONFIG_FB_ATY_BACKLIGHT */ 2297 2298 static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk) 2299 { 2300 static const int ragepro_tbl[] = { 2301 44, 50, 55, 66, 75, 80, 100 2302 }; 2303 static const int ragexl_tbl[] = { 2304 50, 66, 75, 83, 90, 95, 100, 105, 2305 110, 115, 120, 125, 133, 143, 166 2306 }; 2307 const int *refresh_tbl; 2308 int i, size; 2309 2310 if (M64_HAS(XL_MEM)) { 2311 refresh_tbl = ragexl_tbl; 2312 size = ARRAY_SIZE(ragexl_tbl); 2313 } else { 2314 refresh_tbl = ragepro_tbl; 2315 size = ARRAY_SIZE(ragepro_tbl); 2316 } 2317 2318 for (i = 0; i < size; i++) { 2319 if (xclk < refresh_tbl[i]) 2320 break; 2321 } 2322 par->mem_refresh_rate = i; 2323 } 2324 2325 /* 2326 * Initialisation 2327 */ 2328 2329 static struct fb_info *fb_list = NULL; 2330 2331 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) 2332 static int atyfb_get_timings_from_lcd(struct atyfb_par *par, 2333 struct fb_var_screeninfo *var) 2334 { 2335 int ret = -EINVAL; 2336 2337 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2338 *var = default_var; 2339 var->xres = var->xres_virtual = par->lcd_hdisp; 2340 var->right_margin = par->lcd_right_margin; 2341 var->left_margin = par->lcd_hblank_len - 2342 (par->lcd_right_margin + par->lcd_hsync_dly + 2343 par->lcd_hsync_len); 2344 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly; 2345 var->yres = var->yres_virtual = par->lcd_vdisp; 2346 var->lower_margin = par->lcd_lower_margin; 2347 var->upper_margin = par->lcd_vblank_len - 2348 (par->lcd_lower_margin + par->lcd_vsync_len); 2349 var->vsync_len = par->lcd_vsync_len; 2350 var->pixclock = par->lcd_pixclock; 2351 ret = 0; 2352 } 2353 2354 return ret; 2355 } 2356 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ 2357 2358 static int aty_init(struct fb_info *info) 2359 { 2360 struct atyfb_par *par = (struct atyfb_par *) info->par; 2361 const char *ramname = NULL, *xtal; 2362 int gtb_memsize, has_var = 0; 2363 struct fb_var_screeninfo var; 2364 int ret; 2365 #ifdef CONFIG_ATARI 2366 u8 dac_type; 2367 #endif 2368 2369 init_waitqueue_head(&par->vblank.wait); 2370 spin_lock_init(&par->int_lock); 2371 2372 #ifdef CONFIG_FB_ATY_GX 2373 if (!M64_HAS(INTEGRATED)) { 2374 u32 stat0; 2375 u8 dac_subtype, clk_type; 2376 stat0 = aty_ld_le32(CNFG_STAT0, par); 2377 par->bus_type = (stat0 >> 0) & 0x07; 2378 par->ram_type = (stat0 >> 3) & 0x07; 2379 ramname = aty_gx_ram[par->ram_type]; 2380 /* FIXME: clockchip/RAMDAC probing? */ 2381 #ifdef CONFIG_ATARI 2382 clk_type = CLK_ATI18818_1; 2383 dac_type = (stat0 >> 9) & 0x07; 2384 if (dac_type == 0x07) 2385 dac_subtype = DAC_ATT20C408; 2386 else 2387 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type; 2388 #else 2389 dac_subtype = DAC_IBMRGB514; 2390 clk_type = CLK_IBMRGB514; 2391 #endif 2392 switch (dac_subtype) { 2393 case DAC_IBMRGB514: 2394 par->dac_ops = &aty_dac_ibm514; 2395 break; 2396 #ifdef CONFIG_ATARI 2397 case DAC_ATI68860_B: 2398 case DAC_ATI68860_C: 2399 par->dac_ops = &aty_dac_ati68860b; 2400 break; 2401 case DAC_ATT20C408: 2402 case DAC_ATT21C498: 2403 par->dac_ops = &aty_dac_att21c498; 2404 break; 2405 #endif 2406 default: 2407 PRINTKI("aty_init: DAC type not implemented yet!\n"); 2408 par->dac_ops = &aty_dac_unsupported; 2409 break; 2410 } 2411 switch (clk_type) { 2412 #ifdef CONFIG_ATARI 2413 case CLK_ATI18818_1: 2414 par->pll_ops = &aty_pll_ati18818_1; 2415 break; 2416 #else 2417 case CLK_IBMRGB514: 2418 par->pll_ops = &aty_pll_ibm514; 2419 break; 2420 #endif 2421 default: 2422 PRINTKI("aty_init: CLK type not implemented yet!"); 2423 par->pll_ops = &aty_pll_unsupported; 2424 break; 2425 } 2426 } 2427 #endif /* CONFIG_FB_ATY_GX */ 2428 #ifdef CONFIG_FB_ATY_CT 2429 if (M64_HAS(INTEGRATED)) { 2430 par->dac_ops = &aty_dac_ct; 2431 par->pll_ops = &aty_pll_ct; 2432 par->bus_type = PCI; 2433 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); 2434 if (M64_HAS(XL_MEM)) 2435 ramname = aty_xl_ram[par->ram_type]; 2436 else 2437 ramname = aty_ct_ram[par->ram_type]; 2438 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ 2439 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) 2440 par->pll_limits.mclk = 63; 2441 /* Mobility + 32bit memory interface need halved XCLK. */ 2442 if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32) 2443 par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1; 2444 } 2445 #endif 2446 #ifdef CONFIG_PPC_PMAC 2447 /* 2448 * The Apple iBook1 uses non-standard memory frequencies. 2449 * We detect it and set the frequency manually. 2450 */ 2451 if (of_machine_is_compatible("PowerBook2,1")) { 2452 par->pll_limits.mclk = 70; 2453 par->pll_limits.xclk = 53; 2454 } 2455 #endif 2456 2457 /* Allow command line to override clocks. */ 2458 if (pll) 2459 par->pll_limits.pll_max = pll; 2460 if (mclk) 2461 par->pll_limits.mclk = mclk; 2462 if (xclk) 2463 par->pll_limits.xclk = xclk; 2464 2465 aty_calc_mem_refresh(par, par->pll_limits.xclk); 2466 par->pll_per = 1000000/par->pll_limits.pll_max; 2467 par->mclk_per = 1000000/par->pll_limits.mclk; 2468 par->xclk_per = 1000000/par->pll_limits.xclk; 2469 2470 par->ref_clk_per = 1000000000000ULL / 14318180; 2471 xtal = "14.31818"; 2472 2473 #ifdef CONFIG_FB_ATY_CT 2474 if (M64_HAS(GTB_DSP)) { 2475 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par); 2476 2477 if (pll_ref_div) { 2478 int diff1, diff2; 2479 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max; 2480 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max; 2481 if (diff1 < 0) 2482 diff1 = -diff1; 2483 if (diff2 < 0) 2484 diff2 = -diff2; 2485 if (diff2 < diff1) { 2486 par->ref_clk_per = 1000000000000ULL / 29498928; 2487 xtal = "29.498928"; 2488 } 2489 } 2490 } 2491 #endif /* CONFIG_FB_ATY_CT */ 2492 2493 /* save previous video mode */ 2494 aty_get_crtc(par, &par->saved_crtc); 2495 if (par->pll_ops->get_pll) 2496 par->pll_ops->get_pll(info, &par->saved_pll); 2497 2498 par->mem_cntl = aty_ld_le32(MEM_CNTL, par); 2499 gtb_memsize = M64_HAS(GTB_DSP); 2500 if (gtb_memsize) 2501 /* 0xF used instead of MEM_SIZE_ALIAS */ 2502 switch (par->mem_cntl & 0xF) { 2503 case MEM_SIZE_512K: 2504 info->fix.smem_len = 0x80000; 2505 break; 2506 case MEM_SIZE_1M: 2507 info->fix.smem_len = 0x100000; 2508 break; 2509 case MEM_SIZE_2M_GTB: 2510 info->fix.smem_len = 0x200000; 2511 break; 2512 case MEM_SIZE_4M_GTB: 2513 info->fix.smem_len = 0x400000; 2514 break; 2515 case MEM_SIZE_6M_GTB: 2516 info->fix.smem_len = 0x600000; 2517 break; 2518 case MEM_SIZE_8M_GTB: 2519 info->fix.smem_len = 0x800000; 2520 break; 2521 default: 2522 info->fix.smem_len = 0x80000; 2523 } else 2524 switch (par->mem_cntl & MEM_SIZE_ALIAS) { 2525 case MEM_SIZE_512K: 2526 info->fix.smem_len = 0x80000; 2527 break; 2528 case MEM_SIZE_1M: 2529 info->fix.smem_len = 0x100000; 2530 break; 2531 case MEM_SIZE_2M: 2532 info->fix.smem_len = 0x200000; 2533 break; 2534 case MEM_SIZE_4M: 2535 info->fix.smem_len = 0x400000; 2536 break; 2537 case MEM_SIZE_6M: 2538 info->fix.smem_len = 0x600000; 2539 break; 2540 case MEM_SIZE_8M: 2541 info->fix.smem_len = 0x800000; 2542 break; 2543 default: 2544 info->fix.smem_len = 0x80000; 2545 } 2546 2547 if (M64_HAS(MAGIC_VRAM_SIZE)) { 2548 if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000) 2549 info->fix.smem_len += 0x400000; 2550 } 2551 2552 if (vram) { 2553 info->fix.smem_len = vram * 1024; 2554 par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); 2555 if (info->fix.smem_len <= 0x80000) 2556 par->mem_cntl |= MEM_SIZE_512K; 2557 else if (info->fix.smem_len <= 0x100000) 2558 par->mem_cntl |= MEM_SIZE_1M; 2559 else if (info->fix.smem_len <= 0x200000) 2560 par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; 2561 else if (info->fix.smem_len <= 0x400000) 2562 par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; 2563 else if (info->fix.smem_len <= 0x600000) 2564 par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M; 2565 else 2566 par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M; 2567 aty_st_le32(MEM_CNTL, par->mem_cntl, par); 2568 } 2569 2570 /* 2571 * Reg Block 0 (CT-compatible block) is at mmio_start 2572 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 2573 */ 2574 if (M64_HAS(GX)) { 2575 info->fix.mmio_len = 0x400; 2576 info->fix.accel = FB_ACCEL_ATI_MACH64GX; 2577 } else if (M64_HAS(CT)) { 2578 info->fix.mmio_len = 0x400; 2579 info->fix.accel = FB_ACCEL_ATI_MACH64CT; 2580 } else if (M64_HAS(VT)) { 2581 info->fix.mmio_start -= 0x400; 2582 info->fix.mmio_len = 0x800; 2583 info->fix.accel = FB_ACCEL_ATI_MACH64VT; 2584 } else {/* GT */ 2585 info->fix.mmio_start -= 0x400; 2586 info->fix.mmio_len = 0x800; 2587 info->fix.accel = FB_ACCEL_ATI_MACH64GT; 2588 } 2589 2590 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n", 2591 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20), 2592 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, 2593 par->pll_limits.pll_max, par->pll_limits.mclk, 2594 par->pll_limits.xclk); 2595 2596 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) 2597 if (M64_HAS(INTEGRATED)) { 2598 int i; 2599 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL " 2600 "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG " 2601 "DSP_ON_OFF CLOCK_CNTL\n" 2602 "debug atyfb: %08x %08x %08x " 2603 "%08x %08x %08x " 2604 "%08x %08x\n" 2605 "debug atyfb: PLL", 2606 aty_ld_le32(BUS_CNTL, par), 2607 aty_ld_le32(DAC_CNTL, par), 2608 aty_ld_le32(MEM_CNTL, par), 2609 aty_ld_le32(EXT_MEM_CNTL, par), 2610 aty_ld_le32(CRTC_GEN_CNTL, par), 2611 aty_ld_le32(DSP_CONFIG, par), 2612 aty_ld_le32(DSP_ON_OFF, par), 2613 aty_ld_le32(CLOCK_CNTL, par)); 2614 for (i = 0; i < 40; i++) 2615 pr_cont(" %02x", aty_ld_pll_ct(i, par)); 2616 pr_cont("\n"); 2617 } 2618 #endif 2619 if (par->pll_ops->init_pll) 2620 par->pll_ops->init_pll(info, &par->pll); 2621 if (par->pll_ops->resume_pll) 2622 par->pll_ops->resume_pll(info, &par->pll); 2623 2624 aty_fudge_framebuffer_len(info); 2625 2626 /* 2627 * Disable register access through the linear aperture 2628 * if the auxiliary aperture is used so we can access 2629 * the full 8 MB of video RAM on 8 MB boards. 2630 */ 2631 if (par->aux_start) 2632 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | 2633 BUS_APER_REG_DIS, par); 2634 2635 if (!nomtrr) 2636 /* 2637 * Only the ioremap_wc()'d area will get WC here 2638 * since ioremap_uc() was used on the entire PCI BAR. 2639 */ 2640 par->wc_cookie = arch_phys_wc_add(par->res_start, 2641 par->res_size); 2642 2643 info->fbops = &atyfb_ops; 2644 info->pseudo_palette = par->pseudo_palette; 2645 info->flags = FBINFO_DEFAULT | 2646 FBINFO_HWACCEL_IMAGEBLIT | 2647 FBINFO_HWACCEL_FILLRECT | 2648 FBINFO_HWACCEL_COPYAREA | 2649 FBINFO_HWACCEL_YPAN | 2650 FBINFO_READS_FAST; 2651 2652 #ifdef CONFIG_PMAC_BACKLIGHT 2653 if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) { 2654 /* 2655 * these bits let the 101 powerbook 2656 * wake up from sleep -- paulus 2657 */ 2658 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | 2659 USE_F32KHZ | TRISTATE_MEM_EN, par); 2660 } else 2661 #endif 2662 if (M64_HAS(MOBIL_BUS) && backlight) { 2663 #ifdef CONFIG_FB_ATY_BACKLIGHT 2664 aty_bl_init(par); 2665 #endif 2666 } 2667 2668 memset(&var, 0, sizeof(var)); 2669 #ifdef CONFIG_PPC 2670 if (machine_is(powermac)) { 2671 /* 2672 * FIXME: The NVRAM stuff should be put in a Mac-specific file, 2673 * as it applies to all Mac video cards 2674 */ 2675 if (mode) { 2676 if (mac_find_mode(&var, info, mode, 8)) 2677 has_var = 1; 2678 } else { 2679 if (default_vmode == VMODE_CHOOSE) { 2680 int sense; 2681 if (M64_HAS(G3_PB_1024x768)) 2682 /* G3 PowerBook with 1024x768 LCD */ 2683 default_vmode = VMODE_1024_768_60; 2684 else if (of_machine_is_compatible("iMac")) 2685 default_vmode = VMODE_1024_768_75; 2686 else if (of_machine_is_compatible("PowerBook2,1")) 2687 /* iBook with 800x600 LCD */ 2688 default_vmode = VMODE_800_600_60; 2689 else 2690 default_vmode = VMODE_640_480_67; 2691 sense = read_aty_sense(par); 2692 PRINTKI("monitor sense=%x, mode %d\n", 2693 sense, mac_map_monitor_sense(sense)); 2694 } 2695 if (default_vmode <= 0 || default_vmode > VMODE_MAX) 2696 default_vmode = VMODE_640_480_60; 2697 if (default_cmode < CMODE_8 || default_cmode > CMODE_32) 2698 default_cmode = CMODE_8; 2699 if (!mac_vmode_to_var(default_vmode, default_cmode, 2700 &var)) 2701 has_var = 1; 2702 } 2703 } 2704 2705 #endif /* !CONFIG_PPC */ 2706 2707 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) 2708 if (!atyfb_get_timings_from_lcd(par, &var)) 2709 has_var = 1; 2710 #endif 2711 2712 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) 2713 has_var = 1; 2714 2715 if (!has_var) 2716 var = default_var; 2717 2718 if (noaccel) 2719 var.accel_flags &= ~FB_ACCELF_TEXT; 2720 else 2721 var.accel_flags |= FB_ACCELF_TEXT; 2722 2723 if (comp_sync != -1) { 2724 if (!comp_sync) 2725 var.sync &= ~FB_SYNC_COMP_HIGH_ACT; 2726 else 2727 var.sync |= FB_SYNC_COMP_HIGH_ACT; 2728 } 2729 2730 if (var.yres == var.yres_virtual) { 2731 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); 2732 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual; 2733 if (var.yres_virtual < var.yres) 2734 var.yres_virtual = var.yres; 2735 } 2736 2737 ret = atyfb_check_var(&var, info); 2738 if (ret) { 2739 PRINTKE("can't set default video mode\n"); 2740 goto aty_init_exit; 2741 } 2742 2743 #ifdef CONFIG_FB_ATY_CT 2744 if (!noaccel && M64_HAS(INTEGRATED)) 2745 aty_init_cursor(info, &atyfb_ops); 2746 #endif /* CONFIG_FB_ATY_CT */ 2747 info->var = var; 2748 2749 ret = fb_alloc_cmap(&info->cmap, 256, 0); 2750 if (ret < 0) 2751 goto aty_init_exit; 2752 2753 ret = register_framebuffer(info); 2754 if (ret < 0) { 2755 fb_dealloc_cmap(&info->cmap); 2756 goto aty_init_exit; 2757 } 2758 2759 fb_list = info; 2760 2761 PRINTKI("fb%d: %s frame buffer device on %s\n", 2762 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI"); 2763 return 0; 2764 2765 aty_init_exit: 2766 /* restore video mode */ 2767 aty_set_crtc(par, &par->saved_crtc); 2768 par->pll_ops->set_pll(info, &par->saved_pll); 2769 arch_phys_wc_del(par->wc_cookie); 2770 2771 return ret; 2772 } 2773 2774 #if defined(CONFIG_ATARI) && !defined(MODULE) 2775 static int store_video_par(char *video_str, unsigned char m64_num) 2776 { 2777 char *p; 2778 unsigned long vmembase, size, guiregbase; 2779 2780 PRINTKI("store_video_par() '%s' \n", video_str); 2781 2782 if (!(p = strsep(&video_str, ";")) || !*p) 2783 goto mach64_invalid; 2784 vmembase = simple_strtoul(p, NULL, 0); 2785 if (!(p = strsep(&video_str, ";")) || !*p) 2786 goto mach64_invalid; 2787 size = simple_strtoul(p, NULL, 0); 2788 if (!(p = strsep(&video_str, ";")) || !*p) 2789 goto mach64_invalid; 2790 guiregbase = simple_strtoul(p, NULL, 0); 2791 2792 phys_vmembase[m64_num] = vmembase; 2793 phys_size[m64_num] = size; 2794 phys_guiregbase[m64_num] = guiregbase; 2795 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, 2796 guiregbase); 2797 return 0; 2798 2799 mach64_invalid: 2800 phys_vmembase[m64_num] = 0; 2801 return -1; 2802 } 2803 #endif /* CONFIG_ATARI && !MODULE */ 2804 2805 /* 2806 * Blank the display. 2807 */ 2808 2809 static int atyfb_blank(int blank, struct fb_info *info) 2810 { 2811 struct atyfb_par *par = (struct atyfb_par *) info->par; 2812 u32 gen_cntl; 2813 2814 if (par->lock_blank || par->asleep) 2815 return 0; 2816 2817 #ifdef CONFIG_FB_ATY_GENERIC_LCD 2818 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2819 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2820 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2821 pm &= ~PWR_BLON; 2822 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2823 } 2824 #endif 2825 2826 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 2827 gen_cntl &= ~0x400004c; 2828 switch (blank) { 2829 case FB_BLANK_UNBLANK: 2830 break; 2831 case FB_BLANK_NORMAL: 2832 gen_cntl |= 0x4000040; 2833 break; 2834 case FB_BLANK_VSYNC_SUSPEND: 2835 gen_cntl |= 0x4000048; 2836 break; 2837 case FB_BLANK_HSYNC_SUSPEND: 2838 gen_cntl |= 0x4000044; 2839 break; 2840 case FB_BLANK_POWERDOWN: 2841 gen_cntl |= 0x400004c; 2842 break; 2843 } 2844 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2845 2846 #ifdef CONFIG_FB_ATY_GENERIC_LCD 2847 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2848 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2849 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2850 pm |= PWR_BLON; 2851 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2852 } 2853 #endif 2854 2855 return 0; 2856 } 2857 2858 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue, 2859 const struct atyfb_par *par) 2860 { 2861 aty_st_8(DAC_W_INDEX, regno, par); 2862 aty_st_8(DAC_DATA, red, par); 2863 aty_st_8(DAC_DATA, green, par); 2864 aty_st_8(DAC_DATA, blue, par); 2865 } 2866 2867 /* 2868 * Set a single color register. The values supplied are already 2869 * rounded down to the hardware's capabilities (according to the 2870 * entries in the var structure). Return != 0 for invalid regno. 2871 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR 2872 */ 2873 2874 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 2875 u_int transp, struct fb_info *info) 2876 { 2877 struct atyfb_par *par = (struct atyfb_par *) info->par; 2878 int i, depth; 2879 u32 *pal = info->pseudo_palette; 2880 2881 depth = info->var.bits_per_pixel; 2882 if (depth == 16) 2883 depth = (info->var.green.length == 5) ? 15 : 16; 2884 2885 if (par->asleep) 2886 return 0; 2887 2888 if (regno > 255 || 2889 (depth == 16 && regno > 63) || 2890 (depth == 15 && regno > 31)) 2891 return 1; 2892 2893 red >>= 8; 2894 green >>= 8; 2895 blue >>= 8; 2896 2897 par->palette[regno].red = red; 2898 par->palette[regno].green = green; 2899 par->palette[regno].blue = blue; 2900 2901 if (regno < 16) { 2902 switch (depth) { 2903 case 15: 2904 pal[regno] = (regno << 10) | (regno << 5) | regno; 2905 break; 2906 case 16: 2907 pal[regno] = (regno << 11) | (regno << 5) | regno; 2908 break; 2909 case 24: 2910 pal[regno] = (regno << 16) | (regno << 8) | regno; 2911 break; 2912 case 32: 2913 i = (regno << 8) | regno; 2914 pal[regno] = (i << 16) | i; 2915 break; 2916 } 2917 } 2918 2919 i = aty_ld_8(DAC_CNTL, par) & 0xfc; 2920 if (M64_HAS(EXTRA_BRIGHT)) 2921 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */ 2922 aty_st_8(DAC_CNTL, i, par); 2923 aty_st_8(DAC_MASK, 0xff, par); 2924 2925 if (M64_HAS(INTEGRATED)) { 2926 if (depth == 16) { 2927 if (regno < 32) 2928 aty_st_pal(regno << 3, red, 2929 par->palette[regno << 1].green, 2930 blue, par); 2931 red = par->palette[regno >> 1].red; 2932 blue = par->palette[regno >> 1].blue; 2933 regno <<= 2; 2934 } else if (depth == 15) { 2935 regno <<= 3; 2936 for (i = 0; i < 8; i++) 2937 aty_st_pal(regno + i, red, green, blue, par); 2938 } 2939 } 2940 aty_st_pal(regno, red, green, blue, par); 2941 2942 return 0; 2943 } 2944 2945 #ifdef CONFIG_PCI 2946 2947 #ifdef __sparc__ 2948 2949 static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, 2950 unsigned long addr) 2951 { 2952 struct atyfb_par *par = info->par; 2953 struct device_node *dp; 2954 u32 mem, chip_id; 2955 int i, j, ret; 2956 2957 /* 2958 * Map memory-mapped registers. 2959 */ 2960 par->ati_regbase = (void *)addr + 0x7ffc00UL; 2961 info->fix.mmio_start = addr + 0x7ffc00UL; 2962 2963 /* 2964 * Map in big-endian aperture. 2965 */ 2966 info->screen_base = (char *) (addr + 0x800000UL); 2967 info->fix.smem_start = addr + 0x800000UL; 2968 2969 /* 2970 * Figure mmap addresses from PCI config space. 2971 * Split Framebuffer in big- and little-endian halfs. 2972 */ 2973 for (i = 0; i < 6 && pdev->resource[i].start; i++) 2974 /* nothing */ ; 2975 j = i + 4; 2976 2977 par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC); 2978 if (!par->mmap_map) { 2979 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n"); 2980 return -ENOMEM; 2981 } 2982 2983 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) { 2984 struct resource *rp = &pdev->resource[i]; 2985 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2); 2986 unsigned long base; 2987 u32 size, pbase; 2988 2989 base = rp->start; 2990 2991 io = (rp->flags & IORESOURCE_IO); 2992 2993 size = rp->end - base + 1; 2994 2995 pci_read_config_dword(pdev, breg, &pbase); 2996 2997 if (io) 2998 size &= ~1; 2999 3000 /* 3001 * Map the framebuffer a second time, this time without 3002 * the braindead _PAGE_IE setting. This is used by the 3003 * fixed Xserver, but we need to maintain the old mapping 3004 * to stay compatible with older ones... 3005 */ 3006 if (base == addr) { 3007 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK; 3008 par->mmap_map[j].poff = base & PAGE_MASK; 3009 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK; 3010 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3011 par->mmap_map[j].prot_flag = _PAGE_E; 3012 j++; 3013 } 3014 3015 /* 3016 * Here comes the old framebuffer mapping with _PAGE_IE 3017 * set for the big endian half of the framebuffer... 3018 */ 3019 if (base == addr) { 3020 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK; 3021 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK; 3022 par->mmap_map[j].size = 0x800000; 3023 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3024 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE; 3025 size -= 0x800000; 3026 j++; 3027 } 3028 3029 par->mmap_map[j].voff = pbase & PAGE_MASK; 3030 par->mmap_map[j].poff = base & PAGE_MASK; 3031 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK; 3032 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3033 par->mmap_map[j].prot_flag = _PAGE_E; 3034 j++; 3035 } 3036 3037 ret = correct_chipset(par); 3038 if (ret) 3039 return ret; 3040 3041 if (IS_XL(pdev->device)) { 3042 /* 3043 * Fix PROMs idea of MEM_CNTL settings... 3044 */ 3045 mem = aty_ld_le32(MEM_CNTL, par); 3046 chip_id = aty_ld_le32(CNFG_CHIP_ID, par); 3047 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { 3048 switch (mem & 0x0f) { 3049 case 3: 3050 mem = (mem & ~(0x0f)) | 2; 3051 break; 3052 case 7: 3053 mem = (mem & ~(0x0f)) | 3; 3054 break; 3055 case 9: 3056 mem = (mem & ~(0x0f)) | 4; 3057 break; 3058 case 11: 3059 mem = (mem & ~(0x0f)) | 5; 3060 break; 3061 default: 3062 break; 3063 } 3064 if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM) 3065 mem &= ~(0x00700000); 3066 } 3067 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ 3068 aty_st_le32(MEM_CNTL, mem, par); 3069 } 3070 3071 dp = pci_device_to_OF_node(pdev); 3072 if (dp == of_console_device) { 3073 struct fb_var_screeninfo *var = &default_var; 3074 unsigned int N, P, Q, M, T, R; 3075 struct crtc crtc; 3076 u8 pll_regs[16]; 3077 u8 clock_cntl; 3078 3079 crtc.vxres = of_getintprop_default(dp, "width", 1024); 3080 crtc.vyres = of_getintprop_default(dp, "height", 768); 3081 var->bits_per_pixel = of_getintprop_default(dp, "depth", 8); 3082 var->xoffset = var->yoffset = 0; 3083 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 3084 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 3085 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par); 3086 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par); 3087 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 3088 aty_crtc_to_var(&crtc, var); 3089 3090 /* 3091 * Read the PLL to figure actual Refresh Rate. 3092 */ 3093 clock_cntl = aty_ld_8(CLOCK_CNTL, par); 3094 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */ 3095 for (i = 0; i < 16; i++) 3096 pll_regs[i] = aty_ld_pll_ct(i, par); 3097 3098 /* 3099 * PLL Reference Divider M: 3100 */ 3101 M = pll_regs[PLL_REF_DIV]; 3102 3103 /* 3104 * PLL Feedback Divider N (Dependent on CLOCK_CNTL): 3105 */ 3106 N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)]; 3107 3108 /* 3109 * PLL Post Divider P (Dependent on CLOCK_CNTL): 3110 */ 3111 P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) | 3112 ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)]; 3113 3114 /* 3115 * PLL Divider Q: 3116 */ 3117 Q = N / P; 3118 3119 /* 3120 * Target Frequency: 3121 * 3122 * T * M 3123 * Q = ------- 3124 * 2 * R 3125 * 3126 * where R is XTALIN (= 14318 or 29498 kHz). 3127 */ 3128 if (IS_XL(pdev->device)) 3129 R = 29498; 3130 else 3131 R = 14318; 3132 3133 T = 2 * Q * R / M; 3134 3135 default_var.pixclock = 1000000000 / T; 3136 } 3137 3138 return 0; 3139 } 3140 3141 #else /* __sparc__ */ 3142 3143 #ifdef __i386__ 3144 #ifdef CONFIG_FB_ATY_GENERIC_LCD 3145 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) 3146 { 3147 u32 driv_inf_tab, sig; 3148 u16 lcd_ofs; 3149 3150 /* 3151 * To support an LCD panel, we should know it's dimensions and 3152 * it's desired pixel clock. 3153 * There are two ways to do it: 3154 * - Check the startup video mode and calculate the panel 3155 * size from it. This is unreliable. 3156 * - Read it from the driver information table in the video BIOS. 3157 */ 3158 /* Address of driver information table is at offset 0x78. */ 3159 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); 3160 3161 /* Check for the driver information table signature. */ 3162 sig = *(u32 *)driv_inf_tab; 3163 if ((sig == 0x54504c24) || /* Rage LT pro */ 3164 (sig == 0x544d5224) || /* Rage mobility */ 3165 (sig == 0x54435824) || /* Rage XC */ 3166 (sig == 0x544c5824)) { /* Rage XL */ 3167 PRINTKI("BIOS contains driver information table.\n"); 3168 lcd_ofs = *(u16 *)(driv_inf_tab + 10); 3169 par->lcd_table = 0; 3170 if (lcd_ofs != 0) 3171 par->lcd_table = bios_base + lcd_ofs; 3172 } 3173 3174 if (par->lcd_table != 0) { 3175 char model[24]; 3176 char strbuf[16]; 3177 char refresh_rates_buf[100]; 3178 int id, tech, f, i, m, default_refresh_rate; 3179 char *txtcolour; 3180 char *txtmonitor; 3181 char *txtdual; 3182 char *txtformat; 3183 u16 width, height, panel_type, refresh_rates; 3184 u16 *lcdmodeptr; 3185 u32 format; 3186 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85, 3187 90, 100, 120, 140, 150, 160, 200 }; 3188 /* 3189 * The most important information is the panel size at 3190 * offset 25 and 27, but there's some other nice information 3191 * which we print to the screen. 3192 */ 3193 id = *(u8 *)par->lcd_table; 3194 strncpy(model, (char *)par->lcd_table+1, 24); 3195 model[23] = 0; 3196 3197 width = par->lcd_width = *(u16 *)(par->lcd_table+25); 3198 height = par->lcd_height = *(u16 *)(par->lcd_table+27); 3199 panel_type = *(u16 *)(par->lcd_table+29); 3200 if (panel_type & 1) 3201 txtcolour = "colour"; 3202 else 3203 txtcolour = "monochrome"; 3204 if (panel_type & 2) 3205 txtdual = "dual (split) "; 3206 else 3207 txtdual = ""; 3208 tech = (panel_type >> 2) & 63; 3209 switch (tech) { 3210 case 0: 3211 txtmonitor = "passive matrix"; 3212 break; 3213 case 1: 3214 txtmonitor = "active matrix"; 3215 break; 3216 case 2: 3217 txtmonitor = "active addressed STN"; 3218 break; 3219 case 3: 3220 txtmonitor = "EL"; 3221 break; 3222 case 4: 3223 txtmonitor = "plasma"; 3224 break; 3225 default: 3226 txtmonitor = "unknown"; 3227 } 3228 format = *(u32 *)(par->lcd_table+57); 3229 if (tech == 0 || tech == 2) { 3230 switch (format & 7) { 3231 case 0: 3232 txtformat = "12 bit interface"; 3233 break; 3234 case 1: 3235 txtformat = "16 bit interface"; 3236 break; 3237 case 2: 3238 txtformat = "24 bit interface"; 3239 break; 3240 default: 3241 txtformat = "unknown format"; 3242 } 3243 } else { 3244 switch (format & 7) { 3245 case 0: 3246 txtformat = "8 colours"; 3247 break; 3248 case 1: 3249 txtformat = "512 colours"; 3250 break; 3251 case 2: 3252 txtformat = "4096 colours"; 3253 break; 3254 case 4: 3255 txtformat = "262144 colours (LT mode)"; 3256 break; 3257 case 5: 3258 txtformat = "16777216 colours"; 3259 break; 3260 case 6: 3261 txtformat = "262144 colours (FDPI-2 mode)"; 3262 break; 3263 default: 3264 txtformat = "unknown format"; 3265 } 3266 } 3267 PRINTKI("%s%s %s monitor detected: %s\n", 3268 txtdual, txtcolour, txtmonitor, model); 3269 PRINTKI(" id=%d, %dx%d pixels, %s\n", 3270 id, width, height, txtformat); 3271 refresh_rates_buf[0] = 0; 3272 refresh_rates = *(u16 *)(par->lcd_table+62); 3273 m = 1; 3274 f = 0; 3275 for (i = 0; i < 16; i++) { 3276 if (refresh_rates & m) { 3277 if (f == 0) { 3278 sprintf(strbuf, "%d", 3279 lcd_refresh_rates[i]); 3280 f++; 3281 } else { 3282 sprintf(strbuf, ",%d", 3283 lcd_refresh_rates[i]); 3284 } 3285 strcat(refresh_rates_buf, strbuf); 3286 } 3287 m = m << 1; 3288 } 3289 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4; 3290 PRINTKI(" supports refresh rates [%s], default %d Hz\n", 3291 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); 3292 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; 3293 /* 3294 * We now need to determine the crtc parameters for the 3295 * LCD monitor. This is tricky, because they are not stored 3296 * individually in the BIOS. Instead, the BIOS contains a 3297 * table of display modes that work for this monitor. 3298 * 3299 * The idea is that we search for a mode of the same dimensions 3300 * as the dimensions of the LCD monitor. Say our LCD monitor 3301 * is 800x600 pixels, we search for a 800x600 monitor. 3302 * The CRTC parameters we find here are the ones that we need 3303 * to use to simulate other resolutions on the LCD screen. 3304 */ 3305 lcdmodeptr = (u16 *)(par->lcd_table + 64); 3306 while (*lcdmodeptr != 0) { 3307 u32 modeptr; 3308 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start; 3309 modeptr = bios_base + *lcdmodeptr; 3310 3311 mwidth = *((u16 *)(modeptr+0)); 3312 mheight = *((u16 *)(modeptr+2)); 3313 3314 if (mwidth == width && mheight == height) { 3315 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9)); 3316 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511; 3317 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511; 3318 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511; 3319 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7; 3320 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63; 3321 3322 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047; 3323 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047; 3324 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047; 3325 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31; 3326 3327 par->lcd_htotal = (par->lcd_htotal + 1) * 8; 3328 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8; 3329 lcd_hsync_start = (lcd_hsync_start + 1) * 8; 3330 par->lcd_hsync_len = par->lcd_hsync_len * 8; 3331 3332 par->lcd_vtotal++; 3333 par->lcd_vdisp++; 3334 lcd_vsync_start++; 3335 3336 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp; 3337 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp; 3338 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp; 3339 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp; 3340 break; 3341 } 3342 3343 lcdmodeptr++; 3344 } 3345 if (*lcdmodeptr == 0) { 3346 PRINTKE("LCD monitor CRTC parameters not found!!!\n"); 3347 /* To do: Switch to CRT if possible. */ 3348 } else { 3349 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n", 3350 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock, 3351 par->lcd_hdisp, 3352 par->lcd_hdisp + par->lcd_right_margin, 3353 par->lcd_hdisp + par->lcd_right_margin 3354 + par->lcd_hsync_dly + par->lcd_hsync_len, 3355 par->lcd_htotal, 3356 par->lcd_vdisp, 3357 par->lcd_vdisp + par->lcd_lower_margin, 3358 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len, 3359 par->lcd_vtotal); 3360 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n", 3361 par->lcd_pixclock, 3362 par->lcd_hblank_len - (par->lcd_right_margin + 3363 par->lcd_hsync_dly + par->lcd_hsync_len), 3364 par->lcd_hdisp, 3365 par->lcd_right_margin, 3366 par->lcd_hsync_len, 3367 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len), 3368 par->lcd_vdisp, 3369 par->lcd_lower_margin, 3370 par->lcd_vsync_len); 3371 } 3372 } 3373 } 3374 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 3375 3376 static int init_from_bios(struct atyfb_par *par) 3377 { 3378 u32 bios_base, rom_addr; 3379 int ret; 3380 3381 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11); 3382 bios_base = (unsigned long)ioremap(rom_addr, 0x10000); 3383 3384 /* The BIOS starts with 0xaa55. */ 3385 if (*((u16 *)bios_base) == 0xaa55) { 3386 3387 u8 *bios_ptr; 3388 u16 rom_table_offset, freq_table_offset; 3389 PLL_BLOCK_MACH64 pll_block; 3390 3391 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base); 3392 3393 /* check for frequncy table */ 3394 bios_ptr = (u8*)bios_base; 3395 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8)); 3396 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8); 3397 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64)); 3398 3399 PRINTKI("BIOS frequency table:\n"); 3400 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n", 3401 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq, 3402 pll_block.ref_freq, pll_block.ref_divider); 3403 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n", 3404 pll_block.MCLK_pwd, pll_block.MCLK_max_freq, 3405 pll_block.XCLK_max_freq, pll_block.SCLK_freq); 3406 3407 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100; 3408 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100; 3409 par->pll_limits.ref_clk = pll_block.ref_freq/100; 3410 par->pll_limits.ref_div = pll_block.ref_divider; 3411 par->pll_limits.sclk = pll_block.SCLK_freq/100; 3412 par->pll_limits.mclk = pll_block.MCLK_max_freq/100; 3413 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100; 3414 par->pll_limits.xclk = pll_block.XCLK_max_freq/100; 3415 #ifdef CONFIG_FB_ATY_GENERIC_LCD 3416 aty_init_lcd(par, bios_base); 3417 #endif 3418 ret = 0; 3419 } else { 3420 PRINTKE("no BIOS frequency table found, use parameters\n"); 3421 ret = -ENXIO; 3422 } 3423 iounmap((void __iomem *)bios_base); 3424 3425 return ret; 3426 } 3427 #endif /* __i386__ */ 3428 3429 static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, 3430 unsigned long addr) 3431 { 3432 struct atyfb_par *par = info->par; 3433 u16 tmp; 3434 unsigned long raddr; 3435 struct resource *rrp; 3436 int ret = 0; 3437 3438 raddr = addr + 0x7ff000UL; 3439 rrp = &pdev->resource[2]; 3440 if ((rrp->flags & IORESOURCE_MEM) && 3441 request_mem_region(rrp->start, resource_size(rrp), "atyfb")) { 3442 par->aux_start = rrp->start; 3443 par->aux_size = resource_size(rrp); 3444 raddr = rrp->start; 3445 PRINTKI("using auxiliary register aperture\n"); 3446 } 3447 3448 info->fix.mmio_start = raddr; 3449 /* 3450 * By using strong UC we force the MTRR to never have an 3451 * effect on the MMIO region on both non-PAT and PAT systems. 3452 */ 3453 par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000); 3454 if (par->ati_regbase == NULL) 3455 return -ENOMEM; 3456 3457 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; 3458 par->ati_regbase += par->aux_start ? 0x400 : 0xc00; 3459 3460 /* 3461 * Enable memory-space accesses using config-space 3462 * command register. 3463 */ 3464 pci_read_config_word(pdev, PCI_COMMAND, &tmp); 3465 if (!(tmp & PCI_COMMAND_MEMORY)) { 3466 tmp |= PCI_COMMAND_MEMORY; 3467 pci_write_config_word(pdev, PCI_COMMAND, tmp); 3468 } 3469 #ifdef __BIG_ENDIAN 3470 /* Use the big-endian aperture */ 3471 addr += 0x800000; 3472 #endif 3473 3474 /* Map in frame buffer */ 3475 info->fix.smem_start = addr; 3476 3477 /* 3478 * The framebuffer is not always 8 MiB, that's just the size of the 3479 * PCI BAR. We temporarily abuse smem_len here to store the size 3480 * of the BAR. aty_init() will later correct it to match the actual 3481 * framebuffer size. 3482 * 3483 * On devices that don't have the auxiliary register aperture, the 3484 * registers are housed at the top end of the framebuffer PCI BAR. 3485 * aty_fudge_framebuffer_len() is used to reduce smem_len to not 3486 * overlap with the registers. 3487 */ 3488 info->fix.smem_len = 0x800000; 3489 3490 aty_fudge_framebuffer_len(info); 3491 3492 info->screen_base = ioremap_wc(info->fix.smem_start, 3493 info->fix.smem_len); 3494 if (info->screen_base == NULL) { 3495 ret = -ENOMEM; 3496 goto atyfb_setup_generic_fail; 3497 } 3498 3499 ret = correct_chipset(par); 3500 if (ret) 3501 goto atyfb_setup_generic_fail; 3502 #ifdef __i386__ 3503 ret = init_from_bios(par); 3504 if (ret) 3505 goto atyfb_setup_generic_fail; 3506 #endif 3507 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN)) 3508 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2; 3509 else 3510 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U; 3511 3512 /* according to ATI, we should use clock 3 for acelerated mode */ 3513 par->clk_wr_offset = 3; 3514 3515 return 0; 3516 3517 atyfb_setup_generic_fail: 3518 iounmap(par->ati_regbase); 3519 par->ati_regbase = NULL; 3520 if (info->screen_base) { 3521 iounmap(info->screen_base); 3522 info->screen_base = NULL; 3523 } 3524 return ret; 3525 } 3526 3527 #endif /* !__sparc__ */ 3528 3529 static int atyfb_pci_probe(struct pci_dev *pdev, 3530 const struct pci_device_id *ent) 3531 { 3532 unsigned long addr, res_start, res_size; 3533 struct fb_info *info; 3534 struct resource *rp; 3535 struct atyfb_par *par; 3536 int rc = -ENOMEM; 3537 3538 /* Enable device in PCI config */ 3539 if (pci_enable_device(pdev)) { 3540 PRINTKE("Cannot enable PCI device\n"); 3541 return -ENXIO; 3542 } 3543 3544 /* Find which resource to use */ 3545 rp = &pdev->resource[0]; 3546 if (rp->flags & IORESOURCE_IO) 3547 rp = &pdev->resource[1]; 3548 addr = rp->start; 3549 if (!addr) 3550 return -ENXIO; 3551 3552 /* Reserve space */ 3553 res_start = rp->start; 3554 res_size = resource_size(rp); 3555 if (!request_mem_region(res_start, res_size, "atyfb")) 3556 return -EBUSY; 3557 3558 /* Allocate framebuffer */ 3559 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); 3560 if (!info) 3561 return -ENOMEM; 3562 3563 par = info->par; 3564 par->bus_type = PCI; 3565 info->fix = atyfb_fix; 3566 info->device = &pdev->dev; 3567 par->pci_id = pdev->device; 3568 par->res_start = res_start; 3569 par->res_size = res_size; 3570 par->irq = pdev->irq; 3571 par->pdev = pdev; 3572 3573 /* Setup "info" structure */ 3574 #ifdef __sparc__ 3575 rc = atyfb_setup_sparc(pdev, info, addr); 3576 #else 3577 rc = atyfb_setup_generic(pdev, info, addr); 3578 #endif 3579 if (rc) 3580 goto err_release_mem; 3581 3582 pci_set_drvdata(pdev, info); 3583 3584 /* Init chip & register framebuffer */ 3585 rc = aty_init(info); 3586 if (rc) 3587 goto err_release_io; 3588 3589 #ifdef __sparc__ 3590 /* 3591 * Add /dev/fb mmap values. 3592 */ 3593 par->mmap_map[0].voff = 0x8000000000000000UL; 3594 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK; 3595 par->mmap_map[0].size = info->fix.smem_len; 3596 par->mmap_map[0].prot_mask = _PAGE_CACHE; 3597 par->mmap_map[0].prot_flag = _PAGE_E; 3598 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len; 3599 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK; 3600 par->mmap_map[1].size = PAGE_SIZE; 3601 par->mmap_map[1].prot_mask = _PAGE_CACHE; 3602 par->mmap_map[1].prot_flag = _PAGE_E; 3603 #endif /* __sparc__ */ 3604 3605 mutex_lock(&reboot_lock); 3606 if (!reboot_info) 3607 reboot_info = info; 3608 mutex_unlock(&reboot_lock); 3609 3610 return 0; 3611 3612 err_release_io: 3613 #ifdef __sparc__ 3614 kfree(par->mmap_map); 3615 #else 3616 if (par->ati_regbase) 3617 iounmap(par->ati_regbase); 3618 if (info->screen_base) 3619 iounmap(info->screen_base); 3620 #endif 3621 err_release_mem: 3622 if (par->aux_start) 3623 release_mem_region(par->aux_start, par->aux_size); 3624 3625 release_mem_region(par->res_start, par->res_size); 3626 framebuffer_release(info); 3627 3628 return rc; 3629 } 3630 3631 #endif /* CONFIG_PCI */ 3632 3633 #ifdef CONFIG_ATARI 3634 3635 static int __init atyfb_atari_probe(void) 3636 { 3637 struct atyfb_par *par; 3638 struct fb_info *info; 3639 int m64_num; 3640 u32 clock_r; 3641 int num_found = 0; 3642 3643 for (m64_num = 0; m64_num < mach64_count; m64_num++) { 3644 if (!phys_vmembase[m64_num] || !phys_size[m64_num] || 3645 !phys_guiregbase[m64_num]) { 3646 PRINTKI("phys_*[%d] parameters not set => " 3647 "returning early. \n", m64_num); 3648 continue; 3649 } 3650 3651 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL); 3652 if (!info) 3653 return -ENOMEM; 3654 3655 par = info->par; 3656 3657 info->fix = atyfb_fix; 3658 3659 par->irq = (unsigned int) -1; /* something invalid */ 3660 3661 /* 3662 * Map the video memory (physical address given) 3663 * to somewhere in the kernel address space. 3664 */ 3665 info->screen_base = ioremap_wc(phys_vmembase[m64_num], 3666 phys_size[m64_num]); 3667 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ 3668 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) + 3669 0xFC00ul; 3670 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */ 3671 3672 aty_st_le32(CLOCK_CNTL, 0x12345678, par); 3673 clock_r = aty_ld_le32(CLOCK_CNTL, par); 3674 3675 switch (clock_r & 0x003F) { 3676 case 0x12: 3677 par->clk_wr_offset = 3; /* */ 3678 break; 3679 case 0x34: 3680 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */ 3681 break; 3682 case 0x16: 3683 par->clk_wr_offset = 1; /* */ 3684 break; 3685 case 0x38: 3686 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */ 3687 break; 3688 } 3689 3690 /* Fake pci_id for correct_chipset() */ 3691 switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) { 3692 case 0x00d7: 3693 par->pci_id = PCI_CHIP_MACH64GX; 3694 break; 3695 case 0x0057: 3696 par->pci_id = PCI_CHIP_MACH64CX; 3697 break; 3698 default: 3699 break; 3700 } 3701 3702 if (correct_chipset(par) || aty_init(info)) { 3703 iounmap(info->screen_base); 3704 iounmap(par->ati_regbase); 3705 framebuffer_release(info); 3706 } else { 3707 num_found++; 3708 } 3709 } 3710 3711 return num_found ? 0 : -ENXIO; 3712 } 3713 3714 #endif /* CONFIG_ATARI */ 3715 3716 #ifdef CONFIG_PCI 3717 3718 static void atyfb_remove(struct fb_info *info) 3719 { 3720 struct atyfb_par *par = (struct atyfb_par *) info->par; 3721 3722 /* restore video mode */ 3723 aty_set_crtc(par, &par->saved_crtc); 3724 par->pll_ops->set_pll(info, &par->saved_pll); 3725 3726 unregister_framebuffer(info); 3727 3728 #ifdef CONFIG_FB_ATY_BACKLIGHT 3729 if (M64_HAS(MOBIL_BUS)) 3730 aty_bl_exit(info->bl_dev); 3731 #endif 3732 arch_phys_wc_del(par->wc_cookie); 3733 3734 #ifndef __sparc__ 3735 if (par->ati_regbase) 3736 iounmap(par->ati_regbase); 3737 if (info->screen_base) 3738 iounmap(info->screen_base); 3739 #ifdef __BIG_ENDIAN 3740 if (info->sprite.addr) 3741 iounmap(info->sprite.addr); 3742 #endif 3743 #endif 3744 #ifdef __sparc__ 3745 kfree(par->mmap_map); 3746 #endif 3747 if (par->aux_start) 3748 release_mem_region(par->aux_start, par->aux_size); 3749 3750 if (par->res_start) 3751 release_mem_region(par->res_start, par->res_size); 3752 3753 framebuffer_release(info); 3754 } 3755 3756 3757 static void atyfb_pci_remove(struct pci_dev *pdev) 3758 { 3759 struct fb_info *info = pci_get_drvdata(pdev); 3760 3761 mutex_lock(&reboot_lock); 3762 if (reboot_info == info) 3763 reboot_info = NULL; 3764 mutex_unlock(&reboot_lock); 3765 3766 atyfb_remove(info); 3767 } 3768 3769 static const struct pci_device_id atyfb_pci_tbl[] = { 3770 #ifdef CONFIG_FB_ATY_GX 3771 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) }, 3772 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) }, 3773 #endif /* CONFIG_FB_ATY_GX */ 3774 3775 #ifdef CONFIG_FB_ATY_CT 3776 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CT) }, 3777 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64ET) }, 3778 3779 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LT) }, 3780 3781 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VT) }, 3782 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GT) }, 3783 3784 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VU) }, 3785 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GU) }, 3786 3787 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LG) }, 3788 3789 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VV) }, 3790 3791 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GV) }, 3792 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GW) }, 3793 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GY) }, 3794 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GZ) }, 3795 3796 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GB) }, 3797 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GD) }, 3798 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GI) }, 3799 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GP) }, 3800 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GQ) }, 3801 3802 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LB) }, 3803 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LD) }, 3804 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LI) }, 3805 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LP) }, 3806 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LQ) }, 3807 3808 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GM) }, 3809 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GN) }, 3810 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GO) }, 3811 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GL) }, 3812 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GR) }, 3813 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GS) }, 3814 3815 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LM) }, 3816 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LN) }, 3817 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LR) }, 3818 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LS) }, 3819 #endif /* CONFIG_FB_ATY_CT */ 3820 { } 3821 }; 3822 3823 MODULE_DEVICE_TABLE(pci, atyfb_pci_tbl); 3824 3825 static struct pci_driver atyfb_driver = { 3826 .name = "atyfb", 3827 .id_table = atyfb_pci_tbl, 3828 .probe = atyfb_pci_probe, 3829 .remove = atyfb_pci_remove, 3830 .driver.pm = &atyfb_pci_pm_ops, 3831 }; 3832 3833 #endif /* CONFIG_PCI */ 3834 3835 #ifndef MODULE 3836 static int __init atyfb_setup(char *options) 3837 { 3838 char *this_opt; 3839 3840 if (!options || !*options) 3841 return 0; 3842 3843 while ((this_opt = strsep(&options, ",")) != NULL) { 3844 if (!strncmp(this_opt, "noaccel", 7)) { 3845 noaccel = true; 3846 } else if (!strncmp(this_opt, "nomtrr", 6)) { 3847 nomtrr = true; 3848 } else if (!strncmp(this_opt, "vram:", 5)) 3849 vram = simple_strtoul(this_opt + 5, NULL, 0); 3850 else if (!strncmp(this_opt, "pll:", 4)) 3851 pll = simple_strtoul(this_opt + 4, NULL, 0); 3852 else if (!strncmp(this_opt, "mclk:", 5)) 3853 mclk = simple_strtoul(this_opt + 5, NULL, 0); 3854 else if (!strncmp(this_opt, "xclk:", 5)) 3855 xclk = simple_strtoul(this_opt+5, NULL, 0); 3856 else if (!strncmp(this_opt, "comp_sync:", 10)) 3857 comp_sync = simple_strtoul(this_opt+10, NULL, 0); 3858 else if (!strncmp(this_opt, "backlight:", 10)) 3859 backlight = simple_strtoul(this_opt+10, NULL, 0); 3860 #ifdef CONFIG_PPC 3861 else if (!strncmp(this_opt, "vmode:", 6)) { 3862 unsigned int vmode = 3863 simple_strtoul(this_opt + 6, NULL, 0); 3864 if (vmode > 0 && vmode <= VMODE_MAX) 3865 default_vmode = vmode; 3866 } else if (!strncmp(this_opt, "cmode:", 6)) { 3867 unsigned int cmode = 3868 simple_strtoul(this_opt + 6, NULL, 0); 3869 switch (cmode) { 3870 case 0: 3871 case 8: 3872 default_cmode = CMODE_8; 3873 break; 3874 case 15: 3875 case 16: 3876 default_cmode = CMODE_16; 3877 break; 3878 case 24: 3879 case 32: 3880 default_cmode = CMODE_32; 3881 break; 3882 } 3883 } 3884 #endif 3885 #ifdef CONFIG_ATARI 3886 /* 3887 * Why do we need this silly Mach64 argument? 3888 * We are already here because of mach64= so its redundant. 3889 */ 3890 else if (MACH_IS_ATARI 3891 && (!strncmp(this_opt, "Mach64:", 7))) { 3892 static unsigned char m64_num; 3893 static char mach64_str[80]; 3894 strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str)); 3895 if (!store_video_par(mach64_str, m64_num)) { 3896 m64_num++; 3897 mach64_count = m64_num; 3898 } 3899 } 3900 #endif 3901 else 3902 mode = this_opt; 3903 } 3904 return 0; 3905 } 3906 #endif /* MODULE */ 3907 3908 static int atyfb_reboot_notify(struct notifier_block *nb, 3909 unsigned long code, void *unused) 3910 { 3911 struct atyfb_par *par; 3912 3913 if (code != SYS_RESTART) 3914 return NOTIFY_DONE; 3915 3916 mutex_lock(&reboot_lock); 3917 3918 if (!reboot_info) 3919 goto out; 3920 3921 lock_fb_info(reboot_info); 3922 3923 par = reboot_info->par; 3924 3925 /* 3926 * HP OmniBook 500's BIOS doesn't like the state of the 3927 * hardware after atyfb has been used. Restore the hardware 3928 * to the original state to allow successful reboots. 3929 */ 3930 aty_set_crtc(par, &par->saved_crtc); 3931 par->pll_ops->set_pll(reboot_info, &par->saved_pll); 3932 3933 unlock_fb_info(reboot_info); 3934 out: 3935 mutex_unlock(&reboot_lock); 3936 3937 return NOTIFY_DONE; 3938 } 3939 3940 static struct notifier_block atyfb_reboot_notifier = { 3941 .notifier_call = atyfb_reboot_notify, 3942 }; 3943 3944 static const struct dmi_system_id atyfb_reboot_ids[] __initconst = { 3945 { 3946 .ident = "HP OmniBook 500", 3947 .matches = { 3948 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 3949 DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), 3950 DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), 3951 }, 3952 }, 3953 3954 { } 3955 }; 3956 static bool registered_notifier = false; 3957 3958 static int __init atyfb_init(void) 3959 { 3960 int err1 = 1, err2 = 1; 3961 #ifndef MODULE 3962 char *option = NULL; 3963 3964 if (fb_get_options("atyfb", &option)) 3965 return -ENODEV; 3966 atyfb_setup(option); 3967 #endif 3968 3969 #ifdef CONFIG_PCI 3970 err1 = pci_register_driver(&atyfb_driver); 3971 #endif 3972 #ifdef CONFIG_ATARI 3973 err2 = atyfb_atari_probe(); 3974 #endif 3975 3976 if (err1 && err2) 3977 return -ENODEV; 3978 3979 if (dmi_check_system(atyfb_reboot_ids)) { 3980 register_reboot_notifier(&atyfb_reboot_notifier); 3981 registered_notifier = true; 3982 } 3983 3984 return 0; 3985 } 3986 3987 static void __exit atyfb_exit(void) 3988 { 3989 if (registered_notifier) 3990 unregister_reboot_notifier(&atyfb_reboot_notifier); 3991 3992 #ifdef CONFIG_PCI 3993 pci_unregister_driver(&atyfb_driver); 3994 #endif 3995 } 3996 3997 module_init(atyfb_init); 3998 module_exit(atyfb_exit); 3999 4000 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards"); 4001 MODULE_LICENSE("GPL"); 4002 module_param(noaccel, bool, 0); 4003 MODULE_PARM_DESC(noaccel, "bool: disable acceleration"); 4004 module_param(vram, int, 0); 4005 MODULE_PARM_DESC(vram, "int: override size of video ram"); 4006 module_param(pll, int, 0); 4007 MODULE_PARM_DESC(pll, "int: override video clock"); 4008 module_param(mclk, int, 0); 4009 MODULE_PARM_DESC(mclk, "int: override memory clock"); 4010 module_param(xclk, int, 0); 4011 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); 4012 module_param(comp_sync, int, 0); 4013 MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)"); 4014 module_param(mode, charp, 0); 4015 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); 4016 module_param(nomtrr, bool, 0); 4017 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); 4018