2 * ATI Frame Buffer Device Driver Core
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)
9 * This driver supports the following ATI graphics chips:
12 * To do: add support for
13 * - ATI Rage128 (from aty128fb.c)
14 * - ATI Radeon (from radeonfb.c)
16 * This driver is partly based on the PowerMac console driver:
18 * Copyright (C) 1996 Paul Mackerras
20 * and on the PowerMac ATI/mach64 display driver:
22 * Copyright (C) 1997 Michael AK Tesch
24 * with work by Jon Howell
26 * Anthony Tong <atong@uiuc.edu>
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.
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
35 * Many thanks to Nitya from ATI devrel for support and patience !
38 /******************************************************************************
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
47 (Anyone with Mac to help with this?)
49 ******************************************************************************/
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>
58 #include <linux/slab.h>
59 #include <linux/vmalloc.h>
60 #include <linux/delay.h>
61 #include <linux/console.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>
71 #include <asm/uaccess.h>
73 #include <video/mach64.h>
78 #include <asm/machdep.h>
80 #include "../macmodes.h"
88 #include <linux/adb.h>
89 #include <linux/pmu.h>
91 #ifdef CONFIG_BOOTX_TEXT
92 #include <asm/btext.h>
94 #ifdef CONFIG_PMAC_BACKLIGHT
95 #include <asm/backlight.h>
107 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
108 /* - must be large enough to catch all GUI-Regs */
109 /* - must be aligned to a PAGE boundary */
110 #define GUI_RESERVE (1 * PAGE_SIZE)
112 /* FIXME: remove the FAIL definition */
113 #define FAIL(msg) do { \
114 if (!(var->activate & FB_ACTIVATE_TEST)) \
115 printk(KERN_CRIT "atyfb: " msg "\n"); \
118 #define FAIL_MAX(msg, x, _max_) do { \
120 if (!(var->activate & FB_ACTIVATE_TEST)) \
121 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
126 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
128 #define DPRINTK(fmt, args...)
131 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
132 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
134 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
135 static const u32 lt_lcd_regs[] = {
142 0, /* EXT_VERT_STRETCH */
147 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
149 if (M64_HAS(LT_LCD_REGS)) {
150 aty_st_le32(lt_lcd_regs[index], val, par);
154 /* write addr byte */
155 temp = aty_ld_le32(LCD_INDEX, par);
156 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
157 /* write the register value */
158 aty_st_le32(LCD_DATA, val, par);
162 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
164 if (M64_HAS(LT_LCD_REGS)) {
165 return aty_ld_le32(lt_lcd_regs[index], par);
169 /* write addr byte */
170 temp = aty_ld_le32(LCD_INDEX, par);
171 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
172 /* read the register value */
173 return aty_ld_le32(LCD_DATA, par);
176 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
178 #ifdef CONFIG_FB_ATY_GENERIC_LCD
182 * Reduce a fraction by factoring out the largest common divider of the
183 * fraction's numerator and denominator.
185 static void ATIReduceRatio(int *Numerator, int *Denominator)
187 int Multiplier, Divider, Remainder;
189 Multiplier = *Numerator;
190 Divider = *Denominator;
192 while ((Remainder = Multiplier % Divider))
194 Multiplier = Divider;
198 *Numerator /= Divider;
199 *Denominator /= Divider;
203 * The Hardware parameters for each card
206 struct pci_mmap_map {
210 unsigned long prot_flag;
211 unsigned long prot_mask;
214 static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
216 .type = FB_TYPE_PACKED_PIXELS,
217 .visual = FB_VISUAL_PSEUDOCOLOR,
223 * Frame buffer device API
226 static int atyfb_open(struct fb_info *info, int user);
227 static int atyfb_release(struct fb_info *info, int user);
228 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
229 static int atyfb_set_par(struct fb_info *info);
230 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
231 u_int transp, struct fb_info *info);
232 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
233 static int atyfb_blank(int blank, struct fb_info *info);
234 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
236 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
238 static int atyfb_sync(struct fb_info *info);
244 static int aty_init(struct fb_info *info);
246 static int store_video_par(char *videopar, unsigned char m64_num);
249 static struct crtc saved_crtc;
250 static union aty_pll saved_pll;
251 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
253 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
254 static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
255 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
256 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
258 static int read_aty_sense(const struct atyfb_par *par);
263 * Interface used by the world
266 static struct fb_var_screeninfo default_var = {
267 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
268 640, 480, 640, 480, 0, 0, 8, 0,
269 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
270 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
271 0, FB_VMODE_NONINTERLACED
274 static struct fb_videomode defmode = {
275 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
276 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
277 0, FB_VMODE_NONINTERLACED
280 static struct fb_ops atyfb_ops = {
281 .owner = THIS_MODULE,
282 .fb_open = atyfb_open,
283 .fb_release = atyfb_release,
284 .fb_check_var = atyfb_check_var,
285 .fb_set_par = atyfb_set_par,
286 .fb_setcolreg = atyfb_setcolreg,
287 .fb_pan_display = atyfb_pan_display,
288 .fb_blank = atyfb_blank,
289 .fb_ioctl = atyfb_ioctl,
290 .fb_fillrect = atyfb_fillrect,
291 .fb_copyarea = atyfb_copyarea,
292 .fb_imageblit = atyfb_imageblit,
294 .fb_mmap = atyfb_mmap,
296 .fb_sync = atyfb_sync,
307 static int comp_sync __devinitdata = -1;
311 static int default_vmode __devinitdata = VMODE_CHOOSE;
312 static int default_cmode __devinitdata = CMODE_CHOOSE;
314 module_param_named(vmode, default_vmode, int, 0);
315 MODULE_PARM_DESC(vmode, "int: video mode for mac");
316 module_param_named(cmode, default_cmode, int, 0);
317 MODULE_PARM_DESC(cmode, "int: color mode for mac");
321 static unsigned int mach64_count __devinitdata = 0;
322 static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };
323 static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };
324 static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
327 /* top -> down is an evolution of mach64 chipset, any corrections? */
328 #define ATI_CHIP_88800GX (M64F_GX)
329 #define ATI_CHIP_88800CX (M64F_GX)
331 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
332 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
334 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
335 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
337 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
338 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
339 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
341 /* FIXME what is this chip? */
342 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
344 /* make sets shorter */
345 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
347 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
348 /*#define ATI_CHIP_264GTDVD ?*/
349 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
351 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
352 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
353 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
355 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
356 #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)
361 int pll, mclk, xclk, ecp_max;
363 } aty_chips[] __devinitdata = {
364 #ifdef CONFIG_FB_ATY_GX
366 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
367 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
368 #endif /* CONFIG_FB_ATY_GX */
370 #ifdef CONFIG_FB_ATY_CT
371 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
372 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
374 /* FIXME what is this chip? */
375 { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
377 { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
378 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
380 { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
381 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
383 { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
385 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
387 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
388 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
389 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
390 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
392 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
393 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
394 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
395 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
396 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
398 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
399 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
400 { 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 },
401 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
402 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
404 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
405 { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
406 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
407 { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
408 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
409 { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
411 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
412 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
413 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
414 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
415 #endif /* CONFIG_FB_ATY_CT */
419 static int __devinit correct_chipset(struct atyfb_par *par)
427 for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
428 if (par->pci_id == aty_chips[i].pci_id)
431 name = aty_chips[i].name;
432 par->pll_limits.pll_max = aty_chips[i].pll;
433 par->pll_limits.mclk = aty_chips[i].mclk;
434 par->pll_limits.xclk = aty_chips[i].xclk;
435 par->pll_limits.ecp_max = aty_chips[i].ecp_max;
436 par->features = aty_chips[i].features;
438 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
439 type = chip_id & CFG_CHIP_TYPE;
440 rev = (chip_id & CFG_CHIP_REV) >> 24;
442 switch(par->pci_id) {
443 #ifdef CONFIG_FB_ATY_GX
444 case PCI_CHIP_MACH64GX:
448 case PCI_CHIP_MACH64CX:
453 #ifdef CONFIG_FB_ATY_CT
454 case PCI_CHIP_MACH64VT:
455 switch (rev & 0x07) {
457 switch (rev & 0xc0) {
459 name = "ATI264VT (A3) (Mach64 VT)";
460 par->pll_limits.pll_max = 170;
461 par->pll_limits.mclk = 67;
462 par->pll_limits.xclk = 67;
463 par->pll_limits.ecp_max = 80;
464 par->features = ATI_CHIP_264VT;
467 name = "ATI264VT2 (A4) (Mach64 VT)";
468 par->pll_limits.pll_max = 200;
469 par->pll_limits.mclk = 67;
470 par->pll_limits.xclk = 67;
471 par->pll_limits.ecp_max = 80;
472 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
477 name = "ATI264VT3 (B1) (Mach64 VT)";
478 par->pll_limits.pll_max = 200;
479 par->pll_limits.mclk = 67;
480 par->pll_limits.xclk = 67;
481 par->pll_limits.ecp_max = 80;
482 par->features = ATI_CHIP_264VTB;
485 name = "ATI264VT3 (B2) (Mach64 VT)";
486 par->pll_limits.pll_max = 200;
487 par->pll_limits.mclk = 67;
488 par->pll_limits.xclk = 67;
489 par->pll_limits.ecp_max = 80;
490 par->features = ATI_CHIP_264VT3;
494 case PCI_CHIP_MACH64GT:
495 switch (rev & 0x07) {
497 name = "3D RAGE II (Mach64 GT)";
498 par->pll_limits.pll_max = 170;
499 par->pll_limits.mclk = 67;
500 par->pll_limits.xclk = 67;
501 par->pll_limits.ecp_max = 80;
502 par->features = ATI_CHIP_264GTB;
505 name = "3D RAGE II+ (Mach64 GT)";
506 par->pll_limits.pll_max = 200;
507 par->pll_limits.mclk = 67;
508 par->pll_limits.xclk = 67;
509 par->pll_limits.ecp_max = 100;
510 par->features = ATI_CHIP_264GTB;
517 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
521 static char ram_dram[] __devinitdata = "DRAM";
522 static char ram_resv[] __devinitdata = "RESV";
523 #ifdef CONFIG_FB_ATY_GX
524 static char ram_vram[] __devinitdata = "VRAM";
525 #endif /* CONFIG_FB_ATY_GX */
526 #ifdef CONFIG_FB_ATY_CT
527 static char ram_edo[] __devinitdata = "EDO";
528 static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
529 static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
530 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
531 static char ram_off[] __devinitdata = "OFF";
532 #endif /* CONFIG_FB_ATY_CT */
535 static u32 pseudo_palette[17];
537 #ifdef CONFIG_FB_ATY_GX
538 static char *aty_gx_ram[8] __devinitdata = {
539 ram_dram, ram_vram, ram_vram, ram_dram,
540 ram_dram, ram_vram, ram_vram, ram_resv
542 #endif /* CONFIG_FB_ATY_GX */
544 #ifdef CONFIG_FB_ATY_CT
545 static char *aty_ct_ram[8] __devinitdata = {
546 ram_off, ram_dram, ram_edo, ram_edo,
547 ram_sdram, ram_sgram, ram_sdram32, ram_resv
549 #endif /* CONFIG_FB_ATY_CT */
551 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par)
553 u32 pixclock = var->pixclock;
554 #ifdef CONFIG_FB_ATY_GENERIC_LCD
556 par->pll.ct.xres = 0;
557 if (par->lcd_table != 0) {
558 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
559 if(lcd_on_off & LCD_ON) {
560 par->pll.ct.xres = var->xres;
561 pixclock = par->lcd_pixclock;
568 #if defined(CONFIG_PPC)
571 * Apple monitor sense
574 static int __devinit read_aty_sense(const struct atyfb_par *par)
578 aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
580 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
582 i = aty_ld_le32(GP_IO, par); /* get primary sense value */
583 sense = ((i & 0x3000) >> 3) | (i & 0x100);
585 /* drive each sense line low in turn and collect the other 2 */
586 aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
588 i = aty_ld_le32(GP_IO, par);
589 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
590 aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
593 aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
595 i = aty_ld_le32(GP_IO, par);
596 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
597 aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
600 aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
602 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
603 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
607 #endif /* defined(CONFIG_PPC) */
609 /* ------------------------------------------------------------------------- */
615 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
617 #ifdef CONFIG_FB_ATY_GENERIC_LCD
618 if (par->lcd_table != 0) {
619 if(!M64_HAS(LT_LCD_REGS)) {
620 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
621 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
623 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
624 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
627 /* switch to non shadow registers */
628 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
629 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
631 /* save stretching */
632 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
633 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
634 if (!M64_HAS(LT_LCD_REGS))
635 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
638 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
639 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
640 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
641 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
642 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
643 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
644 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
646 #ifdef CONFIG_FB_ATY_GENERIC_LCD
647 if (par->lcd_table != 0) {
648 /* switch to shadow registers */
649 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
650 SHADOW_EN | SHADOW_RW_EN, par);
652 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
653 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
654 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
655 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
657 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
659 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
662 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
664 #ifdef CONFIG_FB_ATY_GENERIC_LCD
665 if (par->lcd_table != 0) {
667 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
669 /* update non-shadow registers first */
670 aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
671 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
672 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
674 /* temporarily disable stretching */
675 aty_st_lcd(HORZ_STRETCHING,
676 crtc->horz_stretching &
677 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
678 aty_st_lcd(VERT_STRETCHING,
679 crtc->vert_stretching &
680 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
681 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
685 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
687 DPRINTK("setting up CRTC\n");
688 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
689 ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
690 (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
691 (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
693 DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
694 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
695 DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
696 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
697 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
698 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
699 DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
701 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
702 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
703 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
704 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
705 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
706 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
708 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
711 if (par->accel_flags & FB_ACCELF_TEXT)
712 aty_init_engine(par, info);
714 #ifdef CONFIG_FB_ATY_GENERIC_LCD
715 /* after setting the CRTC registers we should set the LCD registers. */
716 if (par->lcd_table != 0) {
717 /* switch to shadow registers */
718 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
719 (SHADOW_EN | SHADOW_RW_EN), par);
721 DPRINTK("set shadow CRT to %ix%i %c%c\n",
722 ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
723 (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
725 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
726 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
727 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
728 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
730 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
731 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
732 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
733 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
735 /* restore CRTC selection & shadow state and enable stretching */
736 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
737 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
738 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
739 if(!M64_HAS(LT_LCD_REGS))
740 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
742 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
743 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
744 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
745 if(!M64_HAS(LT_LCD_REGS)) {
746 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
747 aty_ld_le32(LCD_INDEX, par);
748 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
751 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
754 static int aty_var_to_crtc(const struct fb_info *info,
755 const struct fb_var_screeninfo *var, struct crtc *crtc)
757 struct atyfb_par *par = (struct atyfb_par *) info->par;
758 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
759 u32 sync, vmode, vdisplay;
760 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
761 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
762 u32 pix_width, dp_pix_width, dp_chain_mask;
767 vxres = var->xres_virtual;
768 vyres = var->yres_virtual;
769 xoffset = var->xoffset;
770 yoffset = var->yoffset;
771 bpp = var->bits_per_pixel;
773 bpp = (var->green.length == 5) ? 15 : 16;
777 /* convert (and round up) and validate */
778 if (vxres < xres + xoffset)
779 vxres = xres + xoffset;
782 if (vyres < yres + yoffset)
783 vyres = yres + yoffset;
788 pix_width = CRTC_PIX_WIDTH_8BPP;
790 HOST_8BPP | SRC_8BPP | DST_8BPP |
791 BYTE_ORDER_LSB_TO_MSB;
792 dp_chain_mask = DP_CHAIN_8BPP;
793 } else if (bpp <= 15) {
795 pix_width = CRTC_PIX_WIDTH_15BPP;
796 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
797 BYTE_ORDER_LSB_TO_MSB;
798 dp_chain_mask = DP_CHAIN_15BPP;
799 } else if (bpp <= 16) {
801 pix_width = CRTC_PIX_WIDTH_16BPP;
802 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
803 BYTE_ORDER_LSB_TO_MSB;
804 dp_chain_mask = DP_CHAIN_16BPP;
805 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
807 pix_width = CRTC_PIX_WIDTH_24BPP;
809 HOST_8BPP | SRC_8BPP | DST_8BPP |
810 BYTE_ORDER_LSB_TO_MSB;
811 dp_chain_mask = DP_CHAIN_24BPP;
812 } else if (bpp <= 32) {
814 pix_width = CRTC_PIX_WIDTH_32BPP;
815 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
816 BYTE_ORDER_LSB_TO_MSB;
817 dp_chain_mask = DP_CHAIN_32BPP;
821 if (vxres * vyres * bpp / 8 > info->fix.smem_len)
822 FAIL("not enough video RAM");
824 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
825 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
827 if((xres > 1600) || (yres > 1200)) {
828 FAIL("MACH64 chips are designed for max 1600x1200\n"
829 "select anoter resolution.");
831 h_sync_strt = h_disp + var->right_margin;
832 h_sync_end = h_sync_strt + var->hsync_len;
833 h_sync_dly = var->right_margin & 7;
834 h_total = h_sync_end + h_sync_dly + var->left_margin;
836 v_sync_strt = v_disp + var->lower_margin;
837 v_sync_end = v_sync_strt + var->vsync_len;
838 v_total = v_sync_end + var->upper_margin;
840 #ifdef CONFIG_FB_ATY_GENERIC_LCD
841 if (par->lcd_table != 0) {
842 if(!M64_HAS(LT_LCD_REGS)) {
843 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
844 crtc->lcd_index = lcd_index &
845 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
846 aty_st_le32(LCD_INDEX, lcd_index, par);
849 if (!M64_HAS(MOBIL_BUS))
850 crtc->lcd_index |= CRTC2_DISPLAY_DIS;
852 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
853 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
855 crtc->lcd_gen_cntl &=
856 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
857 /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
858 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
859 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
861 if((crtc->lcd_gen_cntl & LCD_ON) &&
862 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
863 /* We cannot display the mode on the LCD. If the CRT is enabled
864 we can turn off the LCD.
865 If the CRT is off, it isn't a good idea to switch it on; we don't
866 know if one is connected. So it's better to fail then.
868 if (crtc->lcd_gen_cntl & CRT_ON) {
869 if (!(var->activate & FB_ACTIVATE_TEST))
870 PRINTKI("Disable LCD panel, because video mode does not fit.\n");
871 crtc->lcd_gen_cntl &= ~LCD_ON;
872 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
874 if (!(var->activate & FB_ACTIVATE_TEST))
875 PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
881 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
883 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
884 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
885 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */
887 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
889 /* This is horror! When we simulate, say 640x480 on an 800x600
890 LCD monitor, the CRTC should be programmed 800x600 values for
891 the non visible part, but 640x480 for the visible part.
892 This code has been tested on a laptop with it's 1400x1050 LCD
893 monitor and a conventional monitor both switched on.
894 Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
895 works with little glitches also with DOUBLESCAN modes
897 if (yres < par->lcd_height) {
898 VScan = par->lcd_height / yres;
901 vmode |= FB_VMODE_DOUBLE;
905 h_sync_strt = h_disp + par->lcd_right_margin;
906 h_sync_end = h_sync_strt + par->lcd_hsync_len;
907 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
908 h_total = h_disp + par->lcd_hblank_len;
910 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
911 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
912 v_total = v_disp + par->lcd_vblank_len / VScan;
914 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
916 h_disp = (h_disp >> 3) - 1;
917 h_sync_strt = (h_sync_strt >> 3) - 1;
918 h_sync_end = (h_sync_end >> 3) - 1;
919 h_total = (h_total >> 3) - 1;
920 h_sync_wid = h_sync_end - h_sync_strt;
922 FAIL_MAX("h_disp too large", h_disp, 0xff);
923 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
924 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
925 if(h_sync_wid > 0x1f)
927 FAIL_MAX("h_total too large", h_total, 0x1ff);
929 if (vmode & FB_VMODE_DOUBLE) {
937 #ifdef CONFIG_FB_ATY_GENERIC_LCD
938 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
939 vdisplay = par->lcd_height;
946 v_sync_wid = v_sync_end - v_sync_strt;
948 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
949 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
950 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
951 if(v_sync_wid > 0x1f)
953 FAIL_MAX("v_total too large", v_total, 0x7ff);
955 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
960 crtc->xoffset = xoffset;
961 crtc->yoffset = yoffset;
963 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
964 crtc->vline_crnt_vline = 0;
966 crtc->h_tot_disp = h_total | (h_disp<<16);
967 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
968 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21);
969 crtc->v_tot_disp = v_total | (v_disp<<16);
970 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
972 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
973 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
974 crtc->gen_cntl |= CRTC_VGA_LINEAR;
976 /* Enable doublescan mode if requested */
977 if (vmode & FB_VMODE_DOUBLE)
978 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
979 /* Enable interlaced mode if requested */
980 if (vmode & FB_VMODE_INTERLACED)
981 crtc->gen_cntl |= CRTC_INTERLACE_EN;
982 #ifdef CONFIG_FB_ATY_GENERIC_LCD
983 if (par->lcd_table != 0) {
985 if(vmode & FB_VMODE_DOUBLE)
987 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
988 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
989 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
990 USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
991 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
993 /* MOBILITY M1 tested, FIXME: LT */
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);
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) {
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.
1014 int HDisplay = xres & ~7;
1015 int nStretch = par->lcd_width / HDisplay;
1016 int Remainder = par->lcd_width % HDisplay;
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;
1024 ATIReduceRatio(&Numerator, &Denominator);
1026 BestRemainder = (Numerator * 16) / Denominator;
1027 while (--Index >= 0) {
1028 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1030 if (Remainder < BestRemainder) {
1031 horz_stretch_loop = Index;
1032 if (!(BestRemainder = Remainder))
1037 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1038 int horz_stretch_ratio = 0, Accumulator = 0;
1039 int reuse_previous = 1;
1041 Index = StretchLoops[horz_stretch_loop];
1043 while (--Index >= 0) {
1044 if (Accumulator > 0)
1045 horz_stretch_ratio |= reuse_previous;
1047 Accumulator += Denominator;
1048 Accumulator -= Numerator;
1049 reuse_previous <<= 1;
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) */
1059 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1060 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
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));
1068 if (!M64_HAS(LT_LCD_REGS) &&
1069 xres <= (M64_HAS(MOBIL_BUS)?1024:800))
1070 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1073 * Don't use vertical blending if the mode is too wide or not
1074 * vertically stretched.
1076 crtc->vert_stretching = 0;
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;
1084 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1086 if (M64_HAS(MAGIC_FIFO)) {
1087 /* FIXME: display FIFO low watermark values */
1088 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
1090 crtc->dp_pix_width = dp_pix_width;
1091 crtc->dp_chain_mask = dp_chain_mask;
1096 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var)
1098 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1099 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
1101 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1103 u32 double_scan, interlace;
1106 h_total = crtc->h_tot_disp & 0x1ff;
1107 h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1108 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1109 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1110 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1111 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1112 v_total = crtc->v_tot_disp & 0x7ff;
1113 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1114 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1115 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1116 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1117 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1118 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1119 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1120 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1123 xres = (h_disp + 1) * 8;
1125 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1126 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1127 hslen = h_sync_wid * 8;
1128 upper = v_total - v_sync_strt - v_sync_wid;
1129 lower = v_sync_strt - v_disp;
1131 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1132 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1133 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1135 switch (pix_width) {
1137 case CRTC_PIX_WIDTH_4BPP:
1139 var->red.offset = 0;
1140 var->red.length = 8;
1141 var->green.offset = 0;
1142 var->green.length = 8;
1143 var->blue.offset = 0;
1144 var->blue.length = 8;
1145 var->transp.offset = 0;
1146 var->transp.length = 0;
1149 case CRTC_PIX_WIDTH_8BPP:
1151 var->red.offset = 0;
1152 var->red.length = 8;
1153 var->green.offset = 0;
1154 var->green.length = 8;
1155 var->blue.offset = 0;
1156 var->blue.length = 8;
1157 var->transp.offset = 0;
1158 var->transp.length = 0;
1160 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
1162 var->red.offset = 10;
1163 var->red.length = 5;
1164 var->green.offset = 5;
1165 var->green.length = 5;
1166 var->blue.offset = 0;
1167 var->blue.length = 5;
1168 var->transp.offset = 0;
1169 var->transp.length = 0;
1171 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
1173 var->red.offset = 11;
1174 var->red.length = 5;
1175 var->green.offset = 5;
1176 var->green.length = 6;
1177 var->blue.offset = 0;
1178 var->blue.length = 5;
1179 var->transp.offset = 0;
1180 var->transp.length = 0;
1182 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
1184 var->red.offset = 16;
1185 var->red.length = 8;
1186 var->green.offset = 8;
1187 var->green.length = 8;
1188 var->blue.offset = 0;
1189 var->blue.length = 8;
1190 var->transp.offset = 0;
1191 var->transp.length = 0;
1193 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
1195 var->red.offset = 16;
1196 var->red.length = 8;
1197 var->green.offset = 8;
1198 var->green.length = 8;
1199 var->blue.offset = 0;
1200 var->blue.length = 8;
1201 var->transp.offset = 24;
1202 var->transp.length = 8;
1205 PRINTKE("Invalid pixel width\n");
1212 var->xres_virtual = crtc->vxres;
1213 var->yres_virtual = crtc->vyres;
1214 var->bits_per_pixel = bpp;
1215 var->left_margin = left;
1216 var->right_margin = right;
1217 var->upper_margin = upper;
1218 var->lower_margin = lower;
1219 var->hsync_len = hslen;
1220 var->vsync_len = vslen;
1222 var->vmode = FB_VMODE_NONINTERLACED;
1223 /* In double scan mode, the vertical parameters are doubled, so we need to
1224 half them to get the right values.
1225 In interlaced mode the values are already correct, so no correction is
1229 var->vmode = FB_VMODE_INTERLACED;
1232 var->vmode = FB_VMODE_DOUBLE;
1234 var->upper_margin>>=1;
1235 var->lower_margin>>=1;
1242 /* ------------------------------------------------------------------------- */
1244 static int atyfb_set_par(struct fb_info *info)
1246 struct atyfb_par *par = (struct atyfb_par *) info->par;
1247 struct fb_var_screeninfo *var = &info->var;
1251 struct fb_var_screeninfo debug;
1257 if ((err = aty_var_to_crtc(info, var, &par->crtc)))
1260 pixclock = atyfb_get_pixclock(var, par);
1262 if (pixclock == 0) {
1263 PRINTKE("Invalid pixclock\n");
1266 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
1270 par->accel_flags = var->accel_flags; /* hack */
1272 if (var->accel_flags) {
1273 info->fbops->fb_sync = atyfb_sync;
1274 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1276 info->fbops->fb_sync = NULL;
1277 info->flags |= FBINFO_HWACCEL_DISABLED;
1280 if (par->blitter_may_be_busy)
1283 aty_set_crtc(par, &par->crtc);
1284 par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
1285 par->pll_ops->set_pll(info, &par->pll);
1288 if(par->pll_ops && par->pll_ops->pll_to_var)
1289 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll));
1293 if(0 == pixclock_in_ps) {
1294 PRINTKE("ALERT ops->pll_to_var get 0\n");
1295 pixclock_in_ps = pixclock;
1298 memset(&debug, 0, sizeof(debug));
1299 if(!aty_crtc_to_var(&(par->crtc), &debug)) {
1300 u32 hSync, vRefresh;
1301 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1302 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1304 h_disp = debug.xres;
1305 h_sync_strt = h_disp + debug.right_margin;
1306 h_sync_end = h_sync_strt + debug.hsync_len;
1307 h_total = h_sync_end + debug.left_margin;
1308 v_disp = debug.yres;
1309 v_sync_strt = v_disp + debug.lower_margin;
1310 v_sync_end = v_sync_strt + debug.vsync_len;
1311 v_total = v_sync_end + debug.upper_margin;
1313 hSync = 1000000000 / (pixclock_in_ps * h_total);
1314 vRefresh = (hSync * 1000) / v_total;
1315 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1317 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1320 DPRINTK("atyfb_set_par\n");
1321 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
1322 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
1323 var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
1324 DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps);
1325 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1326 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1327 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1328 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1329 h_disp, h_sync_strt, h_sync_end, h_total,
1330 v_disp, v_sync_strt, v_sync_end, v_total);
1331 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
1333 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1334 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1338 if (!M64_HAS(INTEGRATED)) {
1339 /* Don't forget MEM_CNTL */
1340 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1341 switch (var->bits_per_pixel) {
1352 aty_st_le32(MEM_CNTL, tmp, par);
1354 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1355 if (!M64_HAS(MAGIC_POSTDIV))
1356 tmp |= par->mem_refresh_rate << 20;
1357 switch (var->bits_per_pixel) {
1369 if (M64_HAS(CT_BUS)) {
1370 aty_st_le32(DAC_CNTL, 0x87010184, par);
1371 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1372 } else if (M64_HAS(VT_BUS)) {
1373 aty_st_le32(DAC_CNTL, 0x87010184, par);
1374 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1375 } else if (M64_HAS(MOBIL_BUS)) {
1376 aty_st_le32(DAC_CNTL, 0x80010102, par);
1377 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1380 aty_st_le32(DAC_CNTL, 0x86010102, par);
1381 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1382 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1384 aty_st_le32(MEM_CNTL, tmp, par);
1386 aty_st_8(DAC_MASK, 0xff, par);
1388 info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
1389 info->fix.visual = var->bits_per_pixel <= 8 ?
1390 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1392 /* Initialize the graphics engine */
1393 if (par->accel_flags & FB_ACCELF_TEXT)
1394 aty_init_engine(par, info);
1396 #ifdef CONFIG_BOOTX_TEXT
1397 btext_update_display(info->fix.smem_start,
1398 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1399 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1400 var->bits_per_pixel,
1401 par->crtc.vxres * var->bits_per_pixel / 8);
1402 #endif /* CONFIG_BOOTX_TEXT */
1404 /* switch to accelerator mode */
1405 if (!(par->crtc.gen_cntl & CRTC_EXT_DISP_EN))
1406 aty_st_le32(CRTC_GEN_CNTL, par->crtc.gen_cntl | CRTC_EXT_DISP_EN, par);
1410 /* dump non shadow CRTC, pll, LCD registers */
1413 /* CRTC registers */
1415 printk("debug atyfb: Mach64 non-shadow register values:");
1416 for (i = 0; i < 256; i = i+4) {
1417 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
1418 printk(" %08X", aty_ld_le32(i, par));
1422 #ifdef CONFIG_FB_ATY_CT
1425 printk("debug atyfb: Mach64 PLL register values:");
1426 for (i = 0; i < 64; i++) {
1427 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1428 if(i%4 == 0) printk(" ");
1429 printk("%02X", aty_ld_pll_ct(i, par));
1432 #endif /* CONFIG_FB_ATY_CT */
1434 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1435 if (par->lcd_table != 0) {
1438 printk("debug atyfb: LCD register values:");
1439 if(M64_HAS(LT_LCD_REGS)) {
1440 for(i = 0; i <= POWER_MANAGEMENT; i++) {
1441 if(i == EXT_VERT_STRETCH)
1443 printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
1444 printk(" %08X", aty_ld_lcd(i, par));
1448 for (i = 0; i < 64; i++) {
1449 if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1450 printk(" %08X", aty_ld_lcd(i, par));
1455 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1461 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1463 struct atyfb_par *par = (struct atyfb_par *) info->par;
1469 memcpy(&pll, &(par->pll), sizeof(pll));
1471 if((err = aty_var_to_crtc(info, var, &crtc)))
1474 pixclock = atyfb_get_pixclock(var, par);
1476 if (pixclock == 0) {
1477 if (!(var->activate & FB_ACTIVATE_TEST))
1478 PRINTKE("Invalid pixclock\n");
1481 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
1485 if (var->accel_flags & FB_ACCELF_TEXT)
1486 info->var.accel_flags = FB_ACCELF_TEXT;
1488 info->var.accel_flags = 0;
1490 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
1491 if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
1494 aty_crtc_to_var(&crtc, var);
1495 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1499 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1501 u32 xoffset = info->var.xoffset;
1502 u32 yoffset = info->var.yoffset;
1503 u32 vxres = par->crtc.vxres;
1504 u32 bpp = info->var.bits_per_pixel;
1506 par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
1511 * Open/Release the frame buffer device
1514 static int atyfb_open(struct fb_info *info, int user)
1516 struct atyfb_par *par = (struct atyfb_par *) info->par;
1527 static irqreturn_t aty_irq(int irq, void *dev_id)
1529 struct atyfb_par *par = dev_id;
1533 spin_lock(&par->int_lock);
1535 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1537 if (int_cntl & CRTC_VBLANK_INT) {
1538 /* clear interrupt */
1539 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
1540 par->vblank.count++;
1541 if (par->vblank.pan_display) {
1542 par->vblank.pan_display = 0;
1543 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1545 wake_up_interruptible(&par->vblank.wait);
1549 spin_unlock(&par->int_lock);
1551 return IRQ_RETVAL(handled);
1554 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1558 if (!test_and_set_bit(0, &par->irq_flags)) {
1559 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1560 clear_bit(0, &par->irq_flags);
1563 spin_lock_irq(&par->int_lock);
1564 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1565 /* clear interrupt */
1566 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1567 /* enable interrupt */
1568 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1569 spin_unlock_irq(&par->int_lock);
1570 } else if (reenable) {
1571 spin_lock_irq(&par->int_lock);
1572 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1573 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1574 printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
1575 /* re-enable interrupt */
1576 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
1578 spin_unlock_irq(&par->int_lock);
1584 static int aty_disable_irq(struct atyfb_par *par)
1588 if (test_and_clear_bit(0, &par->irq_flags)) {
1589 if (par->vblank.pan_display) {
1590 par->vblank.pan_display = 0;
1591 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1593 spin_lock_irq(&par->int_lock);
1594 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1595 /* disable interrupt */
1596 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
1597 spin_unlock_irq(&par->int_lock);
1598 free_irq(par->irq, par);
1604 static int atyfb_release(struct fb_info *info, int user)
1606 struct atyfb_par *par = (struct atyfb_par *) info->par;
1613 int was_mmaped = par->mmaped;
1618 struct fb_var_screeninfo var;
1620 /* Now reset the default display config, we have no
1621 * idea what the program(s) which mmap'd the chip did
1622 * to the configuration, nor whether it restored it
1627 var.accel_flags &= ~FB_ACCELF_TEXT;
1629 var.accel_flags |= FB_ACCELF_TEXT;
1630 if (var.yres == var.yres_virtual) {
1631 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1632 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
1633 if (var.yres_virtual < var.yres)
1634 var.yres_virtual = var.yres;
1638 aty_disable_irq(par);
1645 * Pan or Wrap the Display
1647 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1650 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1652 struct atyfb_par *par = (struct atyfb_par *) info->par;
1653 u32 xres, yres, xoffset, yoffset;
1655 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1656 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1657 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1659 xoffset = (var->xoffset + 7) & ~7;
1660 yoffset = var->yoffset;
1661 if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres)
1663 info->var.xoffset = xoffset;
1664 info->var.yoffset = yoffset;
1668 set_off_pitch(par, info);
1669 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1670 par->vblank.pan_display = 1;
1672 par->vblank.pan_display = 0;
1673 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1679 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1681 struct aty_interrupt *vbl;
1693 ret = aty_enable_irq(par, 0);
1698 ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
1703 aty_enable_irq(par, 1);
1712 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
1713 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
1719 u8 mclk_post_div; /* 1,2,3,4,8 */
1720 u8 mclk_fb_mult; /* 2 or 4 */
1721 u8 xclk_post_div; /* 1,2,3,4,8 */
1723 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
1724 u32 dsp_xclks_per_row; /* 0-16383 */
1725 u32 dsp_loop_latency; /* 0-15 */
1726 u32 dsp_precision; /* 0-7 */
1727 u32 dsp_on; /* 0-2047 */
1728 u32 dsp_off; /* 0-2047 */
1731 #define ATYIO_FEATR 0x41545902 /* ATY\02 */
1732 #define ATYIO_FEATW 0x41545903 /* ATY\03 */
1735 #ifndef FBIO_WAITFORVSYNC
1736 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
1739 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1741 struct atyfb_par *par = (struct atyfb_par *) info->par;
1743 struct fbtype fbtyp;
1749 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1750 fbtyp.fb_width = par->crtc.vxres;
1751 fbtyp.fb_height = par->crtc.vyres;
1752 fbtyp.fb_depth = info->var.bits_per_pixel;
1753 fbtyp.fb_cmsize = info->cmap.len;
1754 fbtyp.fb_size = info->fix.smem_len;
1755 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp)))
1758 #endif /* __sparc__ */
1760 case FBIO_WAITFORVSYNC:
1764 if (get_user(crtc, (__u32 __user *) arg))
1767 return aty_waitforvblank(par, crtc);
1771 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1773 if (M64_HAS(INTEGRATED)) {
1775 union aty_pll *pll = &(par->pll);
1776 u32 dsp_config = pll->ct.dsp_config;
1777 u32 dsp_on_off = pll->ct.dsp_on_off;
1778 clk.ref_clk_per = par->ref_clk_per;
1779 clk.pll_ref_div = pll->ct.pll_ref_div;
1780 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1781 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1782 clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1783 clk.xclk_post_div = pll->ct.xclk_post_div_real;
1784 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1785 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1786 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1787 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1788 clk.dsp_precision = (dsp_config >> 20) & 7;
1789 clk.dsp_off = dsp_on_off & 0x7ff;
1790 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1791 if (copy_to_user((struct atyclk __user *) arg, &clk,
1798 if (M64_HAS(INTEGRATED)) {
1800 union aty_pll *pll = &(par->pll);
1801 if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk)))
1803 par->ref_clk_per = clk.ref_clk_per;
1804 pll->ct.pll_ref_div = clk.pll_ref_div;
1805 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1806 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1807 pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1808 pll->ct.xclk_post_div_real = clk.xclk_post_div;
1809 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1810 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1811 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1812 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20);
1813 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16);
1814 /*aty_calc_pll_ct(info, &pll->ct);*/
1815 aty_set_pll_ct(info, pll);
1820 if (get_user(par->features, (u32 __user *) arg))
1824 if (put_user(par->features, (u32 __user *) arg))
1827 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1834 static int atyfb_sync(struct fb_info *info)
1836 struct atyfb_par *par = (struct atyfb_par *) info->par;
1838 if (par->blitter_may_be_busy)
1844 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1846 struct atyfb_par *par = (struct atyfb_par *) info->par;
1847 unsigned int size, page, map_size = 0;
1848 unsigned long map_offset = 0;
1855 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1858 off = vma->vm_pgoff << PAGE_SHIFT;
1859 size = vma->vm_end - vma->vm_start;
1861 /* To stop the swapper from even considering these pages. */
1862 vma->vm_flags |= (VM_IO | VM_RESERVED);
1864 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1865 ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1866 off += 0x8000000000000000UL;
1868 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
1870 /* Each page, see which map applies */
1871 for (page = 0; page < size;) {
1873 for (i = 0; par->mmap_map[i].size; i++) {
1874 unsigned long start = par->mmap_map[i].voff;
1875 unsigned long end = start + par->mmap_map[i].size;
1876 unsigned long offset = off + page;
1883 map_size = par->mmap_map[i].size - (offset - start);
1885 par->mmap_map[i].poff + (offset - start);
1892 if (page + map_size > size)
1893 map_size = size - page;
1895 pgprot_val(vma->vm_page_prot) &=
1896 ~(par->mmap_map[i].prot_mask);
1897 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1899 if (remap_pfn_range(vma, vma->vm_start + page,
1900 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1921 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1925 for (i = 0; i < 256; i++) {
1926 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1927 if (M64_HAS(EXTRA_BRIGHT))
1929 aty_st_8(DAC_CNTL, tmp, par);
1930 aty_st_8(DAC_MASK, 0xff, par);
1932 aty_st_8(DAC_R_INDEX, i, par);
1933 atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
1934 atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
1935 atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
1936 aty_st_8(DAC_W_INDEX, i, par);
1937 aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
1938 aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
1939 aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
1943 static void atyfb_palette(int enter)
1945 struct atyfb_par *par;
1946 struct fb_info *info;
1949 for (i = 0; i < FB_MAX; i++) {
1950 info = registered_fb[i];
1951 if (info && info->fbops == &atyfb_ops) {
1952 par = (struct atyfb_par *) info->par;
1954 atyfb_save_palette(par, enter);
1956 atyfb_save.yoffset = info->var.yoffset;
1957 info->var.yoffset = 0;
1958 set_off_pitch(par, info);
1960 info->var.yoffset = atyfb_save.yoffset;
1961 set_off_pitch(par, info);
1963 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1968 #endif /* __sparc__ */
1972 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1974 /* Power management routines. Those are used for PowerBook sleep.
1976 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1981 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1982 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1983 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1984 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1990 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1991 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1993 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1995 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1996 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1999 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2001 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2003 if ((--timeout) == 0)
2005 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
2009 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2010 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2013 pm |= (PWR_BLON | AUTO_PWR_UP);
2014 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2015 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2018 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2020 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2022 if ((--timeout) == 0)
2024 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2028 return timeout ? 0 : -EIO;
2031 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2033 struct fb_info *info = pci_get_drvdata(pdev);
2034 struct atyfb_par *par = (struct atyfb_par *) info->par;
2036 #ifndef CONFIG_PPC_PMAC
2037 /* HACK ALERT ! Once I find a proper way to say to each driver
2038 * individually what will happen with it's PCI slot, I'll change
2039 * that. On laptops, the AGP slot is just unclocked, so D2 is
2040 * expected, while on desktops, the card is powered off
2043 #endif /* CONFIG_PPC_PMAC */
2045 if (state.event == pdev->dev.power.power_state.event)
2048 acquire_console_sem();
2050 fb_set_suspend(info, 1);
2052 /* Idle & reset engine */
2054 aty_reset_engine(par);
2056 /* Blank display and LCD */
2057 atyfb_blank(FB_BLANK_POWERDOWN, info);
2060 par->lock_blank = 1;
2062 /* Set chip to "suspend" mode */
2063 if (aty_power_mgmt(1, par)) {
2065 par->lock_blank = 0;
2066 atyfb_blank(FB_BLANK_UNBLANK, info);
2067 fb_set_suspend(info, 0);
2068 release_console_sem();
2072 release_console_sem();
2074 pdev->dev.power.power_state = state;
2079 static int atyfb_pci_resume(struct pci_dev *pdev)
2081 struct fb_info *info = pci_get_drvdata(pdev);
2082 struct atyfb_par *par = (struct atyfb_par *) info->par;
2084 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2087 acquire_console_sem();
2089 if (pdev->dev.power.power_state.event == 2)
2090 aty_power_mgmt(0, par);
2093 /* Restore display */
2094 atyfb_set_par(info);
2097 fb_set_suspend(info, 0);
2100 par->lock_blank = 0;
2101 atyfb_blank(FB_BLANK_UNBLANK, info);
2103 release_console_sem();
2105 pdev->dev.power.power_state = PMSG_ON;
2110 #endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */
2113 #ifdef CONFIG_FB_ATY_BACKLIGHT
2114 #define MAX_LEVEL 0xFF
2116 static struct backlight_properties aty_bl_data;
2118 /* Call with fb_info->bl_mutex held */
2119 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2121 struct fb_info *info = pci_get_drvdata(par->pdev);
2124 /* Get and convert the value */
2125 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2129 else if (atylevel > MAX_LEVEL)
2130 atylevel = MAX_LEVEL;
2135 /* Call with fb_info->bl_mutex held */
2136 static int __aty_bl_update_status(struct backlight_device *bd)
2138 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2139 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2142 if (bd->props->power != FB_BLANK_UNBLANK ||
2143 bd->props->fb_blank != FB_BLANK_UNBLANK)
2146 level = bd->props->brightness;
2148 reg |= (BLMOD_EN | BIASMOD_EN);
2150 reg &= ~BIAS_MOD_LEVEL_MASK;
2151 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2153 reg &= ~BIAS_MOD_LEVEL_MASK;
2154 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2156 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2161 static int aty_bl_update_status(struct backlight_device *bd)
2163 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2164 struct fb_info *info = pci_get_drvdata(par->pdev);
2167 mutex_lock(&info->bl_mutex);
2168 ret = __aty_bl_update_status(bd);
2169 mutex_unlock(&info->bl_mutex);
2174 static int aty_bl_get_brightness(struct backlight_device *bd)
2176 return bd->props->brightness;
2179 static struct backlight_properties aty_bl_data = {
2180 .owner = THIS_MODULE,
2181 .get_brightness = aty_bl_get_brightness,
2182 .update_status = aty_bl_update_status,
2183 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
2186 static void aty_bl_set_power(struct fb_info *info, int power)
2188 mutex_lock(&info->bl_mutex);
2191 down(&info->bl_dev->sem);
2192 info->bl_dev->props->power = power;
2193 __aty_bl_update_status(info->bl_dev);
2194 up(&info->bl_dev->sem);
2197 mutex_unlock(&info->bl_mutex);
2200 static void aty_bl_init(struct atyfb_par *par)
2202 struct fb_info *info = pci_get_drvdata(par->pdev);
2203 struct backlight_device *bd;
2206 #ifdef CONFIG_PMAC_BACKLIGHT
2207 if (!pmac_has_backlight_type("ati"))
2211 snprintf(name, sizeof(name), "atybl%d", info->node);
2213 bd = backlight_device_register(name, par, &aty_bl_data);
2215 info->bl_dev = NULL;
2216 printk(KERN_WARNING "aty: Backlight registration failed\n");
2220 mutex_lock(&info->bl_mutex);
2222 fb_bl_default_curve(info, 0,
2223 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2224 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2225 mutex_unlock(&info->bl_mutex);
2228 bd->props->brightness = aty_bl_data.max_brightness;
2229 bd->props->power = FB_BLANK_UNBLANK;
2230 bd->props->update_status(bd);
2233 #ifdef CONFIG_PMAC_BACKLIGHT
2234 mutex_lock(&pmac_backlight_mutex);
2235 if (!pmac_backlight)
2236 pmac_backlight = bd;
2237 mutex_unlock(&pmac_backlight_mutex);
2240 printk("aty: Backlight initialized (%s)\n", name);
2248 static void aty_bl_exit(struct atyfb_par *par)
2250 struct fb_info *info = pci_get_drvdata(par->pdev);
2252 #ifdef CONFIG_PMAC_BACKLIGHT
2253 mutex_lock(&pmac_backlight_mutex);
2256 mutex_lock(&info->bl_mutex);
2258 #ifdef CONFIG_PMAC_BACKLIGHT
2259 if (pmac_backlight == info->bl_dev)
2260 pmac_backlight = NULL;
2263 backlight_device_unregister(info->bl_dev);
2265 printk("aty: Backlight unloaded\n");
2267 mutex_unlock(&info->bl_mutex);
2269 #ifdef CONFIG_PMAC_BACKLIGHT
2270 mutex_unlock(&pmac_backlight_mutex);
2274 #endif /* CONFIG_FB_ATY_BACKLIGHT */
2276 static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2278 const int ragepro_tbl[] = {
2279 44, 50, 55, 66, 75, 80, 100
2281 const int ragexl_tbl[] = {
2282 50, 66, 75, 83, 90, 95, 100, 105,
2283 110, 115, 120, 125, 133, 143, 166
2285 const int *refresh_tbl;
2288 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2289 refresh_tbl = ragexl_tbl;
2290 size = ARRAY_SIZE(ragexl_tbl);
2292 refresh_tbl = ragepro_tbl;
2293 size = ARRAY_SIZE(ragepro_tbl);
2296 for (i=0; i < size; i++) {
2297 if (xclk < refresh_tbl[i])
2300 par->mem_refresh_rate = i;
2307 static struct fb_info *fb_list = NULL;
2309 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2310 static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2311 struct fb_var_screeninfo *var)
2315 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2317 var->xres = var->xres_virtual = par->lcd_hdisp;
2318 var->right_margin = par->lcd_right_margin;
2319 var->left_margin = par->lcd_hblank_len -
2320 (par->lcd_right_margin + par->lcd_hsync_dly +
2321 par->lcd_hsync_len);
2322 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2323 var->yres = var->yres_virtual = par->lcd_vdisp;
2324 var->lower_margin = par->lcd_lower_margin;
2325 var->upper_margin = par->lcd_vblank_len -
2326 (par->lcd_lower_margin + par->lcd_vsync_len);
2327 var->vsync_len = par->lcd_vsync_len;
2328 var->pixclock = par->lcd_pixclock;
2334 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2336 static int __devinit aty_init(struct fb_info *info)
2338 struct atyfb_par *par = (struct atyfb_par *) info->par;
2339 const char *ramname = NULL, *xtal;
2340 int gtb_memsize, has_var = 0;
2341 struct fb_var_screeninfo var;
2344 init_waitqueue_head(&par->vblank.wait);
2345 spin_lock_init(&par->int_lock);
2347 #ifdef CONFIG_PPC_PMAC
2348 /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2349 * and set the frequency manually. */
2350 if (machine_is_compatible("PowerBook2,1")) {
2351 par->pll_limits.mclk = 70;
2352 par->pll_limits.xclk = 53;
2356 par->pll_limits.pll_max = pll;
2358 par->pll_limits.mclk = mclk;
2360 par->pll_limits.xclk = xclk;
2362 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2363 par->pll_per = 1000000/par->pll_limits.pll_max;
2364 par->mclk_per = 1000000/par->pll_limits.mclk;
2365 par->xclk_per = 1000000/par->pll_limits.xclk;
2367 par->ref_clk_per = 1000000000000ULL / 14318180;
2370 #ifdef CONFIG_FB_ATY_GX
2371 if (!M64_HAS(INTEGRATED)) {
2373 u8 dac_type, dac_subtype, clk_type;
2374 stat0 = aty_ld_le32(CONFIG_STAT0, par);
2375 par->bus_type = (stat0 >> 0) & 0x07;
2376 par->ram_type = (stat0 >> 3) & 0x07;
2377 ramname = aty_gx_ram[par->ram_type];
2378 /* FIXME: clockchip/RAMDAC probing? */
2379 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2381 clk_type = CLK_ATI18818_1;
2382 dac_type = (stat0 >> 9) & 0x07;
2383 if (dac_type == 0x07)
2384 dac_subtype = DAC_ATT20C408;
2386 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2388 dac_type = DAC_IBMRGB514;
2389 dac_subtype = DAC_IBMRGB514;
2390 clk_type = CLK_IBMRGB514;
2392 switch (dac_subtype) {
2394 par->dac_ops = &aty_dac_ibm514;
2396 case DAC_ATI68860_B:
2397 case DAC_ATI68860_C:
2398 par->dac_ops = &aty_dac_ati68860b;
2402 par->dac_ops = &aty_dac_att21c498;
2405 PRINTKI("aty_init: DAC type not implemented yet!\n");
2406 par->dac_ops = &aty_dac_unsupported;
2411 case CLK_ATI18818_1:
2412 par->pll_ops = &aty_pll_ati18818_1;
2416 par->pll_ops = &aty_pll_ibm514;
2419 #if 0 /* dead code */
2421 par->pll_ops = &aty_pll_stg1703;
2424 par->pll_ops = &aty_pll_ch8398;
2427 par->pll_ops = &aty_pll_att20c408;
2431 PRINTKI("aty_init: CLK type not implemented yet!");
2432 par->pll_ops = &aty_pll_unsupported;
2436 #endif /* CONFIG_FB_ATY_GX */
2437 #ifdef CONFIG_FB_ATY_CT
2438 if (M64_HAS(INTEGRATED)) {
2439 par->dac_ops = &aty_dac_ct;
2440 par->pll_ops = &aty_pll_ct;
2441 par->bus_type = PCI;
2442 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
2443 ramname = aty_ct_ram[par->ram_type];
2444 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2445 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2446 par->pll_limits.mclk = 63;
2449 if (M64_HAS(GTB_DSP)) {
2450 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2454 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2455 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2460 if (diff2 < diff1) {
2461 par->ref_clk_per = 1000000000000ULL / 29498928;
2466 #endif /* CONFIG_FB_ATY_CT */
2468 /* save previous video mode */
2469 aty_get_crtc(par, &saved_crtc);
2470 if(par->pll_ops->get_pll)
2471 par->pll_ops->get_pll(info, &saved_pll);
2473 i = aty_ld_le32(MEM_CNTL, par);
2474 gtb_memsize = M64_HAS(GTB_DSP);
2476 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
2478 info->fix.smem_len = 0x80000;
2481 info->fix.smem_len = 0x100000;
2483 case MEM_SIZE_2M_GTB:
2484 info->fix.smem_len = 0x200000;
2486 case MEM_SIZE_4M_GTB:
2487 info->fix.smem_len = 0x400000;
2489 case MEM_SIZE_6M_GTB:
2490 info->fix.smem_len = 0x600000;
2492 case MEM_SIZE_8M_GTB:
2493 info->fix.smem_len = 0x800000;
2496 info->fix.smem_len = 0x80000;
2498 switch (i & MEM_SIZE_ALIAS) {
2500 info->fix.smem_len = 0x80000;
2503 info->fix.smem_len = 0x100000;
2506 info->fix.smem_len = 0x200000;
2509 info->fix.smem_len = 0x400000;
2512 info->fix.smem_len = 0x600000;
2515 info->fix.smem_len = 0x800000;
2518 info->fix.smem_len = 0x80000;
2521 if (M64_HAS(MAGIC_VRAM_SIZE)) {
2522 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
2523 info->fix.smem_len += 0x400000;
2527 info->fix.smem_len = vram * 1024;
2528 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2529 if (info->fix.smem_len <= 0x80000)
2531 else if (info->fix.smem_len <= 0x100000)
2533 else if (info->fix.smem_len <= 0x200000)
2534 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2535 else if (info->fix.smem_len <= 0x400000)
2536 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2537 else if (info->fix.smem_len <= 0x600000)
2538 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2540 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2541 aty_st_le32(MEM_CNTL, i, par);
2545 * Reg Block 0 (CT-compatible block) is at mmio_start
2546 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2549 info->fix.mmio_len = 0x400;
2550 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2551 } else if (M64_HAS(CT)) {
2552 info->fix.mmio_len = 0x400;
2553 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2554 } else if (M64_HAS(VT)) {
2555 info->fix.mmio_start -= 0x400;
2556 info->fix.mmio_len = 0x800;
2557 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2559 info->fix.mmio_start -= 0x400;
2560 info->fix.mmio_len = 0x800;
2561 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2564 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2565 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
2566 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
2567 par->pll_limits.mclk, par->pll_limits.xclk);
2569 #if defined(DEBUG) && defined(CONFIG_ATY_CT)
2570 if (M64_HAS(INTEGRATED)) {
2572 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
2573 "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
2574 "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n"
2576 aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
2577 aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
2578 aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
2579 aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par));
2580 for (i = 0; i < 40; i++)
2581 printk(" %02x", aty_ld_pll_ct(i, par));
2585 if(par->pll_ops->init_pll)
2586 par->pll_ops->init_pll(info, &par->pll);
2589 * Last page of 8 MB (4 MB on ISA) aperture is MMIO,
2590 * unless the auxiliary register aperture is used.
2593 if (!par->aux_start &&
2594 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2595 info->fix.smem_len -= GUI_RESERVE;
2598 * Disable register access through the linear aperture
2599 * if the auxiliary aperture is used so we can access
2600 * the full 8 MB of video RAM on 8 MB boards.
2603 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2606 par->mtrr_aper = -1;
2609 /* Cover the whole resource. */
2610 par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1);
2611 if (par->mtrr_aper >= 0 && !par->aux_start) {
2612 /* Make a hole for mmio. */
2613 par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE,
2614 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1);
2615 if (par->mtrr_reg < 0) {
2616 mtrr_del(par->mtrr_aper, 0, 0);
2617 par->mtrr_aper = -1;
2623 info->fbops = &atyfb_ops;
2624 info->pseudo_palette = pseudo_palette;
2625 info->flags = FBINFO_DEFAULT |
2626 FBINFO_HWACCEL_IMAGEBLIT |
2627 FBINFO_HWACCEL_FILLRECT |
2628 FBINFO_HWACCEL_COPYAREA |
2629 FBINFO_HWACCEL_YPAN;
2631 #ifdef CONFIG_PMAC_BACKLIGHT
2632 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2633 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2634 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2635 | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2638 if (M64_HAS(MOBIL_BUS)) {
2639 #ifdef CONFIG_FB_ATY_BACKLIGHT
2644 memset(&var, 0, sizeof(var));
2646 if (machine_is(powermac)) {
2648 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2649 * applies to all Mac video cards
2652 if (mac_find_mode(&var, info, mode, 8))
2655 if (default_vmode == VMODE_CHOOSE) {
2657 if (M64_HAS(G3_PB_1024x768))
2658 /* G3 PowerBook with 1024x768 LCD */
2659 default_vmode = VMODE_1024_768_60;
2660 else if (machine_is_compatible("iMac"))
2661 default_vmode = VMODE_1024_768_75;
2662 else if (machine_is_compatible
2664 /* iBook with 800x600 LCD */
2665 default_vmode = VMODE_800_600_60;
2667 default_vmode = VMODE_640_480_67;
2668 sense = read_aty_sense(par);
2669 PRINTKI("monitor sense=%x, mode %d\n",
2670 sense, mac_map_monitor_sense(sense));
2672 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2673 default_vmode = VMODE_640_480_60;
2674 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2675 default_cmode = CMODE_8;
2676 if (!mac_vmode_to_var(default_vmode, default_cmode,
2682 #endif /* !CONFIG_PPC */
2684 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2685 if (!atyfb_get_timings_from_lcd(par, &var))
2689 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2696 var.accel_flags &= ~FB_ACCELF_TEXT;
2698 var.accel_flags |= FB_ACCELF_TEXT;
2700 if (comp_sync != -1) {
2702 var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2704 var.sync |= FB_SYNC_COMP_HIGH_ACT;
2707 if (var.yres == var.yres_virtual) {
2708 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2709 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2710 if (var.yres_virtual < var.yres)
2711 var.yres_virtual = var.yres;
2714 if (atyfb_check_var(&var, info)) {
2715 PRINTKE("can't set default video mode\n");
2720 atyfb_save_palette(par, 0);
2723 #ifdef CONFIG_FB_ATY_CT
2724 if (!noaccel && M64_HAS(INTEGRATED))
2725 aty_init_cursor(info);
2726 #endif /* CONFIG_FB_ATY_CT */
2729 fb_alloc_cmap(&info->cmap, 256, 0);
2731 if (register_framebuffer(info) < 0)
2736 PRINTKI("fb%d: %s frame buffer device on %s\n",
2737 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2741 /* restore video mode */
2742 aty_set_crtc(par, &saved_crtc);
2743 par->pll_ops->set_pll(info, &saved_pll);
2746 if (par->mtrr_reg >= 0) {
2747 mtrr_del(par->mtrr_reg, 0, 0);
2750 if (par->mtrr_aper >= 0) {
2751 mtrr_del(par->mtrr_aper, 0, 0);
2752 par->mtrr_aper = -1;
2759 static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2762 unsigned long vmembase, size, guiregbase;
2764 PRINTKI("store_video_par() '%s' \n", video_str);
2766 if (!(p = strsep(&video_str, ";")) || !*p)
2767 goto mach64_invalid;
2768 vmembase = simple_strtoul(p, NULL, 0);
2769 if (!(p = strsep(&video_str, ";")) || !*p)
2770 goto mach64_invalid;
2771 size = simple_strtoul(p, NULL, 0);
2772 if (!(p = strsep(&video_str, ";")) || !*p)
2773 goto mach64_invalid;
2774 guiregbase = simple_strtoul(p, NULL, 0);
2776 phys_vmembase[m64_num] = vmembase;
2777 phys_size[m64_num] = size;
2778 phys_guiregbase[m64_num] = guiregbase;
2779 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2784 phys_vmembase[m64_num] = 0;
2787 #endif /* CONFIG_ATARI */
2790 * Blank the display.
2793 static int atyfb_blank(int blank, struct fb_info *info)
2795 struct atyfb_par *par = (struct atyfb_par *) info->par;
2798 if (par->lock_blank || par->asleep)
2801 #ifdef CONFIG_FB_ATY_BACKLIGHT
2802 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2803 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2804 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2805 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2806 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2807 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2809 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2813 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2814 gen_cntl &= ~0x400004c;
2816 case FB_BLANK_UNBLANK:
2818 case FB_BLANK_NORMAL:
2819 gen_cntl |= 0x4000040;
2821 case FB_BLANK_VSYNC_SUSPEND:
2822 gen_cntl |= 0x4000048;
2824 case FB_BLANK_HSYNC_SUSPEND:
2825 gen_cntl |= 0x4000044;
2827 case FB_BLANK_POWERDOWN:
2828 gen_cntl |= 0x400004c;
2831 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2833 #ifdef CONFIG_FB_ATY_BACKLIGHT
2834 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2835 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2836 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2837 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2838 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2839 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2841 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2848 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2849 const struct atyfb_par *par)
2851 aty_st_8(DAC_W_INDEX, regno, par);
2852 aty_st_8(DAC_DATA, red, par);
2853 aty_st_8(DAC_DATA, green, par);
2854 aty_st_8(DAC_DATA, blue, par);
2858 * Set a single color register. The values supplied are already
2859 * rounded down to the hardware's capabilities (according to the
2860 * entries in the var structure). Return != 0 for invalid regno.
2861 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
2864 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2865 u_int transp, struct fb_info *info)
2867 struct atyfb_par *par = (struct atyfb_par *) info->par;
2869 u32 *pal = info->pseudo_palette;
2871 depth = info->var.bits_per_pixel;
2873 depth = (info->var.green.length == 5) ? 15 : 16;
2879 (depth == 16 && regno > 63) ||
2880 (depth == 15 && regno > 31))
2887 par->palette[regno].red = red;
2888 par->palette[regno].green = green;
2889 par->palette[regno].blue = blue;
2894 pal[regno] = (regno << 10) | (regno << 5) | regno;
2897 pal[regno] = (regno << 11) | (regno << 5) | regno;
2900 pal[regno] = (regno << 16) | (regno << 8) | regno;
2903 i = (regno << 8) | regno;
2904 pal[regno] = (i << 16) | i;
2909 i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2910 if (M64_HAS(EXTRA_BRIGHT))
2911 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
2912 aty_st_8(DAC_CNTL, i, par);
2913 aty_st_8(DAC_MASK, 0xff, par);
2915 if (M64_HAS(INTEGRATED)) {
2918 aty_st_pal(regno << 3, red,
2919 par->palette[regno<<1].green,
2921 red = par->palette[regno>>1].red;
2922 blue = par->palette[regno>>1].blue;
2924 } else if (depth == 15) {
2926 for(i = 0; i < 8; i++) {
2927 aty_st_pal(regno + i, red, green, blue, par);
2931 aty_st_pal(regno, red, green, blue, par);
2940 extern void (*prom_palette) (int);
2942 static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2943 struct fb_info *info, unsigned long addr)
2945 extern int con_is_present(void);
2947 struct atyfb_par *par = info->par;
2948 struct pcidev_cookie *pcp;
2950 int node, len, i, j, ret;
2953 /* Do not attach when we have a serial console. */
2954 if (!con_is_present())
2958 * Map memory-mapped registers.
2960 par->ati_regbase = (void *)addr + 0x7ffc00UL;
2961 info->fix.mmio_start = addr + 0x7ffc00UL;
2964 * Map in big-endian aperture.
2966 info->screen_base = (char *) (addr + 0x800000UL);
2967 info->fix.smem_start = addr + 0x800000UL;
2970 * Figure mmap addresses from PCI config space.
2971 * Split Framebuffer in big- and little-endian halfs.
2973 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2977 par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
2978 if (!par->mmap_map) {
2979 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2982 memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
2984 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2985 struct resource *rp = &pdev->resource[i];
2986 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2992 io = (rp->flags & IORESOURCE_IO);
2994 size = rp->end - base + 1;
2996 pci_read_config_dword(pdev, breg, &pbase);
3002 * Map the framebuffer a second time, this time without
3003 * the braindead _PAGE_IE setting. This is used by the
3004 * fixed Xserver, but we need to maintain the old mapping
3005 * to stay compatible with older ones...
3008 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
3009 par->mmap_map[j].poff = base & PAGE_MASK;
3010 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3011 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3012 par->mmap_map[j].prot_flag = _PAGE_E;
3017 * Here comes the old framebuffer mapping with _PAGE_IE
3018 * set for the big endian half of the framebuffer...
3021 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
3022 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
3023 par->mmap_map[j].size = 0x800000;
3024 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3025 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
3030 par->mmap_map[j].voff = pbase & PAGE_MASK;
3031 par->mmap_map[j].poff = base & PAGE_MASK;
3032 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3033 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3034 par->mmap_map[j].prot_flag = _PAGE_E;
3038 if((ret = correct_chipset(par)))
3041 if (IS_XL(pdev->device)) {
3043 * Fix PROMs idea of MEM_CNTL settings...
3045 mem = aty_ld_le32(MEM_CNTL, par);
3046 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
3047 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
3048 switch (mem & 0x0f) {
3050 mem = (mem & ~(0x0f)) | 2;
3053 mem = (mem & ~(0x0f)) | 3;
3056 mem = (mem & ~(0x0f)) | 4;
3059 mem = (mem & ~(0x0f)) | 5;
3064 if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
3065 mem &= ~(0x00700000);
3067 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
3068 aty_st_le32(MEM_CNTL, mem, par);
3072 * If this is the console device, we will set default video
3073 * settings to what the PROM left us with.
3075 node = prom_getchild(prom_root_node);
3076 node = prom_searchsiblings(node, "aliases");
3078 len = prom_getproperty(node, "screen", prop, sizeof(prop));
3081 node = prom_finddevice(prop);
3086 pcp = pdev->sysdata;
3087 if (node == pcp->prom_node->node) {
3088 struct fb_var_screeninfo *var = &default_var;
3089 unsigned int N, P, Q, M, T, R;
3090 u32 v_total, h_total;
3095 crtc.vxres = prom_getintdefault(node, "width", 1024);
3096 crtc.vyres = prom_getintdefault(node, "height", 768);
3097 var->bits_per_pixel = prom_getintdefault(node, "depth", 8);
3098 var->xoffset = var->yoffset = 0;
3099 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
3100 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
3101 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
3102 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
3103 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
3104 aty_crtc_to_var(&crtc, var);
3106 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin;
3107 v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
3110 * Read the PLL to figure actual Refresh Rate.
3112 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
3113 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
3114 for (i = 0; i < 16; i++)
3115 pll_regs[i] = aty_ld_pll_ct(i, par);
3118 * PLL Reference Divider M:
3123 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
3125 N = pll_regs[7 + (clock_cntl & 3)];
3128 * PLL Post Divider P (Dependant on CLOCK_CNTL):
3130 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3144 * where R is XTALIN (= 14318 or 29498 kHz).
3146 if (IS_XL(pdev->device))
3153 default_var.pixclock = 1000000000 / T;
3159 #else /* __sparc__ */
3162 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3163 static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3165 u32 driv_inf_tab, sig;
3168 /* To support an LCD panel, we should know it's dimensions and
3169 * it's desired pixel clock.
3170 * There are two ways to do it:
3171 * - Check the startup video mode and calculate the panel
3172 * size from it. This is unreliable.
3173 * - Read it from the driver information table in the video BIOS.
3175 /* Address of driver information table is at offset 0x78. */
3176 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3178 /* Check for the driver information table signature. */
3179 sig = (*(u32 *)driv_inf_tab);
3180 if ((sig == 0x54504c24) || /* Rage LT pro */
3181 (sig == 0x544d5224) || /* Rage mobility */
3182 (sig == 0x54435824) || /* Rage XC */
3183 (sig == 0x544c5824)) { /* Rage XL */
3184 PRINTKI("BIOS contains driver information table.\n");
3185 lcd_ofs = (*(u16 *)(driv_inf_tab + 10));
3188 par->lcd_table = bios_base + lcd_ofs;
3192 if (par->lcd_table != 0) {
3195 char refresh_rates_buf[100];
3196 int id, tech, f, i, m, default_refresh_rate;
3201 u16 width, height, panel_type, refresh_rates;
3204 u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200};
3205 /* The most important information is the panel size at
3206 * offset 25 and 27, but there's some other nice information
3207 * which we print to the screen.
3209 id = *(u8 *)par->lcd_table;
3210 strncpy(model,(char *)par->lcd_table+1,24);
3213 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3214 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3215 panel_type = *(u16 *)(par->lcd_table+29);
3217 txtcolour = "colour";
3219 txtcolour = "monochrome";
3221 txtdual = "dual (split) ";
3224 tech = (panel_type>>2) & 63;
3227 txtmonitor = "passive matrix";
3230 txtmonitor = "active matrix";
3233 txtmonitor = "active addressed STN";
3239 txtmonitor = "plasma";
3242 txtmonitor = "unknown";
3244 format = *(u32 *)(par->lcd_table+57);
3245 if (tech == 0 || tech == 2) {
3246 switch (format & 7) {
3248 txtformat = "12 bit interface";
3251 txtformat = "16 bit interface";
3254 txtformat = "24 bit interface";
3257 txtformat = "unkown format";
3260 switch (format & 7) {
3262 txtformat = "8 colours";
3265 txtformat = "512 colours";
3268 txtformat = "4096 colours";
3271 txtformat = "262144 colours (LT mode)";
3274 txtformat = "16777216 colours";
3277 txtformat = "262144 colours (FDPI-2 mode)";
3280 txtformat = "unkown format";
3283 PRINTKI("%s%s %s monitor detected: %s\n",
3284 txtdual ,txtcolour, txtmonitor, model);
3285 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3286 id, width, height, txtformat);
3287 refresh_rates_buf[0] = 0;
3288 refresh_rates = *(u16 *)(par->lcd_table+62);
3291 for (i=0;i<16;i++) {
3292 if (refresh_rates & m) {
3294 sprintf(strbuf, "%d", lcd_refresh_rates[i]);
3297 sprintf(strbuf, ",%d", lcd_refresh_rates[i]);
3299 strcat(refresh_rates_buf,strbuf);
3303 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3304 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3305 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3306 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3307 /* We now need to determine the crtc parameters for the
3308 * LCD monitor. This is tricky, because they are not stored
3309 * individually in the BIOS. Instead, the BIOS contains a
3310 * table of display modes that work for this monitor.
3312 * The idea is that we search for a mode of the same dimensions
3313 * as the dimensions of the LCD monitor. Say our LCD monitor
3314 * is 800x600 pixels, we search for a 800x600 monitor.
3315 * The CRTC parameters we find here are the ones that we need
3316 * to use to simulate other resolutions on the LCD screen.
3318 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3319 while (*lcdmodeptr != 0) {
3321 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3322 modeptr = bios_base + *lcdmodeptr;
3324 mwidth = *((u16 *)(modeptr+0));
3325 mheight = *((u16 *)(modeptr+2));
3327 if (mwidth == width && mheight == height) {
3328 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3329 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3330 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3331 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3332 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3333 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3335 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3336 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3337 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3338 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3340 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3341 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3342 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3343 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3349 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3350 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3351 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3352 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3358 if (*lcdmodeptr == 0) {
3359 PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3360 /* To do: Switch to CRT if possible. */
3362 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3363 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3365 par->lcd_hdisp + par->lcd_right_margin,
3366 par->lcd_hdisp + par->lcd_right_margin
3367 + par->lcd_hsync_dly + par->lcd_hsync_len,
3370 par->lcd_vdisp + par->lcd_lower_margin,
3371 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3373 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
3375 par->lcd_hblank_len - (par->lcd_right_margin +
3376 par->lcd_hsync_dly + par->lcd_hsync_len),
3378 par->lcd_right_margin,
3380 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3382 par->lcd_lower_margin,
3383 par->lcd_vsync_len);
3387 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
3389 static int __devinit init_from_bios(struct atyfb_par *par)
3391 u32 bios_base, rom_addr;
3394 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3395 bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3397 /* The BIOS starts with 0xaa55. */
3398 if (*((u16 *)bios_base) == 0xaa55) {
3401 u16 rom_table_offset, freq_table_offset;
3402 PLL_BLOCK_MACH64 pll_block;
3404 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3406 /* check for frequncy table */
3407 bios_ptr = (u8*)bios_base;
3408 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3409 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3410 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3412 PRINTKI("BIOS frequency table:\n");
3413 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3414 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3415 pll_block.ref_freq, pll_block.ref_divider);
3416 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3417 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3418 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3420 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3421 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3422 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3423 par->pll_limits.ref_div = pll_block.ref_divider;
3424 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3425 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3426 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3427 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3428 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3429 aty_init_lcd(par, bios_base);
3433 PRINTKE("no BIOS frequency table found, use parameters\n");
3436 iounmap((void* __iomem )bios_base);
3440 #endif /* __i386__ */
3442 static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr)
3444 struct atyfb_par *par = info->par;
3446 unsigned long raddr;
3447 struct resource *rrp;
3450 raddr = addr + 0x7ff000UL;
3451 rrp = &pdev->resource[2];
3452 if ((rrp->flags & IORESOURCE_MEM) && request_mem_region(rrp->start, rrp->end - rrp->start + 1, "atyfb")) {
3453 par->aux_start = rrp->start;
3454 par->aux_size = rrp->end - rrp->start + 1;
3456 PRINTKI("using auxiliary register aperture\n");
3459 info->fix.mmio_start = raddr;
3460 par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
3461 if (par->ati_regbase == 0)
3464 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3465 par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3468 * Enable memory-space accesses using config-space
3471 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3472 if (!(tmp & PCI_COMMAND_MEMORY)) {
3473 tmp |= PCI_COMMAND_MEMORY;
3474 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3477 /* Use the big-endian aperture */
3481 /* Map in frame buffer */
3482 info->fix.smem_start = addr;
3483 info->screen_base = ioremap(addr, 0x800000);
3484 if (info->screen_base == NULL) {
3486 goto atyfb_setup_generic_fail;
3489 if((ret = correct_chipset(par)))
3490 goto atyfb_setup_generic_fail;
3492 if((ret = init_from_bios(par)))
3493 goto atyfb_setup_generic_fail;
3495 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3496 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3498 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3500 /* according to ATI, we should use clock 3 for acelerated mode */
3501 par->clk_wr_offset = 3;
3505 atyfb_setup_generic_fail:
3506 iounmap(par->ati_regbase);
3507 par->ati_regbase = NULL;
3508 if (info->screen_base) {
3509 iounmap(info->screen_base);
3510 info->screen_base = NULL;
3515 #endif /* !__sparc__ */
3517 static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3519 unsigned long addr, res_start, res_size;
3520 struct fb_info *info;
3521 struct resource *rp;
3522 struct atyfb_par *par;
3523 int i, rc = -ENOMEM;
3525 for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
3526 if (pdev->device == aty_chips[i].pci_id)
3532 /* Enable device in PCI config */
3533 if (pci_enable_device(pdev)) {
3534 PRINTKE("Cannot enable PCI device\n");
3538 /* Find which resource to use */
3539 rp = &pdev->resource[0];
3540 if (rp->flags & IORESOURCE_IO)
3541 rp = &pdev->resource[1];
3547 res_start = rp->start;
3548 res_size = rp->end - rp->start + 1;
3549 if (!request_mem_region (res_start, res_size, "atyfb"))
3552 /* Allocate framebuffer */
3553 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3555 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
3559 info->fix = atyfb_fix;
3560 info->device = &pdev->dev;
3561 par->pci_id = aty_chips[i].pci_id;
3562 par->res_start = res_start;
3563 par->res_size = res_size;
3564 par->irq = pdev->irq;
3567 /* Setup "info" structure */
3569 rc = atyfb_setup_sparc(pdev, info, addr);
3571 rc = atyfb_setup_generic(pdev, info, addr);
3574 goto err_release_mem;
3576 pci_set_drvdata(pdev, info);
3578 /* Init chip & register framebuffer */
3580 goto err_release_io;
3584 prom_palette = atyfb_palette;
3587 * Add /dev/fb mmap values.
3589 par->mmap_map[0].voff = 0x8000000000000000UL;
3590 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3591 par->mmap_map[0].size = info->fix.smem_len;
3592 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3593 par->mmap_map[0].prot_flag = _PAGE_E;
3594 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3595 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3596 par->mmap_map[1].size = PAGE_SIZE;
3597 par->mmap_map[1].prot_mask = _PAGE_CACHE;
3598 par->mmap_map[1].prot_flag = _PAGE_E;
3599 #endif /* __sparc__ */
3605 kfree(par->mmap_map);
3607 if (par->ati_regbase)
3608 iounmap(par->ati_regbase);
3609 if (info->screen_base)
3610 iounmap(info->screen_base);
3614 release_mem_region(par->aux_start, par->aux_size);
3616 release_mem_region(par->res_start, par->res_size);
3617 framebuffer_release(info);
3622 #endif /* CONFIG_PCI */
3626 static int __init atyfb_atari_probe(void)
3628 struct atyfb_par *par;
3629 struct fb_info *info;
3633 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3634 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3635 !phys_guiregbase[m64_num]) {
3636 PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num);
3640 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3642 PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
3647 info->fix = atyfb_fix;
3649 par->irq = (unsigned int) -1; /* something invalid */
3652 * Map the video memory (physical address given) to somewhere in the
3653 * kernel address space.
3655 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
3656 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
3657 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3659 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */
3661 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3662 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3664 switch (clock_r & 0x003F) {
3666 par->clk_wr_offset = 3; /* */
3669 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
3672 par->clk_wr_offset = 1; /* */
3675 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
3679 if (aty_init(info)) {
3680 if (info->screen_base)
3681 iounmap(info->screen_base);
3682 if (par->ati_regbase)
3683 iounmap(par->ati_regbase);
3684 framebuffer_release(info);
3685 /* This is insufficient! kernel_map has added two large chunks!! */
3691 #endif /* CONFIG_ATARI */
3695 static void __devexit atyfb_remove(struct fb_info *info)
3697 struct atyfb_par *par = (struct atyfb_par *) info->par;
3699 /* restore video mode */
3700 aty_set_crtc(par, &saved_crtc);
3701 par->pll_ops->set_pll(info, &saved_pll);
3703 #ifdef CONFIG_FB_ATY_BACKLIGHT
3704 if (M64_HAS(MOBIL_BUS))
3708 unregister_framebuffer(info);
3711 if (par->mtrr_reg >= 0) {
3712 mtrr_del(par->mtrr_reg, 0, 0);
3715 if (par->mtrr_aper >= 0) {
3716 mtrr_del(par->mtrr_aper, 0, 0);
3717 par->mtrr_aper = -1;
3721 if (par->ati_regbase)
3722 iounmap(par->ati_regbase);
3723 if (info->screen_base)
3724 iounmap(info->screen_base);
3726 if (info->sprite.addr)
3727 iounmap(info->sprite.addr);
3731 kfree(par->mmap_map);
3734 release_mem_region(par->aux_start, par->aux_size);
3737 release_mem_region(par->res_start, par->res_size);
3739 framebuffer_release(info);
3743 static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3745 struct fb_info *info = pci_get_drvdata(pdev);
3751 * This driver uses its own matching table. That will be more difficult
3752 * to fix, so for now, we just match against any ATI ID and let the
3753 * probe() function find out what's up. That also mean we don't have
3754 * a module ID table though.
3756 static struct pci_device_id atyfb_pci_tbl[] = {
3757 { PCI_VENDOR_ID_ATI, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
3758 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 },
3762 static struct pci_driver atyfb_driver = {
3764 .id_table = atyfb_pci_tbl,
3765 .probe = atyfb_pci_probe,
3766 .remove = __devexit_p(atyfb_pci_remove),
3768 .suspend = atyfb_pci_suspend,
3769 .resume = atyfb_pci_resume,
3770 #endif /* CONFIG_PM */
3773 #endif /* CONFIG_PCI */
3776 static int __init atyfb_setup(char *options)
3780 if (!options || !*options)
3783 while ((this_opt = strsep(&options, ",")) != NULL) {
3784 if (!strncmp(this_opt, "noaccel", 7)) {
3787 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3790 } else if (!strncmp(this_opt, "vram:", 5))
3791 vram = simple_strtoul(this_opt + 5, NULL, 0);
3792 else if (!strncmp(this_opt, "pll:", 4))
3793 pll = simple_strtoul(this_opt + 4, NULL, 0);
3794 else if (!strncmp(this_opt, "mclk:", 5))
3795 mclk = simple_strtoul(this_opt + 5, NULL, 0);
3796 else if (!strncmp(this_opt, "xclk:", 5))
3797 xclk = simple_strtoul(this_opt+5, NULL, 0);
3798 else if (!strncmp(this_opt, "comp_sync:", 10))
3799 comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3801 else if (!strncmp(this_opt, "vmode:", 6)) {
3802 unsigned int vmode =
3803 simple_strtoul(this_opt + 6, NULL, 0);
3804 if (vmode > 0 && vmode <= VMODE_MAX)
3805 default_vmode = vmode;
3806 } else if (!strncmp(this_opt, "cmode:", 6)) {
3807 unsigned int cmode =
3808 simple_strtoul(this_opt + 6, NULL, 0);
3812 default_cmode = CMODE_8;
3816 default_cmode = CMODE_16;
3820 default_cmode = CMODE_32;
3827 * Why do we need this silly Mach64 argument?
3828 * We are already here because of mach64= so its redundant.
3830 else if (MACH_IS_ATARI
3831 && (!strncmp(this_opt, "Mach64:", 7))) {
3832 static unsigned char m64_num;
3833 static char mach64_str[80];
3834 strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3835 if (!store_video_par(mach64_str, m64_num)) {
3837 mach64_count = m64_num;
3848 static int __init atyfb_init(void)
3850 int err1 = 1, err2 = 1;
3852 char *option = NULL;
3854 if (fb_get_options("atyfb", &option))
3856 atyfb_setup(option);
3860 err1 = pci_register_driver(&atyfb_driver);
3863 err2 = atyfb_atari_probe();
3866 return (err1 && err2) ? -ENODEV : 0;
3869 static void __exit atyfb_exit(void)
3872 pci_unregister_driver(&atyfb_driver);
3876 module_init(atyfb_init);
3877 module_exit(atyfb_exit);
3879 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
3880 MODULE_LICENSE("GPL");
3881 module_param(noaccel, bool, 0);
3882 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
3883 module_param(vram, int, 0);
3884 MODULE_PARM_DESC(vram, "int: override size of video ram");
3885 module_param(pll, int, 0);
3886 MODULE_PARM_DESC(pll, "int: override video clock");
3887 module_param(mclk, int, 0);
3888 MODULE_PARM_DESC(mclk, "int: override memory clock");
3889 module_param(xclk, int, 0);
3890 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3891 module_param(comp_sync, int, 0);
3892 MODULE_PARM_DESC(comp_sync,
3893 "Set composite sync signal to low (0) or high (1)");
3894 module_param(mode, charp, 0);
3895 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3897 module_param(nomtrr, bool, 0);
3898 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");