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 = FB_BLANK_UNBLANK; 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 par->pll_ops->init_pll(info, &par->pll); 2619 if (par->pll_ops->resume_pll) 2620 par->pll_ops->resume_pll(info, &par->pll); 2621 2622 aty_fudge_framebuffer_len(info); 2623 2624 /* 2625 * Disable register access through the linear aperture 2626 * if the auxiliary aperture is used so we can access 2627 * the full 8 MB of video RAM on 8 MB boards. 2628 */ 2629 if (par->aux_start) 2630 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | 2631 BUS_APER_REG_DIS, par); 2632 2633 if (!nomtrr) 2634 /* 2635 * Only the ioremap_wc()'d area will get WC here 2636 * since ioremap_uc() was used on the entire PCI BAR. 2637 */ 2638 par->wc_cookie = arch_phys_wc_add(par->res_start, 2639 par->res_size); 2640 2641 info->fbops = &atyfb_ops; 2642 info->pseudo_palette = par->pseudo_palette; 2643 info->flags = FBINFO_HWACCEL_IMAGEBLIT | 2644 FBINFO_HWACCEL_FILLRECT | 2645 FBINFO_HWACCEL_COPYAREA | 2646 FBINFO_HWACCEL_YPAN | 2647 FBINFO_READS_FAST; 2648 2649 #ifdef CONFIG_PMAC_BACKLIGHT 2650 if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) { 2651 /* 2652 * these bits let the 101 powerbook 2653 * wake up from sleep -- paulus 2654 */ 2655 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | 2656 USE_F32KHZ | TRISTATE_MEM_EN, par); 2657 } else 2658 #endif 2659 2660 memset(&var, 0, sizeof(var)); 2661 #ifdef CONFIG_PPC 2662 if (machine_is(powermac)) { 2663 /* 2664 * FIXME: The NVRAM stuff should be put in a Mac-specific file, 2665 * as it applies to all Mac video cards 2666 */ 2667 if (mode) { 2668 if (mac_find_mode(&var, info, mode, 8)) 2669 has_var = 1; 2670 } else { 2671 if (default_vmode == VMODE_CHOOSE) { 2672 int sense; 2673 if (M64_HAS(G3_PB_1024x768)) 2674 /* G3 PowerBook with 1024x768 LCD */ 2675 default_vmode = VMODE_1024_768_60; 2676 else if (of_machine_is_compatible("iMac")) 2677 default_vmode = VMODE_1024_768_75; 2678 else if (of_machine_is_compatible("PowerBook2,1")) 2679 /* iBook with 800x600 LCD */ 2680 default_vmode = VMODE_800_600_60; 2681 else 2682 default_vmode = VMODE_640_480_67; 2683 sense = read_aty_sense(par); 2684 PRINTKI("monitor sense=%x, mode %d\n", 2685 sense, mac_map_monitor_sense(sense)); 2686 } 2687 if (default_vmode <= 0 || default_vmode > VMODE_MAX) 2688 default_vmode = VMODE_640_480_60; 2689 if (default_cmode < CMODE_8 || default_cmode > CMODE_32) 2690 default_cmode = CMODE_8; 2691 if (!mac_vmode_to_var(default_vmode, default_cmode, 2692 &var)) 2693 has_var = 1; 2694 } 2695 } 2696 2697 #endif /* !CONFIG_PPC */ 2698 2699 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) 2700 if (!atyfb_get_timings_from_lcd(par, &var)) 2701 has_var = 1; 2702 #endif 2703 2704 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) 2705 has_var = 1; 2706 2707 if (!has_var) 2708 var = default_var; 2709 2710 if (noaccel) 2711 var.accel_flags &= ~FB_ACCELF_TEXT; 2712 else 2713 var.accel_flags |= FB_ACCELF_TEXT; 2714 2715 if (comp_sync != -1) { 2716 if (!comp_sync) 2717 var.sync &= ~FB_SYNC_COMP_HIGH_ACT; 2718 else 2719 var.sync |= FB_SYNC_COMP_HIGH_ACT; 2720 } 2721 2722 if (var.yres == var.yres_virtual) { 2723 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); 2724 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual; 2725 if (var.yres_virtual < var.yres) 2726 var.yres_virtual = var.yres; 2727 } 2728 2729 ret = atyfb_check_var(&var, info); 2730 if (ret) { 2731 PRINTKE("can't set default video mode\n"); 2732 goto aty_init_exit; 2733 } 2734 2735 #ifdef CONFIG_FB_ATY_CT 2736 if (!noaccel && M64_HAS(INTEGRATED)) 2737 aty_init_cursor(info, &atyfb_ops); 2738 #endif /* CONFIG_FB_ATY_CT */ 2739 info->var = var; 2740 2741 ret = fb_alloc_cmap(&info->cmap, 256, 0); 2742 if (ret < 0) 2743 goto aty_init_exit; 2744 2745 ret = register_framebuffer(info); 2746 if (ret < 0) { 2747 fb_dealloc_cmap(&info->cmap); 2748 goto aty_init_exit; 2749 } 2750 2751 if (M64_HAS(MOBIL_BUS) && backlight) { 2752 #ifdef CONFIG_FB_ATY_BACKLIGHT 2753 aty_bl_init(par); 2754 #endif 2755 } 2756 2757 fb_list = info; 2758 2759 PRINTKI("fb%d: %s frame buffer device on %s\n", 2760 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI"); 2761 return 0; 2762 2763 aty_init_exit: 2764 /* restore video mode */ 2765 aty_set_crtc(par, &par->saved_crtc); 2766 par->pll_ops->set_pll(info, &par->saved_pll); 2767 arch_phys_wc_del(par->wc_cookie); 2768 2769 return ret; 2770 } 2771 2772 #if defined(CONFIG_ATARI) && !defined(MODULE) 2773 static int store_video_par(char *video_str, unsigned char m64_num) 2774 { 2775 char *p; 2776 unsigned long vmembase, size, guiregbase; 2777 2778 PRINTKI("store_video_par() '%s' \n", video_str); 2779 2780 if (!(p = strsep(&video_str, ";")) || !*p) 2781 goto mach64_invalid; 2782 vmembase = simple_strtoul(p, NULL, 0); 2783 if (!(p = strsep(&video_str, ";")) || !*p) 2784 goto mach64_invalid; 2785 size = simple_strtoul(p, NULL, 0); 2786 if (!(p = strsep(&video_str, ";")) || !*p) 2787 goto mach64_invalid; 2788 guiregbase = simple_strtoul(p, NULL, 0); 2789 2790 phys_vmembase[m64_num] = vmembase; 2791 phys_size[m64_num] = size; 2792 phys_guiregbase[m64_num] = guiregbase; 2793 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, 2794 guiregbase); 2795 return 0; 2796 2797 mach64_invalid: 2798 phys_vmembase[m64_num] = 0; 2799 return -1; 2800 } 2801 #endif /* CONFIG_ATARI && !MODULE */ 2802 2803 /* 2804 * Blank the display. 2805 */ 2806 2807 static int atyfb_blank(int blank, struct fb_info *info) 2808 { 2809 struct atyfb_par *par = (struct atyfb_par *) info->par; 2810 u32 gen_cntl; 2811 2812 if (par->lock_blank || par->asleep) 2813 return 0; 2814 2815 #ifdef CONFIG_FB_ATY_GENERIC_LCD 2816 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2817 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2818 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2819 pm &= ~PWR_BLON; 2820 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2821 } 2822 #endif 2823 2824 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 2825 gen_cntl &= ~0x400004c; 2826 switch (blank) { 2827 case FB_BLANK_UNBLANK: 2828 break; 2829 case FB_BLANK_NORMAL: 2830 gen_cntl |= 0x4000040; 2831 break; 2832 case FB_BLANK_VSYNC_SUSPEND: 2833 gen_cntl |= 0x4000048; 2834 break; 2835 case FB_BLANK_HSYNC_SUSPEND: 2836 gen_cntl |= 0x4000044; 2837 break; 2838 case FB_BLANK_POWERDOWN: 2839 gen_cntl |= 0x400004c; 2840 break; 2841 } 2842 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2843 2844 #ifdef CONFIG_FB_ATY_GENERIC_LCD 2845 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2846 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2847 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2848 pm |= PWR_BLON; 2849 aty_st_lcd(POWER_MANAGEMENT, pm, par); 2850 } 2851 #endif 2852 2853 return 0; 2854 } 2855 2856 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue, 2857 const struct atyfb_par *par) 2858 { 2859 aty_st_8(DAC_W_INDEX, regno, par); 2860 aty_st_8(DAC_DATA, red, par); 2861 aty_st_8(DAC_DATA, green, par); 2862 aty_st_8(DAC_DATA, blue, par); 2863 } 2864 2865 /* 2866 * Set a single color register. The values supplied are already 2867 * rounded down to the hardware's capabilities (according to the 2868 * entries in the var structure). Return != 0 for invalid regno. 2869 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR 2870 */ 2871 2872 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 2873 u_int transp, struct fb_info *info) 2874 { 2875 struct atyfb_par *par = (struct atyfb_par *) info->par; 2876 int i, depth; 2877 u32 *pal = info->pseudo_palette; 2878 2879 depth = info->var.bits_per_pixel; 2880 if (depth == 16) 2881 depth = (info->var.green.length == 5) ? 15 : 16; 2882 2883 if (par->asleep) 2884 return 0; 2885 2886 if (regno > 255 || 2887 (depth == 16 && regno > 63) || 2888 (depth == 15 && regno > 31)) 2889 return 1; 2890 2891 red >>= 8; 2892 green >>= 8; 2893 blue >>= 8; 2894 2895 par->palette[regno].red = red; 2896 par->palette[regno].green = green; 2897 par->palette[regno].blue = blue; 2898 2899 if (regno < 16) { 2900 switch (depth) { 2901 case 15: 2902 pal[regno] = (regno << 10) | (regno << 5) | regno; 2903 break; 2904 case 16: 2905 pal[regno] = (regno << 11) | (regno << 5) | regno; 2906 break; 2907 case 24: 2908 pal[regno] = (regno << 16) | (regno << 8) | regno; 2909 break; 2910 case 32: 2911 i = (regno << 8) | regno; 2912 pal[regno] = (i << 16) | i; 2913 break; 2914 } 2915 } 2916 2917 i = aty_ld_8(DAC_CNTL, par) & 0xfc; 2918 if (M64_HAS(EXTRA_BRIGHT)) 2919 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */ 2920 aty_st_8(DAC_CNTL, i, par); 2921 aty_st_8(DAC_MASK, 0xff, par); 2922 2923 if (M64_HAS(INTEGRATED)) { 2924 if (depth == 16) { 2925 if (regno < 32) 2926 aty_st_pal(regno << 3, red, 2927 par->palette[regno << 1].green, 2928 blue, par); 2929 red = par->palette[regno >> 1].red; 2930 blue = par->palette[regno >> 1].blue; 2931 regno <<= 2; 2932 } else if (depth == 15) { 2933 regno <<= 3; 2934 for (i = 0; i < 8; i++) 2935 aty_st_pal(regno + i, red, green, blue, par); 2936 } 2937 } 2938 aty_st_pal(regno, red, green, blue, par); 2939 2940 return 0; 2941 } 2942 2943 #ifdef CONFIG_PCI 2944 2945 #ifdef __sparc__ 2946 2947 static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, 2948 unsigned long addr) 2949 { 2950 struct atyfb_par *par = info->par; 2951 struct device_node *dp; 2952 u32 mem, chip_id; 2953 int i, j, ret; 2954 2955 /* 2956 * Map memory-mapped registers. 2957 */ 2958 par->ati_regbase = (void *)addr + 0x7ffc00UL; 2959 info->fix.mmio_start = addr + 0x7ffc00UL; 2960 2961 /* 2962 * Map in big-endian aperture. 2963 */ 2964 info->screen_base = (char *) (addr + 0x800000UL); 2965 info->fix.smem_start = addr + 0x800000UL; 2966 2967 /* 2968 * Figure mmap addresses from PCI config space. 2969 * Split Framebuffer in big- and little-endian halfs. 2970 */ 2971 for (i = 0; i < 6 && pdev->resource[i].start; i++) 2972 /* nothing */ ; 2973 j = i + 4; 2974 2975 par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC); 2976 if (!par->mmap_map) { 2977 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n"); 2978 return -ENOMEM; 2979 } 2980 2981 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) { 2982 struct resource *rp = &pdev->resource[i]; 2983 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2); 2984 unsigned long base; 2985 u32 size, pbase; 2986 2987 base = rp->start; 2988 2989 io = (rp->flags & IORESOURCE_IO); 2990 2991 size = rp->end - base + 1; 2992 2993 pci_read_config_dword(pdev, breg, &pbase); 2994 2995 if (io) 2996 size &= ~1; 2997 2998 /* 2999 * Map the framebuffer a second time, this time without 3000 * the braindead _PAGE_IE setting. This is used by the 3001 * fixed Xserver, but we need to maintain the old mapping 3002 * to stay compatible with older ones... 3003 */ 3004 if (base == addr) { 3005 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK; 3006 par->mmap_map[j].poff = base & PAGE_MASK; 3007 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK; 3008 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3009 par->mmap_map[j].prot_flag = _PAGE_E; 3010 j++; 3011 } 3012 3013 /* 3014 * Here comes the old framebuffer mapping with _PAGE_IE 3015 * set for the big endian half of the framebuffer... 3016 */ 3017 if (base == addr) { 3018 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK; 3019 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK; 3020 par->mmap_map[j].size = 0x800000; 3021 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3022 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE; 3023 size -= 0x800000; 3024 j++; 3025 } 3026 3027 par->mmap_map[j].voff = pbase & PAGE_MASK; 3028 par->mmap_map[j].poff = base & PAGE_MASK; 3029 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK; 3030 par->mmap_map[j].prot_mask = _PAGE_CACHE; 3031 par->mmap_map[j].prot_flag = _PAGE_E; 3032 j++; 3033 } 3034 3035 ret = correct_chipset(par); 3036 if (ret) 3037 return ret; 3038 3039 if (IS_XL(pdev->device)) { 3040 /* 3041 * Fix PROMs idea of MEM_CNTL settings... 3042 */ 3043 mem = aty_ld_le32(MEM_CNTL, par); 3044 chip_id = aty_ld_le32(CNFG_CHIP_ID, par); 3045 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { 3046 switch (mem & 0x0f) { 3047 case 3: 3048 mem = (mem & ~(0x0f)) | 2; 3049 break; 3050 case 7: 3051 mem = (mem & ~(0x0f)) | 3; 3052 break; 3053 case 9: 3054 mem = (mem & ~(0x0f)) | 4; 3055 break; 3056 case 11: 3057 mem = (mem & ~(0x0f)) | 5; 3058 break; 3059 default: 3060 break; 3061 } 3062 if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM) 3063 mem &= ~(0x00700000); 3064 } 3065 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ 3066 aty_st_le32(MEM_CNTL, mem, par); 3067 } 3068 3069 dp = pci_device_to_OF_node(pdev); 3070 if (dp == of_console_device) { 3071 struct fb_var_screeninfo *var = &default_var; 3072 unsigned int N, P, Q, M, T, R; 3073 struct crtc crtc; 3074 u8 pll_regs[16]; 3075 u8 clock_cntl; 3076 3077 crtc.vxres = of_getintprop_default(dp, "width", 1024); 3078 crtc.vyres = of_getintprop_default(dp, "height", 768); 3079 var->bits_per_pixel = of_getintprop_default(dp, "depth", 8); 3080 var->xoffset = var->yoffset = 0; 3081 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); 3082 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); 3083 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par); 3084 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par); 3085 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 3086 aty_crtc_to_var(&crtc, var); 3087 3088 /* 3089 * Read the PLL to figure actual Refresh Rate. 3090 */ 3091 clock_cntl = aty_ld_8(CLOCK_CNTL, par); 3092 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */ 3093 for (i = 0; i < 16; i++) 3094 pll_regs[i] = aty_ld_pll_ct(i, par); 3095 3096 /* 3097 * PLL Reference Divider M: 3098 */ 3099 M = pll_regs[PLL_REF_DIV]; 3100 3101 /* 3102 * PLL Feedback Divider N (Dependent on CLOCK_CNTL): 3103 */ 3104 N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)]; 3105 3106 /* 3107 * PLL Post Divider P (Dependent on CLOCK_CNTL): 3108 */ 3109 P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) | 3110 ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)]; 3111 3112 /* 3113 * PLL Divider Q: 3114 */ 3115 Q = N / P; 3116 3117 /* 3118 * Target Frequency: 3119 * 3120 * T * M 3121 * Q = ------- 3122 * 2 * R 3123 * 3124 * where R is XTALIN (= 14318 or 29498 kHz). 3125 */ 3126 if (IS_XL(pdev->device)) 3127 R = 29498; 3128 else 3129 R = 14318; 3130 3131 T = 2 * Q * R / M; 3132 3133 default_var.pixclock = 1000000000 / T; 3134 } 3135 3136 return 0; 3137 } 3138 3139 #else /* __sparc__ */ 3140 3141 #ifdef __i386__ 3142 #ifdef CONFIG_FB_ATY_GENERIC_LCD 3143 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) 3144 { 3145 u32 driv_inf_tab, sig; 3146 u16 lcd_ofs; 3147 3148 /* 3149 * To support an LCD panel, we should know it's dimensions and 3150 * it's desired pixel clock. 3151 * There are two ways to do it: 3152 * - Check the startup video mode and calculate the panel 3153 * size from it. This is unreliable. 3154 * - Read it from the driver information table in the video BIOS. 3155 */ 3156 /* Address of driver information table is at offset 0x78. */ 3157 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); 3158 3159 /* Check for the driver information table signature. */ 3160 sig = *(u32 *)driv_inf_tab; 3161 if ((sig == 0x54504c24) || /* Rage LT pro */ 3162 (sig == 0x544d5224) || /* Rage mobility */ 3163 (sig == 0x54435824) || /* Rage XC */ 3164 (sig == 0x544c5824)) { /* Rage XL */ 3165 PRINTKI("BIOS contains driver information table.\n"); 3166 lcd_ofs = *(u16 *)(driv_inf_tab + 10); 3167 par->lcd_table = 0; 3168 if (lcd_ofs != 0) 3169 par->lcd_table = bios_base + lcd_ofs; 3170 } 3171 3172 if (par->lcd_table != 0) { 3173 char model[24]; 3174 char strbuf[16]; 3175 char refresh_rates_buf[100]; 3176 int id, tech, f, i, m, default_refresh_rate; 3177 char *txtcolour; 3178 char *txtmonitor; 3179 char *txtdual; 3180 char *txtformat; 3181 u16 width, height, panel_type, refresh_rates; 3182 u16 *lcdmodeptr; 3183 u32 format; 3184 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85, 3185 90, 100, 120, 140, 150, 160, 200 }; 3186 /* 3187 * The most important information is the panel size at 3188 * offset 25 and 27, but there's some other nice information 3189 * which we print to the screen. 3190 */ 3191 id = *(u8 *)par->lcd_table; 3192 strscpy(model, (char *)par->lcd_table+1, sizeof(model)); 3193 3194 width = par->lcd_width = *(u16 *)(par->lcd_table+25); 3195 height = par->lcd_height = *(u16 *)(par->lcd_table+27); 3196 panel_type = *(u16 *)(par->lcd_table+29); 3197 if (panel_type & 1) 3198 txtcolour = "colour"; 3199 else 3200 txtcolour = "monochrome"; 3201 if (panel_type & 2) 3202 txtdual = "dual (split) "; 3203 else 3204 txtdual = ""; 3205 tech = (panel_type >> 2) & 63; 3206 switch (tech) { 3207 case 0: 3208 txtmonitor = "passive matrix"; 3209 break; 3210 case 1: 3211 txtmonitor = "active matrix"; 3212 break; 3213 case 2: 3214 txtmonitor = "active addressed STN"; 3215 break; 3216 case 3: 3217 txtmonitor = "EL"; 3218 break; 3219 case 4: 3220 txtmonitor = "plasma"; 3221 break; 3222 default: 3223 txtmonitor = "unknown"; 3224 } 3225 format = *(u32 *)(par->lcd_table+57); 3226 if (tech == 0 || tech == 2) { 3227 switch (format & 7) { 3228 case 0: 3229 txtformat = "12 bit interface"; 3230 break; 3231 case 1: 3232 txtformat = "16 bit interface"; 3233 break; 3234 case 2: 3235 txtformat = "24 bit interface"; 3236 break; 3237 default: 3238 txtformat = "unknown format"; 3239 } 3240 } else { 3241 switch (format & 7) { 3242 case 0: 3243 txtformat = "8 colours"; 3244 break; 3245 case 1: 3246 txtformat = "512 colours"; 3247 break; 3248 case 2: 3249 txtformat = "4096 colours"; 3250 break; 3251 case 4: 3252 txtformat = "262144 colours (LT mode)"; 3253 break; 3254 case 5: 3255 txtformat = "16777216 colours"; 3256 break; 3257 case 6: 3258 txtformat = "262144 colours (FDPI-2 mode)"; 3259 break; 3260 default: 3261 txtformat = "unknown format"; 3262 } 3263 } 3264 PRINTKI("%s%s %s monitor detected: %s\n", 3265 txtdual, txtcolour, txtmonitor, model); 3266 PRINTKI(" id=%d, %dx%d pixels, %s\n", 3267 id, width, height, txtformat); 3268 refresh_rates_buf[0] = 0; 3269 refresh_rates = *(u16 *)(par->lcd_table+62); 3270 m = 1; 3271 f = 0; 3272 for (i = 0; i < 16; i++) { 3273 if (refresh_rates & m) { 3274 if (f == 0) { 3275 sprintf(strbuf, "%d", 3276 lcd_refresh_rates[i]); 3277 f++; 3278 } else { 3279 sprintf(strbuf, ",%d", 3280 lcd_refresh_rates[i]); 3281 } 3282 strcat(refresh_rates_buf, strbuf); 3283 } 3284 m = m << 1; 3285 } 3286 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4; 3287 PRINTKI(" supports refresh rates [%s], default %d Hz\n", 3288 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); 3289 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; 3290 /* 3291 * We now need to determine the crtc parameters for the 3292 * LCD monitor. This is tricky, because they are not stored 3293 * individually in the BIOS. Instead, the BIOS contains a 3294 * table of display modes that work for this monitor. 3295 * 3296 * The idea is that we search for a mode of the same dimensions 3297 * as the dimensions of the LCD monitor. Say our LCD monitor 3298 * is 800x600 pixels, we search for a 800x600 monitor. 3299 * The CRTC parameters we find here are the ones that we need 3300 * to use to simulate other resolutions on the LCD screen. 3301 */ 3302 lcdmodeptr = (u16 *)(par->lcd_table + 64); 3303 while (*lcdmodeptr != 0) { 3304 u32 modeptr; 3305 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start; 3306 modeptr = bios_base + *lcdmodeptr; 3307 3308 mwidth = *((u16 *)(modeptr+0)); 3309 mheight = *((u16 *)(modeptr+2)); 3310 3311 if (mwidth == width && mheight == height) { 3312 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9)); 3313 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511; 3314 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511; 3315 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511; 3316 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7; 3317 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63; 3318 3319 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047; 3320 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047; 3321 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047; 3322 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31; 3323 3324 par->lcd_htotal = (par->lcd_htotal + 1) * 8; 3325 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8; 3326 lcd_hsync_start = (lcd_hsync_start + 1) * 8; 3327 par->lcd_hsync_len = par->lcd_hsync_len * 8; 3328 3329 par->lcd_vtotal++; 3330 par->lcd_vdisp++; 3331 lcd_vsync_start++; 3332 3333 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp; 3334 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp; 3335 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp; 3336 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp; 3337 break; 3338 } 3339 3340 lcdmodeptr++; 3341 } 3342 if (*lcdmodeptr == 0) { 3343 PRINTKE("LCD monitor CRTC parameters not found!!!\n"); 3344 /* To do: Switch to CRT if possible. */ 3345 } else { 3346 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n", 3347 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock, 3348 par->lcd_hdisp, 3349 par->lcd_hdisp + par->lcd_right_margin, 3350 par->lcd_hdisp + par->lcd_right_margin 3351 + par->lcd_hsync_dly + par->lcd_hsync_len, 3352 par->lcd_htotal, 3353 par->lcd_vdisp, 3354 par->lcd_vdisp + par->lcd_lower_margin, 3355 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len, 3356 par->lcd_vtotal); 3357 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n", 3358 par->lcd_pixclock, 3359 par->lcd_hblank_len - (par->lcd_right_margin + 3360 par->lcd_hsync_dly + par->lcd_hsync_len), 3361 par->lcd_hdisp, 3362 par->lcd_right_margin, 3363 par->lcd_hsync_len, 3364 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len), 3365 par->lcd_vdisp, 3366 par->lcd_lower_margin, 3367 par->lcd_vsync_len); 3368 } 3369 } 3370 } 3371 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 3372 3373 static int init_from_bios(struct atyfb_par *par) 3374 { 3375 u32 bios_base, rom_addr; 3376 int ret; 3377 3378 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11); 3379 bios_base = (unsigned long)ioremap(rom_addr, 0x10000); 3380 3381 /* The BIOS starts with 0xaa55. */ 3382 if (*((u16 *)bios_base) == 0xaa55) { 3383 3384 u8 *bios_ptr; 3385 u16 rom_table_offset, freq_table_offset; 3386 PLL_BLOCK_MACH64 pll_block; 3387 3388 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base); 3389 3390 /* check for frequncy table */ 3391 bios_ptr = (u8*)bios_base; 3392 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8)); 3393 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8); 3394 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64)); 3395 3396 PRINTKI("BIOS frequency table:\n"); 3397 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n", 3398 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq, 3399 pll_block.ref_freq, pll_block.ref_divider); 3400 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n", 3401 pll_block.MCLK_pwd, pll_block.MCLK_max_freq, 3402 pll_block.XCLK_max_freq, pll_block.SCLK_freq); 3403 3404 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100; 3405 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100; 3406 par->pll_limits.ref_clk = pll_block.ref_freq/100; 3407 par->pll_limits.ref_div = pll_block.ref_divider; 3408 par->pll_limits.sclk = pll_block.SCLK_freq/100; 3409 par->pll_limits.mclk = pll_block.MCLK_max_freq/100; 3410 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100; 3411 par->pll_limits.xclk = pll_block.XCLK_max_freq/100; 3412 #ifdef CONFIG_FB_ATY_GENERIC_LCD 3413 aty_init_lcd(par, bios_base); 3414 #endif 3415 ret = 0; 3416 } else { 3417 PRINTKE("no BIOS frequency table found, use parameters\n"); 3418 ret = -ENXIO; 3419 } 3420 iounmap((void __iomem *)bios_base); 3421 3422 return ret; 3423 } 3424 #endif /* __i386__ */ 3425 3426 static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, 3427 unsigned long addr) 3428 { 3429 struct atyfb_par *par = info->par; 3430 u16 tmp; 3431 unsigned long raddr; 3432 struct resource *rrp; 3433 int ret = 0; 3434 3435 raddr = addr + 0x7ff000UL; 3436 rrp = &pdev->resource[2]; 3437 if ((rrp->flags & IORESOURCE_MEM) && 3438 request_mem_region(rrp->start, resource_size(rrp), "atyfb")) { 3439 par->aux_start = rrp->start; 3440 par->aux_size = resource_size(rrp); 3441 raddr = rrp->start; 3442 PRINTKI("using auxiliary register aperture\n"); 3443 } 3444 3445 info->fix.mmio_start = raddr; 3446 #if defined(__i386__) || defined(__ia64__) 3447 /* 3448 * By using strong UC we force the MTRR to never have an 3449 * effect on the MMIO region on both non-PAT and PAT systems. 3450 */ 3451 par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000); 3452 #else 3453 par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); 3454 #endif 3455 if (par->ati_regbase == NULL) 3456 return -ENOMEM; 3457 3458 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; 3459 par->ati_regbase += par->aux_start ? 0x400 : 0xc00; 3460 3461 /* 3462 * Enable memory-space accesses using config-space 3463 * command register. 3464 */ 3465 pci_read_config_word(pdev, PCI_COMMAND, &tmp); 3466 if (!(tmp & PCI_COMMAND_MEMORY)) { 3467 tmp |= PCI_COMMAND_MEMORY; 3468 pci_write_config_word(pdev, PCI_COMMAND, tmp); 3469 } 3470 #ifdef __BIG_ENDIAN 3471 /* Use the big-endian aperture */ 3472 addr += 0x800000; 3473 #endif 3474 3475 /* Map in frame buffer */ 3476 info->fix.smem_start = addr; 3477 3478 /* 3479 * The framebuffer is not always 8 MiB, that's just the size of the 3480 * PCI BAR. We temporarily abuse smem_len here to store the size 3481 * of the BAR. aty_init() will later correct it to match the actual 3482 * framebuffer size. 3483 * 3484 * On devices that don't have the auxiliary register aperture, the 3485 * registers are housed at the top end of the framebuffer PCI BAR. 3486 * aty_fudge_framebuffer_len() is used to reduce smem_len to not 3487 * overlap with the registers. 3488 */ 3489 info->fix.smem_len = 0x800000; 3490 3491 aty_fudge_framebuffer_len(info); 3492 3493 info->screen_base = ioremap_wc(info->fix.smem_start, 3494 info->fix.smem_len); 3495 if (info->screen_base == NULL) { 3496 ret = -ENOMEM; 3497 goto atyfb_setup_generic_fail; 3498 } 3499 3500 ret = correct_chipset(par); 3501 if (ret) 3502 goto atyfb_setup_generic_fail; 3503 #ifdef __i386__ 3504 ret = init_from_bios(par); 3505 if (ret) 3506 goto atyfb_setup_generic_fail; 3507 #endif 3508 /* according to ATI, we should use clock 3 for acelerated mode */ 3509 par->clk_wr_offset = 3; 3510 3511 return 0; 3512 3513 atyfb_setup_generic_fail: 3514 iounmap(par->ati_regbase); 3515 par->ati_regbase = NULL; 3516 if (info->screen_base) { 3517 iounmap(info->screen_base); 3518 info->screen_base = NULL; 3519 } 3520 return ret; 3521 } 3522 3523 #endif /* !__sparc__ */ 3524 3525 static int atyfb_pci_probe(struct pci_dev *pdev, 3526 const struct pci_device_id *ent) 3527 { 3528 unsigned long addr, res_start, res_size; 3529 struct fb_info *info; 3530 struct resource *rp; 3531 struct atyfb_par *par; 3532 int rc; 3533 3534 rc = aperture_remove_conflicting_pci_devices(pdev, "atyfb"); 3535 if (rc) 3536 return rc; 3537 3538 /* Enable device in PCI config */ 3539 if (pci_enable_device(pdev)) { 3540 PRINTKE("Cannot enable PCI device\n"); 3541 return -ENXIO; 3542 } 3543 3544 /* Find which resource to use */ 3545 rp = &pdev->resource[0]; 3546 if (rp->flags & IORESOURCE_IO) 3547 rp = &pdev->resource[1]; 3548 addr = rp->start; 3549 if (!addr) 3550 return -ENXIO; 3551 3552 /* Reserve space */ 3553 res_start = rp->start; 3554 res_size = resource_size(rp); 3555 if (!request_mem_region(res_start, res_size, "atyfb")) 3556 return -EBUSY; 3557 3558 /* Allocate framebuffer */ 3559 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); 3560 if (!info) 3561 return -ENOMEM; 3562 3563 par = info->par; 3564 par->bus_type = PCI; 3565 info->fix = atyfb_fix; 3566 info->device = &pdev->dev; 3567 par->pci_id = pdev->device; 3568 par->res_start = res_start; 3569 par->res_size = res_size; 3570 par->irq = pdev->irq; 3571 par->pdev = pdev; 3572 3573 /* Setup "info" structure */ 3574 #ifdef __sparc__ 3575 rc = atyfb_setup_sparc(pdev, info, addr); 3576 #else 3577 rc = atyfb_setup_generic(pdev, info, addr); 3578 #endif 3579 if (rc) 3580 goto err_release_mem; 3581 3582 pci_set_drvdata(pdev, info); 3583 3584 /* Init chip & register framebuffer */ 3585 rc = aty_init(info); 3586 if (rc) 3587 goto err_release_io; 3588 3589 #ifdef __sparc__ 3590 /* 3591 * Add /dev/fb mmap values. 3592 */ 3593 par->mmap_map[0].voff = 0x8000000000000000UL; 3594 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK; 3595 par->mmap_map[0].size = info->fix.smem_len; 3596 par->mmap_map[0].prot_mask = _PAGE_CACHE; 3597 par->mmap_map[0].prot_flag = _PAGE_E; 3598 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len; 3599 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK; 3600 par->mmap_map[1].size = PAGE_SIZE; 3601 par->mmap_map[1].prot_mask = _PAGE_CACHE; 3602 par->mmap_map[1].prot_flag = _PAGE_E; 3603 #endif /* __sparc__ */ 3604 3605 mutex_lock(&reboot_lock); 3606 if (!reboot_info) 3607 reboot_info = info; 3608 mutex_unlock(&reboot_lock); 3609 3610 return 0; 3611 3612 err_release_io: 3613 #ifdef __sparc__ 3614 kfree(par->mmap_map); 3615 #else 3616 if (par->ati_regbase) 3617 iounmap(par->ati_regbase); 3618 if (info->screen_base) 3619 iounmap(info->screen_base); 3620 #endif 3621 err_release_mem: 3622 if (par->aux_start) 3623 release_mem_region(par->aux_start, par->aux_size); 3624 3625 release_mem_region(par->res_start, par->res_size); 3626 framebuffer_release(info); 3627 3628 return rc; 3629 } 3630 3631 #endif /* CONFIG_PCI */ 3632 3633 #ifdef CONFIG_ATARI 3634 3635 static int __init atyfb_atari_probe(void) 3636 { 3637 struct atyfb_par *par; 3638 struct fb_info *info; 3639 int m64_num; 3640 u32 clock_r; 3641 int num_found = 0; 3642 3643 for (m64_num = 0; m64_num < mach64_count; m64_num++) { 3644 if (!phys_vmembase[m64_num] || !phys_size[m64_num] || 3645 !phys_guiregbase[m64_num]) { 3646 PRINTKI("phys_*[%d] parameters not set => " 3647 "returning early. \n", m64_num); 3648 continue; 3649 } 3650 3651 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL); 3652 if (!info) 3653 return -ENOMEM; 3654 3655 par = info->par; 3656 3657 info->fix = atyfb_fix; 3658 3659 par->irq = (unsigned int) -1; /* something invalid */ 3660 3661 /* 3662 * Map the video memory (physical address given) 3663 * to somewhere in the kernel address space. 3664 */ 3665 info->screen_base = ioremap_wc(phys_vmembase[m64_num], 3666 phys_size[m64_num]); 3667 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ 3668 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) + 3669 0xFC00ul; 3670 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */ 3671 3672 aty_st_le32(CLOCK_CNTL, 0x12345678, par); 3673 clock_r = aty_ld_le32(CLOCK_CNTL, par); 3674 3675 switch (clock_r & 0x003F) { 3676 case 0x12: 3677 par->clk_wr_offset = 3; /* */ 3678 break; 3679 case 0x34: 3680 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */ 3681 break; 3682 case 0x16: 3683 par->clk_wr_offset = 1; /* */ 3684 break; 3685 case 0x38: 3686 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */ 3687 break; 3688 } 3689 3690 /* Fake pci_id for correct_chipset() */ 3691 switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) { 3692 case 0x00d7: 3693 par->pci_id = PCI_CHIP_MACH64GX; 3694 break; 3695 case 0x0057: 3696 par->pci_id = PCI_CHIP_MACH64CX; 3697 break; 3698 default: 3699 break; 3700 } 3701 3702 if (correct_chipset(par) || aty_init(info)) { 3703 iounmap(info->screen_base); 3704 iounmap(par->ati_regbase); 3705 framebuffer_release(info); 3706 } else { 3707 num_found++; 3708 } 3709 } 3710 3711 return num_found ? 0 : -ENXIO; 3712 } 3713 3714 #endif /* CONFIG_ATARI */ 3715 3716 #ifdef CONFIG_PCI 3717 3718 static void atyfb_remove(struct fb_info *info) 3719 { 3720 struct atyfb_par *par = (struct atyfb_par *) info->par; 3721 3722 /* restore video mode */ 3723 aty_set_crtc(par, &par->saved_crtc); 3724 par->pll_ops->set_pll(info, &par->saved_pll); 3725 3726 #ifdef CONFIG_FB_ATY_BACKLIGHT 3727 if (M64_HAS(MOBIL_BUS)) 3728 aty_bl_exit(info->bl_dev); 3729 #endif 3730 3731 unregister_framebuffer(info); 3732 3733 arch_phys_wc_del(par->wc_cookie); 3734 3735 #ifndef __sparc__ 3736 if (par->ati_regbase) 3737 iounmap(par->ati_regbase); 3738 if (info->screen_base) 3739 iounmap(info->screen_base); 3740 #ifdef __BIG_ENDIAN 3741 if (info->sprite.addr) 3742 iounmap(info->sprite.addr); 3743 #endif 3744 #endif 3745 #ifdef __sparc__ 3746 kfree(par->mmap_map); 3747 #endif 3748 if (par->aux_start) 3749 release_mem_region(par->aux_start, par->aux_size); 3750 3751 if (par->res_start) 3752 release_mem_region(par->res_start, par->res_size); 3753 3754 framebuffer_release(info); 3755 } 3756 3757 3758 static void atyfb_pci_remove(struct pci_dev *pdev) 3759 { 3760 struct fb_info *info = pci_get_drvdata(pdev); 3761 3762 mutex_lock(&reboot_lock); 3763 if (reboot_info == info) 3764 reboot_info = NULL; 3765 mutex_unlock(&reboot_lock); 3766 3767 atyfb_remove(info); 3768 } 3769 3770 static const struct pci_device_id atyfb_pci_tbl[] = { 3771 #ifdef CONFIG_FB_ATY_GX 3772 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) }, 3773 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) }, 3774 #endif /* CONFIG_FB_ATY_GX */ 3775 3776 #ifdef CONFIG_FB_ATY_CT 3777 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CT) }, 3778 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64ET) }, 3779 3780 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LT) }, 3781 3782 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VT) }, 3783 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GT) }, 3784 3785 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VU) }, 3786 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GU) }, 3787 3788 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LG) }, 3789 3790 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VV) }, 3791 3792 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GV) }, 3793 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GW) }, 3794 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GY) }, 3795 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GZ) }, 3796 3797 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GB) }, 3798 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GD) }, 3799 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GI) }, 3800 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GP) }, 3801 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GQ) }, 3802 3803 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LB) }, 3804 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LD) }, 3805 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LI) }, 3806 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LP) }, 3807 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LQ) }, 3808 3809 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GM) }, 3810 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GN) }, 3811 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GO) }, 3812 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GL) }, 3813 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GR) }, 3814 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GS) }, 3815 3816 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LM) }, 3817 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LN) }, 3818 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LR) }, 3819 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LS) }, 3820 #endif /* CONFIG_FB_ATY_CT */ 3821 { } 3822 }; 3823 3824 MODULE_DEVICE_TABLE(pci, atyfb_pci_tbl); 3825 3826 static struct pci_driver atyfb_driver = { 3827 .name = "atyfb", 3828 .id_table = atyfb_pci_tbl, 3829 .probe = atyfb_pci_probe, 3830 .remove = atyfb_pci_remove, 3831 .driver.pm = &atyfb_pci_pm_ops, 3832 }; 3833 3834 #endif /* CONFIG_PCI */ 3835 3836 #ifndef MODULE 3837 static int __init atyfb_setup(char *options) 3838 { 3839 char *this_opt; 3840 3841 if (!options || !*options) 3842 return 0; 3843 3844 while ((this_opt = strsep(&options, ",")) != NULL) { 3845 if (!strncmp(this_opt, "noaccel", 7)) { 3846 noaccel = true; 3847 } else if (!strncmp(this_opt, "nomtrr", 6)) { 3848 nomtrr = true; 3849 } else if (!strncmp(this_opt, "vram:", 5)) 3850 vram = simple_strtoul(this_opt + 5, NULL, 0); 3851 else if (!strncmp(this_opt, "pll:", 4)) 3852 pll = simple_strtoul(this_opt + 4, NULL, 0); 3853 else if (!strncmp(this_opt, "mclk:", 5)) 3854 mclk = simple_strtoul(this_opt + 5, NULL, 0); 3855 else if (!strncmp(this_opt, "xclk:", 5)) 3856 xclk = simple_strtoul(this_opt+5, NULL, 0); 3857 else if (!strncmp(this_opt, "comp_sync:", 10)) 3858 comp_sync = simple_strtoul(this_opt+10, NULL, 0); 3859 else if (!strncmp(this_opt, "backlight:", 10)) 3860 backlight = simple_strtoul(this_opt+10, NULL, 0); 3861 #ifdef CONFIG_PPC 3862 else if (!strncmp(this_opt, "vmode:", 6)) { 3863 unsigned int vmode = 3864 simple_strtoul(this_opt + 6, NULL, 0); 3865 if (vmode > 0 && vmode <= VMODE_MAX) 3866 default_vmode = vmode; 3867 } else if (!strncmp(this_opt, "cmode:", 6)) { 3868 unsigned int cmode = 3869 simple_strtoul(this_opt + 6, NULL, 0); 3870 switch (cmode) { 3871 case 0: 3872 case 8: 3873 default_cmode = CMODE_8; 3874 break; 3875 case 15: 3876 case 16: 3877 default_cmode = CMODE_16; 3878 break; 3879 case 24: 3880 case 32: 3881 default_cmode = CMODE_32; 3882 break; 3883 } 3884 } 3885 #endif 3886 #ifdef CONFIG_ATARI 3887 /* 3888 * Why do we need this silly Mach64 argument? 3889 * We are already here because of mach64= so its redundant. 3890 */ 3891 else if (MACH_IS_ATARI 3892 && (!strncmp(this_opt, "Mach64:", 7))) { 3893 static unsigned char m64_num; 3894 static char mach64_str[80]; 3895 strscpy(mach64_str, this_opt + 7, sizeof(mach64_str)); 3896 if (!store_video_par(mach64_str, m64_num)) { 3897 m64_num++; 3898 mach64_count = m64_num; 3899 } 3900 } 3901 #endif 3902 else 3903 mode = this_opt; 3904 } 3905 return 0; 3906 } 3907 #endif /* MODULE */ 3908 3909 static int atyfb_reboot_notify(struct notifier_block *nb, 3910 unsigned long code, void *unused) 3911 { 3912 struct atyfb_par *par; 3913 3914 if (code != SYS_RESTART) 3915 return NOTIFY_DONE; 3916 3917 mutex_lock(&reboot_lock); 3918 3919 if (!reboot_info) 3920 goto out; 3921 3922 lock_fb_info(reboot_info); 3923 3924 par = reboot_info->par; 3925 3926 /* 3927 * HP OmniBook 500's BIOS doesn't like the state of the 3928 * hardware after atyfb has been used. Restore the hardware 3929 * to the original state to allow successful reboots. 3930 */ 3931 aty_set_crtc(par, &par->saved_crtc); 3932 par->pll_ops->set_pll(reboot_info, &par->saved_pll); 3933 3934 unlock_fb_info(reboot_info); 3935 out: 3936 mutex_unlock(&reboot_lock); 3937 3938 return NOTIFY_DONE; 3939 } 3940 3941 static struct notifier_block atyfb_reboot_notifier = { 3942 .notifier_call = atyfb_reboot_notify, 3943 }; 3944 3945 static const struct dmi_system_id atyfb_reboot_ids[] __initconst = { 3946 { 3947 .ident = "HP OmniBook 500", 3948 .matches = { 3949 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 3950 DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), 3951 DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), 3952 }, 3953 }, 3954 3955 { } 3956 }; 3957 static bool registered_notifier = false; 3958 3959 static int __init atyfb_init(void) 3960 { 3961 int err1 = 1, err2 = 1; 3962 #ifndef MODULE 3963 char *option = NULL; 3964 #endif 3965 3966 if (fb_modesetting_disabled("atyfb")) 3967 return -ENODEV; 3968 3969 #ifndef MODULE 3970 if (fb_get_options("atyfb", &option)) 3971 return -ENODEV; 3972 atyfb_setup(option); 3973 #endif 3974 3975 #ifdef CONFIG_PCI 3976 err1 = pci_register_driver(&atyfb_driver); 3977 #endif 3978 #ifdef CONFIG_ATARI 3979 err2 = atyfb_atari_probe(); 3980 #endif 3981 3982 if (err1 && err2) 3983 return -ENODEV; 3984 3985 if (dmi_check_system(atyfb_reboot_ids)) { 3986 register_reboot_notifier(&atyfb_reboot_notifier); 3987 registered_notifier = true; 3988 } 3989 3990 return 0; 3991 } 3992 3993 static void __exit atyfb_exit(void) 3994 { 3995 if (registered_notifier) 3996 unregister_reboot_notifier(&atyfb_reboot_notifier); 3997 3998 #ifdef CONFIG_PCI 3999 pci_unregister_driver(&atyfb_driver); 4000 #endif 4001 } 4002 4003 module_init(atyfb_init); 4004 module_exit(atyfb_exit); 4005 4006 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards"); 4007 MODULE_LICENSE("GPL"); 4008 module_param(noaccel, bool, 0); 4009 MODULE_PARM_DESC(noaccel, "bool: disable acceleration"); 4010 module_param(vram, int, 0); 4011 MODULE_PARM_DESC(vram, "int: override size of video ram"); 4012 module_param(pll, int, 0); 4013 MODULE_PARM_DESC(pll, "int: override video clock"); 4014 module_param(mclk, int, 0); 4015 MODULE_PARM_DESC(mclk, "int: override memory clock"); 4016 module_param(xclk, int, 0); 4017 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); 4018 module_param(comp_sync, int, 0); 4019 MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)"); 4020 module_param(mode, charp, 0); 4021 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); 4022 module_param(nomtrr, bool, 0); 4023 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); 4024