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