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/config.h>
53 #include <linux/module.h>
54 #include <linux/moduleparam.h>
55 #include <linux/kernel.h>
56 #include <linux/errno.h>
57 #include <linux/string.h>
59 #include <linux/slab.h>
60 #include <linux/vmalloc.h>
61 #include <linux/delay.h>
62 #include <linux/console.h>
64 #include <linux/init.h>
65 #include <linux/pci.h>
66 #include <linux/interrupt.h>
67 #include <linux/spinlock.h>
68 #include <linux/wait.h>
71 #include <asm/uaccess.h>
73 #include <video/mach64.h>
79 #include "../macmodes.h"
87 #include <linux/adb.h>
88 #include <linux/pmu.h>
90 #ifdef CONFIG_BOOTX_TEXT
91 #include <asm/btext.h>
93 #ifdef CONFIG_PMAC_BACKLIGHT
94 #include <asm/backlight.h>
106 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
107 /* - must be large enough to catch all GUI-Regs */
108 /* - must be aligned to a PAGE boundary */
109 #define GUI_RESERVE (1 * PAGE_SIZE)
111 /* FIXME: remove the FAIL definition */
112 #define FAIL(msg) do { \
113 if (!(var->activate & FB_ACTIVATE_TEST)) \
114 printk(KERN_CRIT "atyfb: " msg "\n"); \
117 #define FAIL_MAX(msg, x, _max_) do { \
119 if (!(var->activate & FB_ACTIVATE_TEST)) \
120 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
125 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
127 #define DPRINTK(fmt, args...)
130 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
131 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
133 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
134 static const u32 lt_lcd_regs[] = {
141 0, /* EXT_VERT_STRETCH */
146 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
148 if (M64_HAS(LT_LCD_REGS)) {
149 aty_st_le32(lt_lcd_regs[index], val, par);
153 /* write addr byte */
154 temp = aty_ld_le32(LCD_INDEX, par);
155 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
156 /* write the register value */
157 aty_st_le32(LCD_DATA, val, par);
161 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
163 if (M64_HAS(LT_LCD_REGS)) {
164 return aty_ld_le32(lt_lcd_regs[index], par);
168 /* write addr byte */
169 temp = aty_ld_le32(LCD_INDEX, par);
170 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
171 /* read the register value */
172 return aty_ld_le32(LCD_DATA, par);
175 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
177 #ifdef CONFIG_FB_ATY_GENERIC_LCD
181 * Reduce a fraction by factoring out the largest common divider of the
182 * fraction's numerator and denominator.
184 static void ATIReduceRatio(int *Numerator, int *Denominator)
186 int Multiplier, Divider, Remainder;
188 Multiplier = *Numerator;
189 Divider = *Denominator;
191 while ((Remainder = Multiplier % Divider))
193 Multiplier = Divider;
197 *Numerator /= Divider;
198 *Denominator /= Divider;
202 * The Hardware parameters for each card
205 struct aty_cmap_regs {
213 struct pci_mmap_map {
217 unsigned long prot_flag;
218 unsigned long prot_mask;
221 static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
223 .type = FB_TYPE_PACKED_PIXELS,
224 .visual = FB_VISUAL_PSEUDOCOLOR,
230 * Frame buffer device API
233 static int atyfb_open(struct fb_info *info, int user);
234 static int atyfb_release(struct fb_info *info, int user);
235 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
236 static int atyfb_set_par(struct fb_info *info);
237 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
238 u_int transp, struct fb_info *info);
239 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
240 static int atyfb_blank(int blank, struct fb_info *info);
241 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
242 u_long arg, struct fb_info *info);
243 extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
244 extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
245 extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
247 static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
249 static int atyfb_sync(struct fb_info *info);
255 static int aty_init(struct fb_info *info, const char *name);
257 static int store_video_par(char *videopar, unsigned char m64_num);
260 static struct crtc saved_crtc;
261 static union aty_pll saved_pll;
262 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
264 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
265 static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
266 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
267 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
269 static int read_aty_sense(const struct atyfb_par *par);
274 * Interface used by the world
277 static struct fb_var_screeninfo default_var = {
278 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
279 640, 480, 640, 480, 0, 0, 8, 0,
280 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
281 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
282 0, FB_VMODE_NONINTERLACED
285 static struct fb_videomode defmode = {
286 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
287 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
288 0, FB_VMODE_NONINTERLACED
291 static struct fb_ops atyfb_ops = {
292 .owner = THIS_MODULE,
293 .fb_open = atyfb_open,
294 .fb_release = atyfb_release,
295 .fb_check_var = atyfb_check_var,
296 .fb_set_par = atyfb_set_par,
297 .fb_setcolreg = atyfb_setcolreg,
298 .fb_pan_display = atyfb_pan_display,
299 .fb_blank = atyfb_blank,
300 .fb_ioctl = atyfb_ioctl,
301 .fb_fillrect = atyfb_fillrect,
302 .fb_copyarea = atyfb_copyarea,
303 .fb_imageblit = atyfb_imageblit,
305 .fb_mmap = atyfb_mmap,
307 .fb_sync = atyfb_sync,
318 static int comp_sync __initdata = -1;
322 static int default_vmode __initdata = VMODE_CHOOSE;
323 static int default_cmode __initdata = CMODE_CHOOSE;
325 module_param_named(vmode, default_vmode, int, 0);
326 MODULE_PARM_DESC(vmode, "int: video mode for mac");
327 module_param_named(cmode, default_cmode, int, 0);
328 MODULE_PARM_DESC(cmode, "int: color mode for mac");
332 static unsigned int mach64_count __initdata = 0;
333 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
334 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
335 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
338 /* top -> down is an evolution of mach64 chipset, any corrections? */
339 #define ATI_CHIP_88800GX (M64F_GX)
340 #define ATI_CHIP_88800CX (M64F_GX)
342 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
343 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
345 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
346 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
348 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
349 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
350 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
352 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
354 /* make sets shorter */
355 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
357 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
358 /*#define ATI_CHIP_264GTDVD ?*/
359 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
361 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
362 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
363 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
365 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
366 #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)
373 } aty_chips[] __devinitdata = {
374 #ifdef CONFIG_FB_ATY_GX
376 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX },
377 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX },
378 #endif /* CONFIG_FB_ATY_GX */
380 #ifdef CONFIG_FB_ATY_CT
381 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT },
382 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET },
383 { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT },
384 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT },
385 /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */
386 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB },
387 { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 },
389 { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT },
390 /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */
391 { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
393 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 },
395 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
396 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
397 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
398 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
400 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO },
401 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO },
402 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
403 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO },
404 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO },
406 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO },
407 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO },
408 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
409 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
410 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
412 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
413 { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
414 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
415 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
416 { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
417 { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
419 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
420 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
421 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
422 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
423 #endif /* CONFIG_FB_ATY_CT */
427 static int __devinit correct_chipset(struct atyfb_par *par)
435 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
436 if (par->pci_id == aty_chips[i].pci_id)
439 name = aty_chips[i].name;
440 par->pll_limits.pll_max = aty_chips[i].pll;
441 par->pll_limits.mclk = aty_chips[i].mclk;
442 par->pll_limits.xclk = aty_chips[i].xclk;
443 par->features = aty_chips[i].features;
445 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
446 type = chip_id & CFG_CHIP_TYPE;
447 rev = (chip_id & CFG_CHIP_REV) >> 24;
449 switch(par->pci_id) {
450 #ifdef CONFIG_FB_ATY_GX
451 case PCI_CHIP_MACH64GX:
455 case PCI_CHIP_MACH64CX:
460 #ifdef CONFIG_FB_ATY_CT
461 case PCI_CHIP_MACH64VT:
464 name = "ATI264VTA3 (Mach64 VT)";
465 par->pll_limits.pll_max = 170;
466 par->pll_limits.mclk = 67;
467 par->pll_limits.xclk = 67;
468 par->features = ATI_CHIP_264VT;
469 } else if(rev == 0x40) {
470 name = "ATI264VTA4 (Mach64 VT)";
471 par->pll_limits.pll_max = 200;
472 par->pll_limits.mclk = 67;
473 par->pll_limits.xclk = 67;
474 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
476 name = "ATI264VTB (Mach64 VT)";
477 par->pll_limits.pll_max = 200;
478 par->pll_limits.mclk = 67;
479 par->pll_limits.xclk = 67;
480 par->features = ATI_CHIP_264VTB;
483 case PCI_CHIP_MACH64GT:
486 par->pll_limits.pll_max = 170;
487 par->pll_limits.mclk = 67;
488 par->pll_limits.xclk = 67;
489 par->features = ATI_CHIP_264GTB;
490 } else if(rev == 0x02) {
491 par->pll_limits.pll_max = 200;
492 par->pll_limits.mclk = 67;
493 par->pll_limits.xclk = 67;
494 par->features = ATI_CHIP_264GTB;
500 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
504 static char ram_dram[] __devinitdata = "DRAM";
505 static char ram_resv[] __devinitdata = "RESV";
506 #ifdef CONFIG_FB_ATY_GX
507 static char ram_vram[] __devinitdata = "VRAM";
508 #endif /* CONFIG_FB_ATY_GX */
509 #ifdef CONFIG_FB_ATY_CT
510 static char ram_edo[] __devinitdata = "EDO";
511 static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
512 static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
513 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
514 static char ram_off[] __devinitdata = "OFF";
515 #endif /* CONFIG_FB_ATY_CT */
518 static u32 pseudo_palette[17];
520 #ifdef CONFIG_FB_ATY_GX
521 static char *aty_gx_ram[8] __devinitdata = {
522 ram_dram, ram_vram, ram_vram, ram_dram,
523 ram_dram, ram_vram, ram_vram, ram_resv
525 #endif /* CONFIG_FB_ATY_GX */
527 #ifdef CONFIG_FB_ATY_CT
528 static char *aty_ct_ram[8] __devinitdata = {
529 ram_off, ram_dram, ram_edo, ram_edo,
530 ram_sdram, ram_sgram, ram_sdram32, ram_resv
532 #endif /* CONFIG_FB_ATY_CT */
534 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par)
536 u32 pixclock = var->pixclock;
537 #ifdef CONFIG_FB_ATY_GENERIC_LCD
539 par->pll.ct.xres = 0;
540 if (par->lcd_table != 0) {
541 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
542 if(lcd_on_off & LCD_ON) {
543 par->pll.ct.xres = var->xres;
544 pixclock = par->lcd_pixclock;
551 #if defined(CONFIG_PPC)
554 * Apple monitor sense
557 static int __init read_aty_sense(const struct atyfb_par *par)
561 aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
563 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
565 i = aty_ld_le32(GP_IO, par); /* get primary sense value */
566 sense = ((i & 0x3000) >> 3) | (i & 0x100);
568 /* drive each sense line low in turn and collect the other 2 */
569 aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
571 i = aty_ld_le32(GP_IO, par);
572 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
573 aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
576 aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
578 i = aty_ld_le32(GP_IO, par);
579 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
580 aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
583 aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
585 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
586 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
590 #endif /* defined(CONFIG_PPC) */
592 /* ------------------------------------------------------------------------- */
598 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
600 #ifdef CONFIG_FB_ATY_GENERIC_LCD
601 if (par->lcd_table != 0) {
602 if(!M64_HAS(LT_LCD_REGS)) {
603 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
604 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
606 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
607 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
610 /* switch to non shadow registers */
611 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
612 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
614 /* save stretching */
615 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
616 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
617 if (!M64_HAS(LT_LCD_REGS))
618 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
621 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
622 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
623 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
624 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
625 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
626 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
627 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
629 #ifdef CONFIG_FB_ATY_GENERIC_LCD
630 if (par->lcd_table != 0) {
631 /* switch to shadow registers */
632 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
633 SHADOW_EN | SHADOW_RW_EN, par);
635 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
636 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
637 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
638 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
640 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
642 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
645 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
647 #ifdef CONFIG_FB_ATY_GENERIC_LCD
648 if (par->lcd_table != 0) {
650 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
652 /* update non-shadow registers first */
653 aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
654 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
655 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
657 /* temporarily disable stretching */
658 aty_st_lcd(HORZ_STRETCHING,
659 crtc->horz_stretching &
660 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
661 aty_st_lcd(VERT_STRETCHING,
662 crtc->vert_stretching &
663 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
664 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
668 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
670 DPRINTK("setting up CRTC\n");
671 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
672 ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
673 (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
674 (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
676 DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
677 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
678 DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
679 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
680 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
681 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
682 DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
684 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
685 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
686 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
687 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
688 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
689 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
691 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
694 if (par->accel_flags & FB_ACCELF_TEXT)
695 aty_init_engine(par, info);
697 #ifdef CONFIG_FB_ATY_GENERIC_LCD
698 /* after setting the CRTC registers we should set the LCD registers. */
699 if (par->lcd_table != 0) {
700 /* switch to shadow registers */
701 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
702 (SHADOW_EN | SHADOW_RW_EN), par);
704 DPRINTK("set shadow CRT to %ix%i %c%c\n",
705 ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
706 (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
708 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
709 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
710 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
711 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
713 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
714 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
715 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
716 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
718 /* restore CRTC selection & shadow state and enable stretching */
719 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
720 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
721 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
722 if(!M64_HAS(LT_LCD_REGS))
723 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
725 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
726 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
727 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
728 if(!M64_HAS(LT_LCD_REGS)) {
729 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
730 aty_ld_le32(LCD_INDEX, par);
731 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
734 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
737 static int aty_var_to_crtc(const struct fb_info *info,
738 const struct fb_var_screeninfo *var, struct crtc *crtc)
740 struct atyfb_par *par = (struct atyfb_par *) info->par;
741 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
742 u32 sync, vmode, vdisplay;
743 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
744 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
745 u32 pix_width, dp_pix_width, dp_chain_mask;
750 vxres = var->xres_virtual;
751 vyres = var->yres_virtual;
752 xoffset = var->xoffset;
753 yoffset = var->yoffset;
754 bpp = var->bits_per_pixel;
756 bpp = (var->green.length == 5) ? 15 : 16;
760 /* convert (and round up) and validate */
761 if (vxres < xres + xoffset)
762 vxres = xres + xoffset;
765 if (vyres < yres + yoffset)
766 vyres = yres + yoffset;
771 pix_width = CRTC_PIX_WIDTH_8BPP;
773 HOST_8BPP | SRC_8BPP | DST_8BPP |
774 BYTE_ORDER_LSB_TO_MSB;
775 dp_chain_mask = DP_CHAIN_8BPP;
776 } else if (bpp <= 15) {
778 pix_width = CRTC_PIX_WIDTH_15BPP;
779 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
780 BYTE_ORDER_LSB_TO_MSB;
781 dp_chain_mask = DP_CHAIN_15BPP;
782 } else if (bpp <= 16) {
784 pix_width = CRTC_PIX_WIDTH_16BPP;
785 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
786 BYTE_ORDER_LSB_TO_MSB;
787 dp_chain_mask = DP_CHAIN_16BPP;
788 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
790 pix_width = CRTC_PIX_WIDTH_24BPP;
792 HOST_8BPP | SRC_8BPP | DST_8BPP |
793 BYTE_ORDER_LSB_TO_MSB;
794 dp_chain_mask = DP_CHAIN_24BPP;
795 } else if (bpp <= 32) {
797 pix_width = CRTC_PIX_WIDTH_32BPP;
798 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
799 BYTE_ORDER_LSB_TO_MSB;
800 dp_chain_mask = DP_CHAIN_32BPP;
804 if (vxres * vyres * bpp / 8 > info->fix.smem_len)
805 FAIL("not enough video RAM");
807 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
808 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
810 if((xres > 1600) || (yres > 1200)) {
811 FAIL("MACH64 chips are designed for max 1600x1200\n"
812 "select anoter resolution.");
814 h_sync_strt = h_disp + var->right_margin;
815 h_sync_end = h_sync_strt + var->hsync_len;
816 h_sync_dly = var->right_margin & 7;
817 h_total = h_sync_end + h_sync_dly + var->left_margin;
819 v_sync_strt = v_disp + var->lower_margin;
820 v_sync_end = v_sync_strt + var->vsync_len;
821 v_total = v_sync_end + var->upper_margin;
823 #ifdef CONFIG_FB_ATY_GENERIC_LCD
824 if (par->lcd_table != 0) {
825 if(!M64_HAS(LT_LCD_REGS)) {
826 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
827 crtc->lcd_index = lcd_index &
828 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
829 aty_st_le32(LCD_INDEX, lcd_index, par);
832 if (!M64_HAS(MOBIL_BUS))
833 crtc->lcd_index |= CRTC2_DISPLAY_DIS;
835 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
836 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
838 crtc->lcd_gen_cntl &=
839 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
840 /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
841 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
842 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
844 if((crtc->lcd_gen_cntl & LCD_ON) &&
845 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
846 /* We cannot display the mode on the LCD. If the CRT is enabled
847 we can turn off the LCD.
848 If the CRT is off, it isn't a good idea to switch it on; we don't
849 know if one is connected. So it's better to fail then.
851 if (crtc->lcd_gen_cntl & CRT_ON) {
852 if (!(var->activate & FB_ACTIVATE_TEST))
853 PRINTKI("Disable LCD panel, because video mode does not fit.\n");
854 crtc->lcd_gen_cntl &= ~LCD_ON;
855 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
857 if (!(var->activate & FB_ACTIVATE_TEST))
858 PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
864 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
866 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
867 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
868 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */
870 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
872 /* This is horror! When we simulate, say 640x480 on an 800x600
873 LCD monitor, the CRTC should be programmed 800x600 values for
874 the non visible part, but 640x480 for the visible part.
875 This code has been tested on a laptop with it's 1400x1050 LCD
876 monitor and a conventional monitor both switched on.
877 Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
878 works with little glitches also with DOUBLESCAN modes
880 if (yres < par->lcd_height) {
881 VScan = par->lcd_height / yres;
884 vmode |= FB_VMODE_DOUBLE;
888 h_sync_strt = h_disp + par->lcd_right_margin;
889 h_sync_end = h_sync_strt + par->lcd_hsync_len;
890 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
891 h_total = h_disp + par->lcd_hblank_len;
893 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
894 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
895 v_total = v_disp + par->lcd_vblank_len / VScan;
897 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
899 h_disp = (h_disp >> 3) - 1;
900 h_sync_strt = (h_sync_strt >> 3) - 1;
901 h_sync_end = (h_sync_end >> 3) - 1;
902 h_total = (h_total >> 3) - 1;
903 h_sync_wid = h_sync_end - h_sync_strt;
905 FAIL_MAX("h_disp too large", h_disp, 0xff);
906 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
907 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
908 if(h_sync_wid > 0x1f)
910 FAIL_MAX("h_total too large", h_total, 0x1ff);
912 if (vmode & FB_VMODE_DOUBLE) {
920 #ifdef CONFIG_FB_ATY_GENERIC_LCD
921 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
922 vdisplay = par->lcd_height;
929 v_sync_wid = v_sync_end - v_sync_strt;
931 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
932 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
933 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
934 if(v_sync_wid > 0x1f)
936 FAIL_MAX("v_total too large", v_total, 0x7ff);
938 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
943 crtc->xoffset = xoffset;
944 crtc->yoffset = yoffset;
946 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
947 crtc->vline_crnt_vline = 0;
949 crtc->h_tot_disp = h_total | (h_disp<<16);
950 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
951 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21);
952 crtc->v_tot_disp = v_total | (v_disp<<16);
953 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
955 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
956 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
957 crtc->gen_cntl |= CRTC_VGA_LINEAR;
959 /* Enable doublescan mode if requested */
960 if (vmode & FB_VMODE_DOUBLE)
961 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
962 /* Enable interlaced mode if requested */
963 if (vmode & FB_VMODE_INTERLACED)
964 crtc->gen_cntl |= CRTC_INTERLACE_EN;
965 #ifdef CONFIG_FB_ATY_GENERIC_LCD
966 if (par->lcd_table != 0) {
968 if(vmode & FB_VMODE_DOUBLE)
970 if(vmode & FB_VMODE_INTERLACED) {
973 /* The prefered mode for the LCD is not interlaced, so disable it if
974 it was enabled. For doublescan there is no problem, because we can
975 compensate for it in the hardware stretching (we stretch half as much)
977 vmode &= ~FB_VMODE_INTERLACED;
978 /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/
980 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
981 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
982 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
983 USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
984 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
986 /* MOBILITY M1 tested, FIXME: LT */
987 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
988 if (!M64_HAS(LT_LCD_REGS))
989 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
990 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
992 crtc->horz_stretching &=
993 ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
994 HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
995 if (xres < par->lcd_width) {
998 * The horizontal blender misbehaves when HDisplay is less than a
999 * a certain threshold (440 for a 1024-wide panel). It doesn't
1000 * stretch such modes enough. Use pixel replication instead of
1001 * blending to stretch modes that can be made to exactly fit the
1002 * panel width. The undocumented "NoLCDBlend" option allows the
1003 * pixel-replicated mode to be slightly wider or narrower than the
1004 * panel width. It also causes a mode that is exactly half as wide
1005 * as the panel to be pixel-replicated, rather than blended.
1007 int HDisplay = xres & ~7;
1008 int nStretch = par->lcd_width / HDisplay;
1009 int Remainder = par->lcd_width % HDisplay;
1011 if ((!Remainder && ((nStretch > 2))) ||
1012 (((HDisplay * 16) / par->lcd_width) < 7)) {
1013 static const char StretchLoops[] = {10, 12, 13, 15, 16};
1014 int horz_stretch_loop = -1, BestRemainder;
1015 int Numerator = HDisplay, Denominator = par->lcd_width;
1017 ATIReduceRatio(&Numerator, &Denominator);
1019 BestRemainder = (Numerator * 16) / Denominator;
1020 while (--Index >= 0) {
1021 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1023 if (Remainder < BestRemainder) {
1024 horz_stretch_loop = Index;
1025 if (!(BestRemainder = Remainder))
1030 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1031 int horz_stretch_ratio = 0, Accumulator = 0;
1032 int reuse_previous = 1;
1034 Index = StretchLoops[horz_stretch_loop];
1036 while (--Index >= 0) {
1037 if (Accumulator > 0)
1038 horz_stretch_ratio |= reuse_previous;
1040 Accumulator += Denominator;
1041 Accumulator -= Numerator;
1042 reuse_previous <<= 1;
1045 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1046 ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1047 (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1048 break; /* Out of the do { ... } while (0) */
1052 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1053 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1057 if (vdisplay < par->lcd_height) {
1058 crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1059 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1061 if (!M64_HAS(LT_LCD_REGS) &&
1062 xres <= (M64_HAS(MOBIL_BUS)?1024:800))
1063 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1066 * Don't use vertical blending if the mode is too wide or not
1067 * vertically stretched.
1069 crtc->vert_stretching = 0;
1071 /* copy to shadow crtc */
1072 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1073 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1074 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1075 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1077 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1079 if (M64_HAS(MAGIC_FIFO)) {
1081 /* FIXME: magic FIFO values */
1082 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH);
1084 crtc->dp_pix_width = dp_pix_width;
1085 crtc->dp_chain_mask = dp_chain_mask;
1090 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var)
1092 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1093 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
1095 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1097 u32 double_scan, interlace;
1100 h_total = crtc->h_tot_disp & 0x1ff;
1101 h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1102 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1103 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1104 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1105 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1106 v_total = crtc->v_tot_disp & 0x7ff;
1107 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1108 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1109 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1110 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1111 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1112 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1113 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1114 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1117 xres = (h_disp + 1) * 8;
1119 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1120 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1121 hslen = h_sync_wid * 8;
1122 upper = v_total - v_sync_strt - v_sync_wid;
1123 lower = v_sync_strt - v_disp;
1125 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1126 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1127 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1129 switch (pix_width) {
1131 case CRTC_PIX_WIDTH_4BPP:
1133 var->red.offset = 0;
1134 var->red.length = 8;
1135 var->green.offset = 0;
1136 var->green.length = 8;
1137 var->blue.offset = 0;
1138 var->blue.length = 8;
1139 var->transp.offset = 0;
1140 var->transp.length = 0;
1143 case CRTC_PIX_WIDTH_8BPP:
1145 var->red.offset = 0;
1146 var->red.length = 8;
1147 var->green.offset = 0;
1148 var->green.length = 8;
1149 var->blue.offset = 0;
1150 var->blue.length = 8;
1151 var->transp.offset = 0;
1152 var->transp.length = 0;
1154 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
1156 var->red.offset = 10;
1157 var->red.length = 5;
1158 var->green.offset = 5;
1159 var->green.length = 5;
1160 var->blue.offset = 0;
1161 var->blue.length = 5;
1162 var->transp.offset = 0;
1163 var->transp.length = 0;
1165 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
1167 var->red.offset = 11;
1168 var->red.length = 5;
1169 var->green.offset = 5;
1170 var->green.length = 6;
1171 var->blue.offset = 0;
1172 var->blue.length = 5;
1173 var->transp.offset = 0;
1174 var->transp.length = 0;
1176 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
1178 var->red.offset = 16;
1179 var->red.length = 8;
1180 var->green.offset = 8;
1181 var->green.length = 8;
1182 var->blue.offset = 0;
1183 var->blue.length = 8;
1184 var->transp.offset = 0;
1185 var->transp.length = 0;
1187 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
1189 var->red.offset = 16;
1190 var->red.length = 8;
1191 var->green.offset = 8;
1192 var->green.length = 8;
1193 var->blue.offset = 0;
1194 var->blue.length = 8;
1195 var->transp.offset = 24;
1196 var->transp.length = 8;
1199 PRINTKE("Invalid pixel width\n");
1206 var->xres_virtual = crtc->vxres;
1207 var->yres_virtual = crtc->vyres;
1208 var->bits_per_pixel = bpp;
1209 var->left_margin = left;
1210 var->right_margin = right;
1211 var->upper_margin = upper;
1212 var->lower_margin = lower;
1213 var->hsync_len = hslen;
1214 var->vsync_len = vslen;
1216 var->vmode = FB_VMODE_NONINTERLACED;
1217 /* In double scan mode, the vertical parameters are doubled, so we need to
1218 half them to get the right values.
1219 In interlaced mode the values are already correct, so no correction is
1223 var->vmode = FB_VMODE_INTERLACED;
1226 var->vmode = FB_VMODE_DOUBLE;
1228 var->upper_margin>>=1;
1229 var->lower_margin>>=1;
1236 /* ------------------------------------------------------------------------- */
1238 static int atyfb_set_par(struct fb_info *info)
1240 struct atyfb_par *par = (struct atyfb_par *) info->par;
1241 struct fb_var_screeninfo *var = &info->var;
1245 struct fb_var_screeninfo debug;
1251 if ((err = aty_var_to_crtc(info, var, &par->crtc)))
1254 pixclock = atyfb_get_pixclock(var, par);
1256 if (pixclock == 0) {
1257 PRINTKE("Invalid pixclock\n");
1260 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
1264 par->accel_flags = var->accel_flags; /* hack */
1266 if (par->blitter_may_be_busy)
1269 aty_set_crtc(par, &par->crtc);
1270 par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
1271 par->pll_ops->set_pll(info, &par->pll);
1274 if(par->pll_ops && par->pll_ops->pll_to_var)
1275 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll));
1279 if(0 == pixclock_in_ps) {
1280 PRINTKE("ALERT ops->pll_to_var get 0\n");
1281 pixclock_in_ps = pixclock;
1284 memset(&debug, 0, sizeof(debug));
1285 if(!aty_crtc_to_var(&(par->crtc), &debug)) {
1286 u32 hSync, vRefresh;
1287 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1288 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1290 h_disp = debug.xres;
1291 h_sync_strt = h_disp + debug.right_margin;
1292 h_sync_end = h_sync_strt + debug.hsync_len;
1293 h_total = h_sync_end + debug.left_margin;
1294 v_disp = debug.yres;
1295 v_sync_strt = v_disp + debug.lower_margin;
1296 v_sync_end = v_sync_strt + debug.vsync_len;
1297 v_total = v_sync_end + debug.upper_margin;
1299 hSync = 1000000000 / (pixclock_in_ps * h_total);
1300 vRefresh = (hSync * 1000) / v_total;
1301 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1303 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1306 DPRINTK("atyfb_set_par\n");
1307 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
1308 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
1309 var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
1310 DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps);
1311 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1312 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1313 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1314 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1315 h_disp, h_sync_strt, h_sync_end, h_total,
1316 v_disp, v_sync_strt, v_sync_end, v_total);
1317 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
1319 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1320 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1324 if (!M64_HAS(INTEGRATED)) {
1325 /* Don't forget MEM_CNTL */
1326 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1327 switch (var->bits_per_pixel) {
1338 aty_st_le32(MEM_CNTL, tmp, par);
1340 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1341 if (!M64_HAS(MAGIC_POSTDIV))
1342 tmp |= par->mem_refresh_rate << 20;
1343 switch (var->bits_per_pixel) {
1355 if (M64_HAS(CT_BUS)) {
1356 aty_st_le32(DAC_CNTL, 0x87010184, par);
1357 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1358 } else if (M64_HAS(VT_BUS)) {
1359 aty_st_le32(DAC_CNTL, 0x87010184, par);
1360 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1361 } else if (M64_HAS(MOBIL_BUS)) {
1362 aty_st_le32(DAC_CNTL, 0x80010102, par);
1363 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1366 aty_st_le32(DAC_CNTL, 0x86010102, par);
1367 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1368 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1370 aty_st_le32(MEM_CNTL, tmp, par);
1372 aty_st_8(DAC_MASK, 0xff, par);
1374 info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
1375 info->fix.visual = var->bits_per_pixel <= 8 ?
1376 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1378 /* Initialize the graphics engine */
1379 if (par->accel_flags & FB_ACCELF_TEXT)
1380 aty_init_engine(par, info);
1382 #ifdef CONFIG_BOOTX_TEXT
1383 btext_update_display(info->fix.smem_start,
1384 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1385 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1386 var->bits_per_pixel,
1387 par->crtc.vxres * var->bits_per_pixel / 8);
1388 #endif /* CONFIG_BOOTX_TEXT */
1390 /* switch to accelerator mode */
1391 if (!(par->crtc.gen_cntl & CRTC_EXT_DISP_EN))
1392 aty_st_le32(CRTC_GEN_CNTL, par->crtc.gen_cntl | CRTC_EXT_DISP_EN, par);
1396 /* dump non shadow CRTC, pll, LCD registers */
1399 /* CRTC registers */
1401 printk("debug atyfb: Mach64 non-shadow register values:");
1402 for (i = 0; i < 256; i = i+4) {
1403 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
1404 printk(" %08X", aty_ld_le32(i, par));
1408 #ifdef CONFIG_FB_ATY_CT
1411 printk("debug atyfb: Mach64 PLL register values:");
1412 for (i = 0; i < 64; i++) {
1413 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1414 if(i%4 == 0) printk(" ");
1415 printk("%02X", aty_ld_pll_ct(i, par));
1418 #endif /* CONFIG_FB_ATY_CT */
1420 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1421 if (par->lcd_table != 0) {
1424 printk("debug atyfb: LCD register values:");
1425 if(M64_HAS(LT_LCD_REGS)) {
1426 for(i = 0; i <= POWER_MANAGEMENT; i++) {
1427 if(i == EXT_VERT_STRETCH)
1429 printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
1430 printk(" %08X", aty_ld_lcd(i, par));
1434 for (i = 0; i < 64; i++) {
1435 if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1436 printk(" %08X", aty_ld_lcd(i, par));
1441 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1447 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1449 struct atyfb_par *par = (struct atyfb_par *) info->par;
1455 memcpy(&pll, &(par->pll), sizeof(pll));
1457 if((err = aty_var_to_crtc(info, var, &crtc)))
1460 pixclock = atyfb_get_pixclock(var, par);
1462 if (pixclock == 0) {
1463 if (!(var->activate & FB_ACTIVATE_TEST))
1464 PRINTKE("Invalid pixclock\n");
1467 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
1471 if (var->accel_flags & FB_ACCELF_TEXT)
1472 info->var.accel_flags = FB_ACCELF_TEXT;
1474 info->var.accel_flags = 0;
1476 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
1477 if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
1480 aty_crtc_to_var(&crtc, var);
1481 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1485 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1487 u32 xoffset = info->var.xoffset;
1488 u32 yoffset = info->var.yoffset;
1489 u32 vxres = par->crtc.vxres;
1490 u32 bpp = info->var.bits_per_pixel;
1492 par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
1497 * Open/Release the frame buffer device
1500 static int atyfb_open(struct fb_info *info, int user)
1502 struct atyfb_par *par = (struct atyfb_par *) info->par;
1513 static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp)
1515 struct atyfb_par *par = dev_id;
1519 spin_lock(&par->int_lock);
1521 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1523 if (int_cntl & CRTC_VBLANK_INT) {
1524 /* clear interrupt */
1525 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
1526 par->vblank.count++;
1527 if (par->vblank.pan_display) {
1528 par->vblank.pan_display = 0;
1529 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1531 wake_up_interruptible(&par->vblank.wait);
1535 spin_unlock(&par->int_lock);
1537 return IRQ_RETVAL(handled);
1540 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1544 if (!test_and_set_bit(0, &par->irq_flags)) {
1545 if (request_irq(par->irq, aty_irq, SA_SHIRQ, "atyfb", par)) {
1546 clear_bit(0, &par->irq_flags);
1549 spin_lock_irq(&par->int_lock);
1550 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1551 /* clear interrupt */
1552 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1553 /* enable interrupt */
1554 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1555 spin_unlock_irq(&par->int_lock);
1556 } else if (reenable) {
1557 spin_lock_irq(&par->int_lock);
1558 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1559 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1560 printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
1561 /* re-enable interrupt */
1562 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
1564 spin_unlock_irq(&par->int_lock);
1570 static int aty_disable_irq(struct atyfb_par *par)
1574 if (test_and_clear_bit(0, &par->irq_flags)) {
1575 if (par->vblank.pan_display) {
1576 par->vblank.pan_display = 0;
1577 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1579 spin_lock_irq(&par->int_lock);
1580 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1581 /* disable interrupt */
1582 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
1583 spin_unlock_irq(&par->int_lock);
1584 free_irq(par->irq, par);
1590 static int atyfb_release(struct fb_info *info, int user)
1592 struct atyfb_par *par = (struct atyfb_par *) info->par;
1599 int was_mmaped = par->mmaped;
1604 struct fb_var_screeninfo var;
1606 /* Now reset the default display config, we have no
1607 * idea what the program(s) which mmap'd the chip did
1608 * to the configuration, nor whether it restored it
1613 var.accel_flags &= ~FB_ACCELF_TEXT;
1615 var.accel_flags |= FB_ACCELF_TEXT;
1616 if (var.yres == var.yres_virtual) {
1617 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1618 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
1619 if (var.yres_virtual < var.yres)
1620 var.yres_virtual = var.yres;
1624 aty_disable_irq(par);
1631 * Pan or Wrap the Display
1633 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1636 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1638 struct atyfb_par *par = (struct atyfb_par *) info->par;
1639 u32 xres, yres, xoffset, yoffset;
1641 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1642 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1643 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1645 xoffset = (var->xoffset + 7) & ~7;
1646 yoffset = var->yoffset;
1647 if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres)
1649 info->var.xoffset = xoffset;
1650 info->var.yoffset = yoffset;
1654 set_off_pitch(par, info);
1655 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1656 par->vblank.pan_display = 1;
1658 par->vblank.pan_display = 0;
1659 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1665 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1667 struct aty_interrupt *vbl;
1679 ret = aty_enable_irq(par, 0);
1684 ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
1689 aty_enable_irq(par, 1);
1698 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
1699 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
1705 u8 mclk_post_div; /* 1,2,3,4,8 */
1706 u8 mclk_fb_mult; /* 2 or 4 */
1707 u8 xclk_post_div; /* 1,2,3,4,8 */
1709 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
1710 u32 dsp_xclks_per_row; /* 0-16383 */
1711 u32 dsp_loop_latency; /* 0-15 */
1712 u32 dsp_precision; /* 0-7 */
1713 u32 dsp_on; /* 0-2047 */
1714 u32 dsp_off; /* 0-2047 */
1717 #define ATYIO_FEATR 0x41545902 /* ATY\02 */
1718 #define ATYIO_FEATW 0x41545903 /* ATY\03 */
1721 #ifndef FBIO_WAITFORVSYNC
1722 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
1725 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
1726 u_long arg, struct fb_info *info)
1728 struct atyfb_par *par = (struct atyfb_par *) info->par;
1730 struct fbtype fbtyp;
1736 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1737 fbtyp.fb_width = par->crtc.vxres;
1738 fbtyp.fb_height = par->crtc.vyres;
1739 fbtyp.fb_depth = info->var.bits_per_pixel;
1740 fbtyp.fb_cmsize = info->cmap.len;
1741 fbtyp.fb_size = info->fix.smem_len;
1742 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp)))
1745 #endif /* __sparc__ */
1747 case FBIO_WAITFORVSYNC:
1751 if (get_user(crtc, (__u32 __user *) arg))
1754 return aty_waitforvblank(par, crtc);
1758 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1760 if (M64_HAS(INTEGRATED)) {
1762 union aty_pll *pll = &(par->pll);
1763 u32 dsp_config = pll->ct.dsp_config;
1764 u32 dsp_on_off = pll->ct.dsp_on_off;
1765 clk.ref_clk_per = par->ref_clk_per;
1766 clk.pll_ref_div = pll->ct.pll_ref_div;
1767 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1768 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1769 clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1770 clk.xclk_post_div = pll->ct.xclk_post_div_real;
1771 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1772 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1773 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1774 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1775 clk.dsp_precision = (dsp_config >> 20) & 7;
1776 clk.dsp_off = dsp_on_off & 0x7ff;
1777 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1778 if (copy_to_user((struct atyclk __user *) arg, &clk,
1785 if (M64_HAS(INTEGRATED)) {
1787 union aty_pll *pll = &(par->pll);
1788 if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk)))
1790 par->ref_clk_per = clk.ref_clk_per;
1791 pll->ct.pll_ref_div = clk.pll_ref_div;
1792 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1793 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1794 pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1795 pll->ct.xclk_post_div_real = clk.xclk_post_div;
1796 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1797 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1798 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1799 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20);
1800 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16);
1801 /*aty_calc_pll_ct(info, &pll->ct);*/
1802 aty_set_pll_ct(info, pll);
1807 if (get_user(par->features, (u32 __user *) arg))
1811 if (put_user(par->features, (u32 __user *) arg))
1814 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1821 static int atyfb_sync(struct fb_info *info)
1823 struct atyfb_par *par = (struct atyfb_par *) info->par;
1825 if (par->blitter_may_be_busy)
1831 static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
1833 struct atyfb_par *par = (struct atyfb_par *) info->par;
1834 unsigned int size, page, map_size = 0;
1835 unsigned long map_offset = 0;
1842 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1845 off = vma->vm_pgoff << PAGE_SHIFT;
1846 size = vma->vm_end - vma->vm_start;
1848 /* To stop the swapper from even considering these pages. */
1849 vma->vm_flags |= (VM_IO | VM_RESERVED);
1851 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1852 ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1853 off += 0x8000000000000000UL;
1855 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
1857 /* Each page, see which map applies */
1858 for (page = 0; page < size;) {
1860 for (i = 0; par->mmap_map[i].size; i++) {
1861 unsigned long start = par->mmap_map[i].voff;
1862 unsigned long end = start + par->mmap_map[i].size;
1863 unsigned long offset = off + page;
1870 map_size = par->mmap_map[i].size - (offset - start);
1872 par->mmap_map[i].poff + (offset - start);
1879 if (page + map_size > size)
1880 map_size = size - page;
1882 pgprot_val(vma->vm_page_prot) &=
1883 ~(par->mmap_map[i].prot_mask);
1884 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1886 if (remap_pfn_range(vma, vma->vm_start + page,
1887 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1908 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1912 for (i = 0; i < 256; i++) {
1913 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1914 if (M64_HAS(EXTRA_BRIGHT))
1916 aty_st_8(DAC_CNTL, tmp, par);
1917 aty_st_8(DAC_MASK, 0xff, par);
1919 writeb(i, &par->aty_cmap_regs->rindex);
1920 atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
1921 atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
1922 atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
1923 writeb(i, &par->aty_cmap_regs->windex);
1924 writeb(atyfb_save.r[1 - enter][i],
1925 &par->aty_cmap_regs->lut);
1926 writeb(atyfb_save.g[1 - enter][i],
1927 &par->aty_cmap_regs->lut);
1928 writeb(atyfb_save.b[1 - enter][i],
1929 &par->aty_cmap_regs->lut);
1933 static void atyfb_palette(int enter)
1935 struct atyfb_par *par;
1936 struct fb_info *info;
1939 for (i = 0; i < FB_MAX; i++) {
1940 info = registered_fb[i];
1941 if (info && info->fbops == &atyfb_ops) {
1942 par = (struct atyfb_par *) info->par;
1944 atyfb_save_palette(par, enter);
1946 atyfb_save.yoffset = info->var.yoffset;
1947 info->var.yoffset = 0;
1948 set_off_pitch(par, info);
1950 info->var.yoffset = atyfb_save.yoffset;
1951 set_off_pitch(par, info);
1953 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1958 #endif /* __sparc__ */
1962 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1964 /* Power management routines. Those are used for PowerBook sleep.
1966 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1971 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1972 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1973 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1974 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1980 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1981 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1983 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1985 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1986 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1989 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1991 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1993 if ((--timeout) == 0)
1995 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
1999 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2000 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2003 pm |= (PWR_BLON | AUTO_PWR_UP);
2004 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2005 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2008 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2010 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2012 if ((--timeout) == 0)
2014 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2018 return timeout ? 0 : -EIO;
2021 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2023 struct fb_info *info = pci_get_drvdata(pdev);
2024 struct atyfb_par *par = (struct atyfb_par *) info->par;
2026 #ifndef CONFIG_PPC_PMAC
2027 /* HACK ALERT ! Once I find a proper way to say to each driver
2028 * individually what will happen with it's PCI slot, I'll change
2029 * that. On laptops, the AGP slot is just unclocked, so D2 is
2030 * expected, while on desktops, the card is powered off
2033 #endif /* CONFIG_PPC_PMAC */
2035 if (state.event == pdev->dev.power.power_state.event)
2038 acquire_console_sem();
2040 fb_set_suspend(info, 1);
2042 /* Idle & reset engine */
2044 aty_reset_engine(par);
2046 /* Blank display and LCD */
2047 atyfb_blank(FB_BLANK_POWERDOWN, info);
2050 par->lock_blank = 1;
2052 /* Set chip to "suspend" mode */
2053 if (aty_power_mgmt(1, par)) {
2055 par->lock_blank = 0;
2056 atyfb_blank(FB_BLANK_UNBLANK, info);
2057 fb_set_suspend(info, 0);
2058 release_console_sem();
2062 release_console_sem();
2064 pdev->dev.power.power_state = state;
2069 static int atyfb_pci_resume(struct pci_dev *pdev)
2071 struct fb_info *info = pci_get_drvdata(pdev);
2072 struct atyfb_par *par = (struct atyfb_par *) info->par;
2074 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2077 acquire_console_sem();
2079 if (pdev->dev.power.power_state.event == 2)
2080 aty_power_mgmt(0, par);
2083 /* Restore display */
2084 atyfb_set_par(info);
2087 fb_set_suspend(info, 0);
2090 par->lock_blank = 0;
2091 atyfb_blank(FB_BLANK_UNBLANK, info);
2093 release_console_sem();
2095 pdev->dev.power.power_state = PMSG_ON;
2100 #endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */
2102 #ifdef CONFIG_PMAC_BACKLIGHT
2105 * LCD backlight control
2108 static int backlight_conv[] = {
2109 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
2110 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
2113 static int aty_set_backlight_enable(int on, int level, void *data)
2115 struct fb_info *info = (struct fb_info *) data;
2116 struct atyfb_par *par = (struct atyfb_par *) info->par;
2117 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2119 reg |= (BLMOD_EN | BIASMOD_EN);
2120 if (on && level > BACKLIGHT_OFF) {
2121 reg &= ~BIAS_MOD_LEVEL_MASK;
2122 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
2124 reg &= ~BIAS_MOD_LEVEL_MASK;
2125 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
2127 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2131 static int aty_set_backlight_level(int level, void *data)
2133 return aty_set_backlight_enable(1, level, data);
2136 static struct backlight_controller aty_backlight_controller = {
2137 aty_set_backlight_enable,
2138 aty_set_backlight_level
2140 #endif /* CONFIG_PMAC_BACKLIGHT */
2142 static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2144 const int ragepro_tbl[] = {
2145 44, 50, 55, 66, 75, 80, 100
2147 const int ragexl_tbl[] = {
2148 50, 66, 75, 83, 90, 95, 100, 105,
2149 110, 115, 120, 125, 133, 143, 166
2151 const int *refresh_tbl;
2154 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2155 refresh_tbl = ragexl_tbl;
2156 size = sizeof(ragexl_tbl)/sizeof(int);
2158 refresh_tbl = ragepro_tbl;
2159 size = sizeof(ragepro_tbl)/sizeof(int);
2162 for (i=0; i < size; i++) {
2163 if (xclk < refresh_tbl[i])
2166 par->mem_refresh_rate = i;
2173 static struct fb_info *fb_list = NULL;
2175 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2176 static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2177 struct fb_var_screeninfo *var)
2181 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2183 var->xres = var->xres_virtual = par->lcd_hdisp;
2184 var->right_margin = par->lcd_right_margin;
2185 var->left_margin = par->lcd_hblank_len -
2186 (par->lcd_right_margin + par->lcd_hsync_dly +
2187 par->lcd_hsync_len);
2188 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2189 var->yres = var->yres_virtual = par->lcd_vdisp;
2190 var->lower_margin = par->lcd_lower_margin;
2191 var->upper_margin = par->lcd_vblank_len -
2192 (par->lcd_lower_margin + par->lcd_vsync_len);
2193 var->vsync_len = par->lcd_vsync_len;
2194 var->pixclock = par->lcd_pixclock;
2200 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2202 static int __init aty_init(struct fb_info *info, const char *name)
2204 struct atyfb_par *par = (struct atyfb_par *) info->par;
2205 const char *ramname = NULL, *xtal;
2206 int gtb_memsize, has_var = 0;
2207 struct fb_var_screeninfo var;
2210 #if defined(CONFIG_PPC)
2214 init_waitqueue_head(&par->vblank.wait);
2215 spin_lock_init(&par->int_lock);
2217 par->aty_cmap_regs =
2218 (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0);
2220 #ifdef CONFIG_PPC_PMAC
2221 /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2222 * and set the frequency manually. */
2223 if (machine_is_compatible("PowerBook2,1")) {
2224 par->pll_limits.mclk = 70;
2225 par->pll_limits.xclk = 53;
2229 par->pll_limits.pll_max = pll;
2231 par->pll_limits.mclk = mclk;
2233 par->pll_limits.xclk = xclk;
2235 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2236 par->pll_per = 1000000/par->pll_limits.pll_max;
2237 par->mclk_per = 1000000/par->pll_limits.mclk;
2238 par->xclk_per = 1000000/par->pll_limits.xclk;
2240 par->ref_clk_per = 1000000000000ULL / 14318180;
2243 #ifdef CONFIG_FB_ATY_GX
2244 if (!M64_HAS(INTEGRATED)) {
2246 u8 dac_type, dac_subtype, clk_type;
2247 stat0 = aty_ld_le32(CONFIG_STAT0, par);
2248 par->bus_type = (stat0 >> 0) & 0x07;
2249 par->ram_type = (stat0 >> 3) & 0x07;
2250 ramname = aty_gx_ram[par->ram_type];
2251 /* FIXME: clockchip/RAMDAC probing? */
2252 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2254 clk_type = CLK_ATI18818_1;
2255 dac_type = (stat0 >> 9) & 0x07;
2256 if (dac_type == 0x07)
2257 dac_subtype = DAC_ATT20C408;
2259 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2261 dac_type = DAC_IBMRGB514;
2262 dac_subtype = DAC_IBMRGB514;
2263 clk_type = CLK_IBMRGB514;
2265 switch (dac_subtype) {
2267 par->dac_ops = &aty_dac_ibm514;
2269 case DAC_ATI68860_B:
2270 case DAC_ATI68860_C:
2271 par->dac_ops = &aty_dac_ati68860b;
2275 par->dac_ops = &aty_dac_att21c498;
2278 PRINTKI("aty_init: DAC type not implemented yet!\n");
2279 par->dac_ops = &aty_dac_unsupported;
2283 case CLK_ATI18818_1:
2284 par->pll_ops = &aty_pll_ati18818_1;
2287 par->pll_ops = &aty_pll_stg1703;
2290 par->pll_ops = &aty_pll_ch8398;
2293 par->pll_ops = &aty_pll_att20c408;
2296 par->pll_ops = &aty_pll_ibm514;
2299 PRINTKI("aty_init: CLK type not implemented yet!");
2300 par->pll_ops = &aty_pll_unsupported;
2304 #endif /* CONFIG_FB_ATY_GX */
2305 #ifdef CONFIG_FB_ATY_CT
2306 if (M64_HAS(INTEGRATED)) {
2307 par->dac_ops = &aty_dac_ct;
2308 par->pll_ops = &aty_pll_ct;
2309 par->bus_type = PCI;
2310 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
2311 ramname = aty_ct_ram[par->ram_type];
2312 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2313 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2314 par->pll_limits.mclk = 63;
2317 if (M64_HAS(GTB_DSP)
2318 && (pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par))) {
2320 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2321 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2326 if (diff2 < diff1) {
2327 par->ref_clk_per = 1000000000000ULL / 29498928;
2331 #endif /* CONFIG_FB_ATY_CT */
2333 /* save previous video mode */
2334 aty_get_crtc(par, &saved_crtc);
2335 if(par->pll_ops->get_pll)
2336 par->pll_ops->get_pll(info, &saved_pll);
2338 i = aty_ld_le32(MEM_CNTL, par);
2339 gtb_memsize = M64_HAS(GTB_DSP);
2341 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
2343 info->fix.smem_len = 0x80000;
2346 info->fix.smem_len = 0x100000;
2348 case MEM_SIZE_2M_GTB:
2349 info->fix.smem_len = 0x200000;
2351 case MEM_SIZE_4M_GTB:
2352 info->fix.smem_len = 0x400000;
2354 case MEM_SIZE_6M_GTB:
2355 info->fix.smem_len = 0x600000;
2357 case MEM_SIZE_8M_GTB:
2358 info->fix.smem_len = 0x800000;
2361 info->fix.smem_len = 0x80000;
2363 switch (i & MEM_SIZE_ALIAS) {
2365 info->fix.smem_len = 0x80000;
2368 info->fix.smem_len = 0x100000;
2371 info->fix.smem_len = 0x200000;
2374 info->fix.smem_len = 0x400000;
2377 info->fix.smem_len = 0x600000;
2380 info->fix.smem_len = 0x800000;
2383 info->fix.smem_len = 0x80000;
2386 if (M64_HAS(MAGIC_VRAM_SIZE)) {
2387 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
2388 info->fix.smem_len += 0x400000;
2392 info->fix.smem_len = vram * 1024;
2393 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2394 if (info->fix.smem_len <= 0x80000)
2396 else if (info->fix.smem_len <= 0x100000)
2398 else if (info->fix.smem_len <= 0x200000)
2399 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2400 else if (info->fix.smem_len <= 0x400000)
2401 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2402 else if (info->fix.smem_len <= 0x600000)
2403 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2405 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2406 aty_st_le32(MEM_CNTL, i, par);
2410 * Reg Block 0 (CT-compatible block) is at mmio_start
2411 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2414 info->fix.mmio_len = 0x400;
2415 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2416 } else if (M64_HAS(CT)) {
2417 info->fix.mmio_len = 0x400;
2418 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2419 } else if (M64_HAS(VT)) {
2420 info->fix.mmio_start -= 0x400;
2421 info->fix.mmio_len = 0x800;
2422 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2424 info->fix.mmio_start -= 0x400;
2425 info->fix.mmio_len = 0x800;
2426 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2429 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2430 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
2431 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
2432 par->pll_limits.mclk, par->pll_limits.xclk);
2434 #if defined(DEBUG) && defined(CONFIG_ATY_CT)
2435 if (M64_HAS(INTEGRATED)) {
2437 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
2438 "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
2439 "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n"
2441 aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
2442 aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
2443 aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
2444 aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par));
2445 for (i = 0; i < 40; i++)
2446 printk(" %02x", aty_ld_pll_ct(i, par));
2450 if(par->pll_ops->init_pll)
2451 par->pll_ops->init_pll(info, &par->pll);
2454 * Last page of 8 MB (4 MB on ISA) aperture is MMIO
2455 * FIXME: we should use the auxiliary aperture instead so we can access
2456 * the full 8 MB of video RAM on 8 MB boards
2459 if (!par->aux_start &&
2460 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2461 info->fix.smem_len -= GUI_RESERVE;
2464 * Disable register access through the linear aperture
2465 * if the auxiliary aperture is used so we can access
2466 * the full 8 MB of video RAM on 8 MB boards.
2469 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2472 par->mtrr_aper = -1;
2475 /* Cover the whole resource. */
2476 par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1);
2477 if (par->mtrr_aper >= 0 && !par->aux_start) {
2478 /* Make a hole for mmio. */
2479 par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE,
2480 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1);
2481 if (par->mtrr_reg < 0) {
2482 mtrr_del(par->mtrr_aper, 0, 0);
2483 par->mtrr_aper = -1;
2489 info->fbops = &atyfb_ops;
2490 info->pseudo_palette = pseudo_palette;
2491 info->flags = FBINFO_FLAG_DEFAULT;
2493 #ifdef CONFIG_PMAC_BACKLIGHT
2494 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2495 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2496 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2497 | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2498 } else if (M64_HAS(MOBIL_BUS))
2499 register_backlight_controller(&aty_backlight_controller, info, "ati");
2500 #endif /* CONFIG_PMAC_BACKLIGHT */
2502 memset(&var, 0, sizeof(var));
2504 if (_machine == _MACH_Pmac) {
2506 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2507 * applies to all Mac video cards
2510 if (mac_find_mode(&var, info, mode, 8))
2513 if (default_vmode == VMODE_CHOOSE) {
2514 if (M64_HAS(G3_PB_1024x768))
2515 /* G3 PowerBook with 1024x768 LCD */
2516 default_vmode = VMODE_1024_768_60;
2517 else if (machine_is_compatible("iMac"))
2518 default_vmode = VMODE_1024_768_75;
2519 else if (machine_is_compatible
2521 /* iBook with 800x600 LCD */
2522 default_vmode = VMODE_800_600_60;
2524 default_vmode = VMODE_640_480_67;
2525 sense = read_aty_sense(par);
2526 PRINTKI("monitor sense=%x, mode %d\n",
2527 sense, mac_map_monitor_sense(sense));
2529 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2530 default_vmode = VMODE_640_480_60;
2531 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2532 default_cmode = CMODE_8;
2533 if (!mac_vmode_to_var(default_vmode, default_cmode,
2539 #endif /* !CONFIG_PPC */
2541 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2542 if (!atyfb_get_timings_from_lcd(par, &var))
2546 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2553 var.accel_flags &= ~FB_ACCELF_TEXT;
2555 var.accel_flags |= FB_ACCELF_TEXT;
2557 if (comp_sync != -1) {
2559 var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2561 var.sync |= FB_SYNC_COMP_HIGH_ACT;
2564 if (var.yres == var.yres_virtual) {
2565 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2566 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2567 if (var.yres_virtual < var.yres)
2568 var.yres_virtual = var.yres;
2571 if (atyfb_check_var(&var, info)) {
2572 PRINTKE("can't set default video mode\n");
2577 atyfb_save_palette(par, 0);
2580 #ifdef CONFIG_FB_ATY_CT
2581 if (!noaccel && M64_HAS(INTEGRATED))
2582 aty_init_cursor(info);
2583 #endif /* CONFIG_FB_ATY_CT */
2586 fb_alloc_cmap(&info->cmap, 256, 0);
2588 if (register_framebuffer(info) < 0)
2593 PRINTKI("fb%d: %s frame buffer device on %s\n",
2594 info->node, info->fix.id, name);
2598 /* restore video mode */
2599 aty_set_crtc(par, &saved_crtc);
2600 par->pll_ops->set_pll(info, &saved_pll);
2603 if (par->mtrr_reg >= 0) {
2604 mtrr_del(par->mtrr_reg, 0, 0);
2607 if (par->mtrr_aper >= 0) {
2608 mtrr_del(par->mtrr_aper, 0, 0);
2609 par->mtrr_aper = -1;
2616 static int __init store_video_par(char *video_str, unsigned char m64_num)
2619 unsigned long vmembase, size, guiregbase;
2621 PRINTKI("store_video_par() '%s' \n", video_str);
2623 if (!(p = strsep(&video_str, ";")) || !*p)
2624 goto mach64_invalid;
2625 vmembase = simple_strtoul(p, NULL, 0);
2626 if (!(p = strsep(&video_str, ";")) || !*p)
2627 goto mach64_invalid;
2628 size = simple_strtoul(p, NULL, 0);
2629 if (!(p = strsep(&video_str, ";")) || !*p)
2630 goto mach64_invalid;
2631 guiregbase = simple_strtoul(p, NULL, 0);
2633 phys_vmembase[m64_num] = vmembase;
2634 phys_size[m64_num] = size;
2635 phys_guiregbase[m64_num] = guiregbase;
2636 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2641 phys_vmembase[m64_num] = 0;
2644 #endif /* CONFIG_ATARI */
2647 * Blank the display.
2650 static int atyfb_blank(int blank, struct fb_info *info)
2652 struct atyfb_par *par = (struct atyfb_par *) info->par;
2655 if (par->lock_blank || par->asleep)
2658 #ifdef CONFIG_PMAC_BACKLIGHT
2659 if ((_machine == _MACH_Pmac) && blank)
2660 set_backlight_enable(0);
2661 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2662 if (par->lcd_table && blank &&
2663 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2664 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2666 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2670 gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
2672 case FB_BLANK_UNBLANK:
2673 gen_cntl &= ~(0x4c);
2675 case FB_BLANK_NORMAL:
2678 case FB_BLANK_VSYNC_SUSPEND:
2681 case FB_BLANK_HSYNC_SUSPEND:
2684 case FB_BLANK_POWERDOWN:
2688 aty_st_8(CRTC_GEN_CNTL, gen_cntl, par);
2690 #ifdef CONFIG_PMAC_BACKLIGHT
2691 if ((_machine == _MACH_Pmac) && !blank)
2692 set_backlight_enable(1);
2693 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2694 if (par->lcd_table && !blank &&
2695 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2696 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2698 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2705 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2706 const struct atyfb_par *par)
2709 out_8(&par->aty_cmap_regs->windex, regno);
2710 out_8(&par->aty_cmap_regs->lut, red);
2711 out_8(&par->aty_cmap_regs->lut, green);
2712 out_8(&par->aty_cmap_regs->lut, blue);
2714 writeb(regno, &par->aty_cmap_regs->windex);
2715 writeb(red, &par->aty_cmap_regs->lut);
2716 writeb(green, &par->aty_cmap_regs->lut);
2717 writeb(blue, &par->aty_cmap_regs->lut);
2722 * Set a single color register. The values supplied are already
2723 * rounded down to the hardware's capabilities (according to the
2724 * entries in the var structure). Return != 0 for invalid regno.
2725 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
2728 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2729 u_int transp, struct fb_info *info)
2731 struct atyfb_par *par = (struct atyfb_par *) info->par;
2733 u32 *pal = info->pseudo_palette;
2735 depth = info->var.bits_per_pixel;
2737 depth = (info->var.green.length == 5) ? 15 : 16;
2743 (depth == 16 && regno > 63) ||
2744 (depth == 15 && regno > 31))
2751 par->palette[regno].red = red;
2752 par->palette[regno].green = green;
2753 par->palette[regno].blue = blue;
2758 pal[regno] = (regno << 10) | (regno << 5) | regno;
2761 pal[regno] = (regno << 11) | (regno << 5) | regno;
2764 pal[regno] = (regno << 16) | (regno << 8) | regno;
2767 i = (regno << 8) | regno;
2768 pal[regno] = (i << 16) | i;
2773 i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2774 if (M64_HAS(EXTRA_BRIGHT))
2775 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
2776 aty_st_8(DAC_CNTL, i, par);
2777 aty_st_8(DAC_MASK, 0xff, par);
2779 if (M64_HAS(INTEGRATED)) {
2782 aty_st_pal(regno << 3, red,
2783 par->palette[regno<<1].green,
2785 red = par->palette[regno>>1].red;
2786 blue = par->palette[regno>>1].blue;
2788 } else if (depth == 15) {
2790 for(i = 0; i < 8; i++) {
2791 aty_st_pal(regno + i, red, green, blue, par);
2795 aty_st_pal(regno, red, green, blue, par);
2804 extern void (*prom_palette) (int);
2806 static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2807 struct fb_info *info, unsigned long addr)
2809 extern int con_is_present(void);
2811 struct atyfb_par *par = info->par;
2812 struct pcidev_cookie *pcp;
2814 int node, len, i, j, ret;
2817 /* Do not attach when we have a serial console. */
2818 if (!con_is_present())
2822 * Map memory-mapped registers.
2824 par->ati_regbase = (void *)addr + 0x7ffc00UL;
2825 info->fix.mmio_start = addr + 0x7ffc00UL;
2828 * Map in big-endian aperture.
2830 info->screen_base = (char *) (addr + 0x800000UL);
2831 info->fix.smem_start = addr + 0x800000UL;
2834 * Figure mmap addresses from PCI config space.
2835 * Split Framebuffer in big- and little-endian halfs.
2837 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2841 par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
2842 if (!par->mmap_map) {
2843 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2846 memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
2848 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2849 struct resource *rp = &pdev->resource[i];
2850 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2856 io = (rp->flags & IORESOURCE_IO);
2858 size = rp->end - base + 1;
2860 pci_read_config_dword(pdev, breg, &pbase);
2866 * Map the framebuffer a second time, this time without
2867 * the braindead _PAGE_IE setting. This is used by the
2868 * fixed Xserver, but we need to maintain the old mapping
2869 * to stay compatible with older ones...
2872 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
2873 par->mmap_map[j].poff = base & PAGE_MASK;
2874 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2875 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2876 par->mmap_map[j].prot_flag = _PAGE_E;
2881 * Here comes the old framebuffer mapping with _PAGE_IE
2882 * set for the big endian half of the framebuffer...
2885 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
2886 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
2887 par->mmap_map[j].size = 0x800000;
2888 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2889 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
2894 par->mmap_map[j].voff = pbase & PAGE_MASK;
2895 par->mmap_map[j].poff = base & PAGE_MASK;
2896 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2897 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2898 par->mmap_map[j].prot_flag = _PAGE_E;
2902 if((ret = correct_chipset(par)))
2905 if (IS_XL(pdev->device)) {
2907 * Fix PROMs idea of MEM_CNTL settings...
2909 mem = aty_ld_le32(MEM_CNTL, par);
2910 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
2911 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
2912 switch (mem & 0x0f) {
2914 mem = (mem & ~(0x0f)) | 2;
2917 mem = (mem & ~(0x0f)) | 3;
2920 mem = (mem & ~(0x0f)) | 4;
2923 mem = (mem & ~(0x0f)) | 5;
2928 if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
2929 mem &= ~(0x00700000);
2931 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
2932 aty_st_le32(MEM_CNTL, mem, par);
2936 * If this is the console device, we will set default video
2937 * settings to what the PROM left us with.
2939 node = prom_getchild(prom_root_node);
2940 node = prom_searchsiblings(node, "aliases");
2942 len = prom_getproperty(node, "screen", prop, sizeof(prop));
2945 node = prom_finddevice(prop);
2950 pcp = pdev->sysdata;
2951 if (node == pcp->prom_node) {
2952 struct fb_var_screeninfo *var = &default_var;
2953 unsigned int N, P, Q, M, T, R;
2954 u32 v_total, h_total;
2959 crtc.vxres = prom_getintdefault(node, "width", 1024);
2960 crtc.vyres = prom_getintdefault(node, "height", 768);
2961 var->bits_per_pixel = prom_getintdefault(node, "depth", 8);
2962 var->xoffset = var->yoffset = 0;
2963 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
2964 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
2965 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
2966 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
2967 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2968 aty_crtc_to_var(&crtc, var);
2970 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin;
2971 v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
2974 * Read the PLL to figure actual Refresh Rate.
2976 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
2977 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
2978 for (i = 0; i < 16; i++)
2979 pll_regs[i] = aty_ld_pll_ct(i, par);
2982 * PLL Reference Divider M:
2987 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
2989 N = pll_regs[7 + (clock_cntl & 3)];
2992 * PLL Post Divider P (Dependant on CLOCK_CNTL):
2994 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3008 * where R is XTALIN (= 14318 or 29498 kHz).
3010 if (IS_XL(pdev->device))
3017 default_var.pixclock = 1000000000 / T;
3023 #else /* __sparc__ */
3026 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3027 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3029 u32 driv_inf_tab, sig;
3032 /* To support an LCD panel, we should know it's dimensions and
3033 * it's desired pixel clock.
3034 * There are two ways to do it:
3035 * - Check the startup video mode and calculate the panel
3036 * size from it. This is unreliable.
3037 * - Read it from the driver information table in the video BIOS.
3039 /* Address of driver information table is at offset 0x78. */
3040 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3042 /* Check for the driver information table signature. */
3043 sig = (*(u32 *)driv_inf_tab);
3044 if ((sig == 0x54504c24) || /* Rage LT pro */
3045 (sig == 0x544d5224) || /* Rage mobility */
3046 (sig == 0x54435824) || /* Rage XC */
3047 (sig == 0x544c5824)) { /* Rage XL */
3048 PRINTKI("BIOS contains driver information table.\n");
3049 lcd_ofs = (*(u16 *)(driv_inf_tab + 10));
3052 par->lcd_table = bios_base + lcd_ofs;
3056 if (par->lcd_table != 0) {
3059 char refresh_rates_buf[100];
3060 int id, tech, f, i, m, default_refresh_rate;
3065 u16 width, height, panel_type, refresh_rates;
3068 u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200};
3069 /* The most important information is the panel size at
3070 * offset 25 and 27, but there's some other nice information
3071 * which we print to the screen.
3073 id = *(u8 *)par->lcd_table;
3074 strncpy(model,(char *)par->lcd_table+1,24);
3077 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3078 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3079 panel_type = *(u16 *)(par->lcd_table+29);
3081 txtcolour = "colour";
3083 txtcolour = "monochrome";
3085 txtdual = "dual (split) ";
3088 tech = (panel_type>>2) & 63;
3091 txtmonitor = "passive matrix";
3094 txtmonitor = "active matrix";
3097 txtmonitor = "active addressed STN";
3103 txtmonitor = "plasma";
3106 txtmonitor = "unknown";
3108 format = *(u32 *)(par->lcd_table+57);
3109 if (tech == 0 || tech == 2) {
3110 switch (format & 7) {
3112 txtformat = "12 bit interface";
3115 txtformat = "16 bit interface";
3118 txtformat = "24 bit interface";
3121 txtformat = "unkown format";
3124 switch (format & 7) {
3126 txtformat = "8 colours";
3129 txtformat = "512 colours";
3132 txtformat = "4096 colours";
3135 txtformat = "262144 colours (LT mode)";
3138 txtformat = "16777216 colours";
3141 txtformat = "262144 colours (FDPI-2 mode)";
3144 txtformat = "unkown format";
3147 PRINTKI("%s%s %s monitor detected: %s\n",
3148 txtdual ,txtcolour, txtmonitor, model);
3149 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3150 id, width, height, txtformat);
3151 refresh_rates_buf[0] = 0;
3152 refresh_rates = *(u16 *)(par->lcd_table+62);
3155 for (i=0;i<16;i++) {
3156 if (refresh_rates & m) {
3158 sprintf(strbuf, "%d", lcd_refresh_rates[i]);
3161 sprintf(strbuf, ",%d", lcd_refresh_rates[i]);
3163 strcat(refresh_rates_buf,strbuf);
3167 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3168 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3169 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3170 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3171 /* We now need to determine the crtc parameters for the
3172 * LCD monitor. This is tricky, because they are not stored
3173 * individually in the BIOS. Instead, the BIOS contains a
3174 * table of display modes that work for this monitor.
3176 * The idea is that we search for a mode of the same dimensions
3177 * as the dimensions of the LCD monitor. Say our LCD monitor
3178 * is 800x600 pixels, we search for a 800x600 monitor.
3179 * The CRTC parameters we find here are the ones that we need
3180 * to use to simulate other resolutions on the LCD screen.
3182 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3183 while (*lcdmodeptr != 0) {
3185 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3186 modeptr = bios_base + *lcdmodeptr;
3188 mwidth = *((u16 *)(modeptr+0));
3189 mheight = *((u16 *)(modeptr+2));
3191 if (mwidth == width && mheight == height) {
3192 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3193 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3194 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3195 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3196 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3197 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3199 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3200 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3201 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3202 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3204 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3205 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3206 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3207 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3213 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3214 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3215 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3216 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3222 if (*lcdmodeptr == 0) {
3223 PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3224 /* To do: Switch to CRT if possible. */
3226 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3227 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3229 par->lcd_hdisp + par->lcd_right_margin,
3230 par->lcd_hdisp + par->lcd_right_margin
3231 + par->lcd_hsync_dly + par->lcd_hsync_len,
3234 par->lcd_vdisp + par->lcd_lower_margin,
3235 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3237 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
3239 par->lcd_hblank_len - (par->lcd_right_margin +
3240 par->lcd_hsync_dly + par->lcd_hsync_len),
3242 par->lcd_right_margin,
3244 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3246 par->lcd_lower_margin,
3247 par->lcd_vsync_len);
3251 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
3253 static int __devinit init_from_bios(struct atyfb_par *par)
3255 u32 bios_base, rom_addr;
3258 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3259 bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3261 /* The BIOS starts with 0xaa55. */
3262 if (*((u16 *)bios_base) == 0xaa55) {
3265 u16 rom_table_offset, freq_table_offset;
3266 PLL_BLOCK_MACH64 pll_block;
3268 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3270 /* check for frequncy table */
3271 bios_ptr = (u8*)bios_base;
3272 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3273 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3274 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3276 PRINTKI("BIOS frequency table:\n");
3277 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3278 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3279 pll_block.ref_freq, pll_block.ref_divider);
3280 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3281 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3282 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3284 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3285 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3286 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3287 par->pll_limits.ref_div = pll_block.ref_divider;
3288 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3289 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3290 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3291 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3292 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3293 aty_init_lcd(par, bios_base);
3297 PRINTKE("no BIOS frequency table found, use parameters\n");
3300 iounmap((void* __iomem )bios_base);
3304 #endif /* __i386__ */
3306 static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr)
3308 struct atyfb_par *par = info->par;
3310 unsigned long raddr;
3311 struct resource *rrp;
3314 raddr = addr + 0x7ff000UL;
3315 rrp = &pdev->resource[2];
3316 if ((rrp->flags & IORESOURCE_MEM) && request_mem_region(rrp->start, rrp->end - rrp->start + 1, "atyfb")) {
3317 par->aux_start = rrp->start;
3318 par->aux_size = rrp->end - rrp->start + 1;
3320 PRINTKI("using auxiliary register aperture\n");
3323 info->fix.mmio_start = raddr;
3324 par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
3325 if (par->ati_regbase == 0)
3328 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3329 par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3332 * Enable memory-space accesses using config-space
3335 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3336 if (!(tmp & PCI_COMMAND_MEMORY)) {
3337 tmp |= PCI_COMMAND_MEMORY;
3338 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3341 /* Use the big-endian aperture */
3345 /* Map in frame buffer */
3346 info->fix.smem_start = addr;
3347 info->screen_base = ioremap(addr, 0x800000);
3348 if (info->screen_base == NULL) {
3350 goto atyfb_setup_generic_fail;
3353 if((ret = correct_chipset(par)))
3354 goto atyfb_setup_generic_fail;
3356 if((ret = init_from_bios(par)))
3357 goto atyfb_setup_generic_fail;
3359 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3360 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3362 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3364 /* according to ATI, we should use clock 3 for acelerated mode */
3365 par->clk_wr_offset = 3;
3369 atyfb_setup_generic_fail:
3370 iounmap(par->ati_regbase);
3371 par->ati_regbase = NULL;
3375 #endif /* !__sparc__ */
3377 static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3379 unsigned long addr, res_start, res_size;
3380 struct fb_info *info;
3381 struct resource *rp;
3382 struct atyfb_par *par;
3383 int i, rc = -ENOMEM;
3385 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
3386 if (pdev->device == aty_chips[i].pci_id)
3392 /* Enable device in PCI config */
3393 if (pci_enable_device(pdev)) {
3394 PRINTKE("Cannot enable PCI device\n");
3398 /* Find which resource to use */
3399 rp = &pdev->resource[0];
3400 if (rp->flags & IORESOURCE_IO)
3401 rp = &pdev->resource[1];
3407 res_start = rp->start;
3408 res_size = rp->end - rp->start + 1;
3409 if (!request_mem_region (res_start, res_size, "atyfb"))
3412 /* Allocate framebuffer */
3413 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3415 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
3419 info->fix = atyfb_fix;
3420 info->device = &pdev->dev;
3421 par->pci_id = aty_chips[i].pci_id;
3422 par->res_start = res_start;
3423 par->res_size = res_size;
3424 par->irq = pdev->irq;
3426 /* Setup "info" structure */
3428 rc = atyfb_setup_sparc(pdev, info, addr);
3430 rc = atyfb_setup_generic(pdev, info, addr);
3433 goto err_release_mem;
3435 pci_set_drvdata(pdev, info);
3437 /* Init chip & register framebuffer */
3438 if (aty_init(info, "PCI"))
3439 goto err_release_io;
3443 prom_palette = atyfb_palette;
3446 * Add /dev/fb mmap values.
3448 par->mmap_map[0].voff = 0x8000000000000000UL;
3449 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3450 par->mmap_map[0].size = info->fix.smem_len;
3451 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3452 par->mmap_map[0].prot_flag = _PAGE_E;
3453 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3454 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3455 par->mmap_map[1].size = PAGE_SIZE;
3456 par->mmap_map[1].prot_mask = _PAGE_CACHE;
3457 par->mmap_map[1].prot_flag = _PAGE_E;
3458 #endif /* __sparc__ */
3464 kfree(par->mmap_map);
3466 if (par->ati_regbase)
3467 iounmap(par->ati_regbase);
3468 if (info->screen_base)
3469 iounmap(info->screen_base);
3473 release_mem_region(par->aux_start, par->aux_size);
3475 release_mem_region(par->res_start, par->res_size);
3476 framebuffer_release(info);
3481 #endif /* CONFIG_PCI */
3485 static int __devinit atyfb_atari_probe(void)
3487 struct aty_par *par;
3488 struct fb_info *info;
3492 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3493 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3494 !phys_guiregbase[m64_num]) {
3495 PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num);
3499 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3501 PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
3506 info->fix = atyfb_fix;
3508 par->irq = (unsigned int) -1; /* something invalid */
3511 * Map the video memory (physical address given) to somewhere in the
3512 * kernel address space.
3514 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
3515 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
3516 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3518 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */
3520 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3521 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3523 switch (clock_r & 0x003F) {
3525 par->clk_wr_offset = 3; /* */
3528 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
3531 par->clk_wr_offset = 1; /* */
3534 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
3538 if (aty_init(info, "ISA bus")) {
3539 framebuffer_release(info);
3540 /* This is insufficient! kernel_map has added two large chunks!! */
3546 #endif /* CONFIG_ATARI */
3548 static void __devexit atyfb_remove(struct fb_info *info)
3550 struct atyfb_par *par = (struct atyfb_par *) info->par;
3552 /* restore video mode */
3553 aty_set_crtc(par, &saved_crtc);
3554 par->pll_ops->set_pll(info, &saved_pll);
3556 unregister_framebuffer(info);
3559 if (par->mtrr_reg >= 0) {
3560 mtrr_del(par->mtrr_reg, 0, 0);
3563 if (par->mtrr_aper >= 0) {
3564 mtrr_del(par->mtrr_aper, 0, 0);
3565 par->mtrr_aper = -1;
3569 if (par->ati_regbase)
3570 iounmap(par->ati_regbase);
3571 if (info->screen_base)
3572 iounmap(info->screen_base);
3574 if (info->sprite.addr)
3575 iounmap(info->sprite.addr);
3579 kfree(par->mmap_map);
3582 release_mem_region(par->aux_start, par->aux_size);
3585 release_mem_region(par->res_start, par->res_size);
3587 framebuffer_release(info);
3592 static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3594 struct fb_info *info = pci_get_drvdata(pdev);
3600 * This driver uses its own matching table. That will be more difficult
3601 * to fix, so for now, we just match against any ATI ID and let the
3602 * probe() function find out what's up. That also mean we don't have
3603 * a module ID table though.
3605 static struct pci_device_id atyfb_pci_tbl[] = {
3606 { PCI_VENDOR_ID_ATI, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
3607 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 },
3611 static struct pci_driver atyfb_driver = {
3613 .id_table = atyfb_pci_tbl,
3614 .probe = atyfb_pci_probe,
3615 .remove = __devexit_p(atyfb_pci_remove),
3617 .suspend = atyfb_pci_suspend,
3618 .resume = atyfb_pci_resume,
3619 #endif /* CONFIG_PM */
3622 #endif /* CONFIG_PCI */
3625 static int __init atyfb_setup(char *options)
3629 if (!options || !*options)
3632 while ((this_opt = strsep(&options, ",")) != NULL) {
3633 if (!strncmp(this_opt, "noaccel", 7)) {
3636 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3639 } else if (!strncmp(this_opt, "vram:", 5))
3640 vram = simple_strtoul(this_opt + 5, NULL, 0);
3641 else if (!strncmp(this_opt, "pll:", 4))
3642 pll = simple_strtoul(this_opt + 4, NULL, 0);
3643 else if (!strncmp(this_opt, "mclk:", 5))
3644 mclk = simple_strtoul(this_opt + 5, NULL, 0);
3645 else if (!strncmp(this_opt, "xclk:", 5))
3646 xclk = simple_strtoul(this_opt+5, NULL, 0);
3647 else if (!strncmp(this_opt, "comp_sync:", 10))
3648 comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3650 else if (!strncmp(this_opt, "vmode:", 6)) {
3651 unsigned int vmode =
3652 simple_strtoul(this_opt + 6, NULL, 0);
3653 if (vmode > 0 && vmode <= VMODE_MAX)
3654 default_vmode = vmode;
3655 } else if (!strncmp(this_opt, "cmode:", 6)) {
3656 unsigned int cmode =
3657 simple_strtoul(this_opt + 6, NULL, 0);
3661 default_cmode = CMODE_8;
3665 default_cmode = CMODE_16;
3669 default_cmode = CMODE_32;
3676 * Why do we need this silly Mach64 argument?
3677 * We are already here because of mach64= so its redundant.
3679 else if (MACH_IS_ATARI
3680 && (!strncmp(this_opt, "Mach64:", 7))) {
3681 static unsigned char m64_num;
3682 static char mach64_str[80];
3683 strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3684 if (!store_video_par(mach64_str, m64_num)) {
3686 mach64_count = m64_num;
3697 static int __init atyfb_init(void)
3700 char *option = NULL;
3702 if (fb_get_options("atyfb", &option))
3704 atyfb_setup(option);
3707 pci_register_driver(&atyfb_driver);
3709 atyfb_atari_probe();
3714 static void __exit atyfb_exit(void)
3716 pci_unregister_driver(&atyfb_driver);
3719 module_init(atyfb_init);
3720 module_exit(atyfb_exit);
3722 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
3723 MODULE_LICENSE("GPL");
3724 module_param(noaccel, bool, 0);
3725 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
3726 module_param(vram, int, 0);
3727 MODULE_PARM_DESC(vram, "int: override size of video ram");
3728 module_param(pll, int, 0);
3729 MODULE_PARM_DESC(pll, "int: override video clock");
3730 module_param(mclk, int, 0);
3731 MODULE_PARM_DESC(mclk, "int: override memory clock");
3732 module_param(xclk, int, 0);
3733 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3734 module_param(comp_sync, int, 0);
3735 MODULE_PARM_DESC(comp_sync,
3736 "Set composite sync signal to low (0) or high (1)");
3737 module_param(mode, charp, 0);
3738 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3740 module_param(nomtrr, bool, 0);
3741 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");