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