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 { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0)
113 #define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0)
116 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
118 #define DPRINTK(fmt, args...)
121 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
122 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
124 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
125 static const u32 lt_lcd_regs[] = {
132 0, /* EXT_VERT_STRETCH */
137 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
139 if (M64_HAS(LT_LCD_REGS)) {
140 aty_st_le32(lt_lcd_regs[index], val, par);
144 /* write addr byte */
145 temp = aty_ld_le32(LCD_INDEX, par);
146 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
147 /* write the register value */
148 aty_st_le32(LCD_DATA, val, par);
152 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
154 if (M64_HAS(LT_LCD_REGS)) {
155 return aty_ld_le32(lt_lcd_regs[index], par);
159 /* write addr byte */
160 temp = aty_ld_le32(LCD_INDEX, par);
161 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
162 /* read the register value */
163 return aty_ld_le32(LCD_DATA, par);
166 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
168 #ifdef CONFIG_FB_ATY_GENERIC_LCD
172 * Reduce a fraction by factoring out the largest common divider of the
173 * fraction's numerator and denominator.
175 static void ATIReduceRatio(int *Numerator, int *Denominator)
177 int Multiplier, Divider, Remainder;
179 Multiplier = *Numerator;
180 Divider = *Denominator;
182 while ((Remainder = Multiplier % Divider))
184 Multiplier = Divider;
188 *Numerator /= Divider;
189 *Denominator /= Divider;
193 * The Hardware parameters for each card
196 struct aty_cmap_regs {
204 struct pci_mmap_map {
208 unsigned long prot_flag;
209 unsigned long prot_mask;
212 static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
214 .type = FB_TYPE_PACKED_PIXELS,
215 .visual = FB_VISUAL_PSEUDOCOLOR,
221 * Frame buffer device API
224 static int atyfb_open(struct fb_info *info, int user);
225 static int atyfb_release(struct fb_info *info, int user);
226 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
227 static int atyfb_set_par(struct fb_info *info);
228 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
229 u_int transp, struct fb_info *info);
230 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
231 static int atyfb_blank(int blank, struct fb_info *info);
232 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
233 u_long arg, struct fb_info *info);
234 extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
235 extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
236 extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
238 static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
240 static int atyfb_sync(struct fb_info *info);
246 static int aty_init(struct fb_info *info, const char *name);
248 static int store_video_par(char *videopar, unsigned char m64_num);
251 static struct crtc saved_crtc;
252 static union aty_pll saved_pll;
253 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
255 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
256 static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
257 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
258 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
260 static int read_aty_sense(const struct atyfb_par *par);
265 * Interface used by the world
268 static struct fb_var_screeninfo default_var = {
269 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
270 640, 480, 640, 480, 0, 0, 8, 0,
271 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
272 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
273 0, FB_VMODE_NONINTERLACED
276 static struct fb_videomode defmode = {
277 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
278 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
279 0, FB_VMODE_NONINTERLACED
282 static struct fb_ops atyfb_ops = {
283 .owner = THIS_MODULE,
284 .fb_open = atyfb_open,
285 .fb_release = atyfb_release,
286 .fb_check_var = atyfb_check_var,
287 .fb_set_par = atyfb_set_par,
288 .fb_setcolreg = atyfb_setcolreg,
289 .fb_pan_display = atyfb_pan_display,
290 .fb_blank = atyfb_blank,
291 .fb_ioctl = atyfb_ioctl,
292 .fb_fillrect = atyfb_fillrect,
293 .fb_copyarea = atyfb_copyarea,
294 .fb_imageblit = atyfb_imageblit,
295 .fb_cursor = soft_cursor,
297 .fb_mmap = atyfb_mmap,
299 .fb_sync = atyfb_sync,
310 static int comp_sync __initdata = -1;
314 static int default_vmode __initdata = VMODE_CHOOSE;
315 static int default_cmode __initdata = CMODE_CHOOSE;
317 module_param_named(vmode, default_vmode, int, 0);
318 MODULE_PARM_DESC(vmode, "int: video mode for mac");
319 module_param_named(cmode, default_cmode, int, 0);
320 MODULE_PARM_DESC(cmode, "int: color mode for mac");
324 static unsigned int mach64_count __initdata = 0;
325 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
326 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
327 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
330 /* top -> down is an evolution of mach64 chipset, any corrections? */
331 #define ATI_CHIP_88800GX (M64F_GX)
332 #define ATI_CHIP_88800CX (M64F_GX)
334 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
335 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
337 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
338 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
340 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
341 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
342 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
344 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
346 /* make sets shorter */
347 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
349 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
350 /*#define ATI_CHIP_264GTDVD ?*/
351 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
353 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
354 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
355 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
357 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
358 #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)
365 } aty_chips[] __devinitdata = {
366 #ifdef CONFIG_FB_ATY_GX
368 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX },
369 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX },
370 #endif /* CONFIG_FB_ATY_GX */
372 #ifdef CONFIG_FB_ATY_CT
373 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT },
374 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET },
375 { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT },
376 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT },
377 /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */
378 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB },
379 { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 },
381 { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT },
382 /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */
383 { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
385 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 },
387 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
388 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
389 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
390 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
392 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO },
393 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO },
394 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
395 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO },
396 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO },
398 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO },
399 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO },
400 { 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 },
401 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
402 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
404 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
405 { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
406 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
407 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL },
408 { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
409 { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
411 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
412 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
413 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
414 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
415 #endif /* CONFIG_FB_ATY_CT */
419 static int __devinit correct_chipset(struct atyfb_par *par)
427 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
428 if (par->pci_id == aty_chips[i].pci_id)
431 name = aty_chips[i].name;
432 par->pll_limits.pll_max = aty_chips[i].pll;
433 par->pll_limits.mclk = aty_chips[i].mclk;
434 par->pll_limits.xclk = aty_chips[i].xclk;
435 par->features = aty_chips[i].features;
437 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
438 type = chip_id & CFG_CHIP_TYPE;
439 rev = (chip_id & CFG_CHIP_REV) >> 24;
441 switch(par->pci_id) {
442 #ifdef CONFIG_FB_ATY_GX
443 case PCI_CHIP_MACH64GX:
447 case PCI_CHIP_MACH64CX:
452 #ifdef CONFIG_FB_ATY_CT
453 case PCI_CHIP_MACH64VT:
456 name = "ATI264VTA3 (Mach64 VT)";
457 par->pll_limits.pll_max = 170;
458 par->pll_limits.mclk = 67;
459 par->pll_limits.xclk = 67;
460 par->features = ATI_CHIP_264VT;
461 } else if(rev == 0x40) {
462 name = "ATI264VTA4 (Mach64 VT)";
463 par->pll_limits.pll_max = 200;
464 par->pll_limits.mclk = 67;
465 par->pll_limits.xclk = 67;
466 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
468 name = "ATI264VTB (Mach64 VT)";
469 par->pll_limits.pll_max = 200;
470 par->pll_limits.mclk = 67;
471 par->pll_limits.xclk = 67;
472 par->features = ATI_CHIP_264VTB;
475 case PCI_CHIP_MACH64GT:
478 par->pll_limits.pll_max = 170;
479 par->pll_limits.mclk = 67;
480 par->pll_limits.xclk = 67;
481 par->features = ATI_CHIP_264GTB;
482 } else if(rev == 0x02) {
483 par->pll_limits.pll_max = 200;
484 par->pll_limits.mclk = 67;
485 par->pll_limits.xclk = 67;
486 par->features = ATI_CHIP_264GTB;
492 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
496 static char ram_dram[] __devinitdata = "DRAM";
497 static char ram_resv[] __devinitdata = "RESV";
498 #ifdef CONFIG_FB_ATY_GX
499 static char ram_vram[] __devinitdata = "VRAM";
500 #endif /* CONFIG_FB_ATY_GX */
501 #ifdef CONFIG_FB_ATY_CT
502 static char ram_edo[] __devinitdata = "EDO";
503 static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
504 static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
505 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
506 static char ram_off[] __devinitdata = "OFF";
507 #endif /* CONFIG_FB_ATY_CT */
510 static u32 pseudo_palette[17];
512 #ifdef CONFIG_FB_ATY_GX
513 static char *aty_gx_ram[8] __devinitdata = {
514 ram_dram, ram_vram, ram_vram, ram_dram,
515 ram_dram, ram_vram, ram_vram, ram_resv
517 #endif /* CONFIG_FB_ATY_GX */
519 #ifdef CONFIG_FB_ATY_CT
520 static char *aty_ct_ram[8] __devinitdata = {
521 ram_off, ram_dram, ram_edo, ram_edo,
522 ram_sdram, ram_sgram, ram_sdram32, ram_resv
524 #endif /* CONFIG_FB_ATY_CT */
526 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par)
528 u32 pixclock = var->pixclock;
529 #ifdef CONFIG_FB_ATY_GENERIC_LCD
531 par->pll.ct.xres = 0;
532 if (par->lcd_table != 0) {
533 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
534 if(lcd_on_off & LCD_ON) {
535 par->pll.ct.xres = var->xres;
536 pixclock = par->lcd_pixclock;
543 #if defined(CONFIG_PPC)
546 * Apple monitor sense
549 static int __init read_aty_sense(const struct atyfb_par *par)
553 aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
555 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
557 i = aty_ld_le32(GP_IO, par); /* get primary sense value */
558 sense = ((i & 0x3000) >> 3) | (i & 0x100);
560 /* drive each sense line low in turn and collect the other 2 */
561 aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
563 i = aty_ld_le32(GP_IO, par);
564 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
565 aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
568 aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
570 i = aty_ld_le32(GP_IO, par);
571 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
572 aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
575 aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
577 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
578 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
582 #endif /* defined(CONFIG_PPC) */
584 /* ------------------------------------------------------------------------- */
590 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
592 #ifdef CONFIG_FB_ATY_GENERIC_LCD
593 if (par->lcd_table != 0) {
594 if(!M64_HAS(LT_LCD_REGS)) {
595 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
596 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
598 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
599 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
602 /* switch to non shadow registers */
603 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
604 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
606 /* save stretching */
607 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
608 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
609 if (!M64_HAS(LT_LCD_REGS))
610 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
613 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
614 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
615 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
616 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
617 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
618 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
619 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
621 #ifdef CONFIG_FB_ATY_GENERIC_LCD
622 if (par->lcd_table != 0) {
623 /* switch to shadow registers */
624 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
625 SHADOW_EN | SHADOW_RW_EN, par);
627 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
628 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
629 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
630 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
632 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
634 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
637 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
639 #ifdef CONFIG_FB_ATY_GENERIC_LCD
640 if (par->lcd_table != 0) {
642 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
644 /* update non-shadow registers first */
645 aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
646 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
647 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
649 /* temporarily disable stretching */
650 aty_st_lcd(HORZ_STRETCHING,
651 crtc->horz_stretching &
652 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
653 aty_st_lcd(VERT_STRETCHING,
654 crtc->vert_stretching &
655 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
656 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
660 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
662 DPRINTK("setting up CRTC\n");
663 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
664 ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
665 (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
666 (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
668 DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
669 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
670 DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
671 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
672 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
673 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
674 DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
676 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
677 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
678 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
679 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
680 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
681 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
683 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
686 if (par->accel_flags & FB_ACCELF_TEXT)
687 aty_init_engine(par, info);
689 #ifdef CONFIG_FB_ATY_GENERIC_LCD
690 /* after setting the CRTC registers we should set the LCD registers. */
691 if (par->lcd_table != 0) {
692 /* switch to shadow registers */
693 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
694 (SHADOW_EN | SHADOW_RW_EN), par);
696 DPRINTK("set secondary CRT to %ix%i %c%c\n",
697 ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
698 (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
700 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
701 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
702 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
703 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
705 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
706 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
707 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
708 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
710 /* restore CRTC selection & shadow state and enable stretching */
711 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
712 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
713 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
714 if(!M64_HAS(LT_LCD_REGS))
715 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
717 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
718 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
719 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
720 if(!M64_HAS(LT_LCD_REGS)) {
721 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
722 aty_ld_le32(LCD_INDEX, par);
723 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
726 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
729 static int aty_var_to_crtc(const struct fb_info *info,
730 const struct fb_var_screeninfo *var, struct crtc *crtc)
732 struct atyfb_par *par = (struct atyfb_par *) info->par;
733 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
734 u32 sync, vmode, vdisplay;
735 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
736 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
737 u32 pix_width, dp_pix_width, dp_chain_mask;
742 vxres = var->xres_virtual;
743 vyres = var->yres_virtual;
744 xoffset = var->xoffset;
745 yoffset = var->yoffset;
746 bpp = var->bits_per_pixel;
748 bpp = (var->green.length == 5) ? 15 : 16;
752 /* convert (and round up) and validate */
753 if (vxres < xres + xoffset)
754 vxres = xres + xoffset;
757 if (vyres < yres + yoffset)
758 vyres = yres + yoffset;
763 pix_width = CRTC_PIX_WIDTH_8BPP;
765 HOST_8BPP | SRC_8BPP | DST_8BPP |
766 BYTE_ORDER_LSB_TO_MSB;
767 dp_chain_mask = DP_CHAIN_8BPP;
768 } else if (bpp <= 15) {
770 pix_width = CRTC_PIX_WIDTH_15BPP;
771 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
772 BYTE_ORDER_LSB_TO_MSB;
773 dp_chain_mask = DP_CHAIN_15BPP;
774 } else if (bpp <= 16) {
776 pix_width = CRTC_PIX_WIDTH_16BPP;
777 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
778 BYTE_ORDER_LSB_TO_MSB;
779 dp_chain_mask = DP_CHAIN_16BPP;
780 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
782 pix_width = CRTC_PIX_WIDTH_24BPP;
784 HOST_8BPP | SRC_8BPP | DST_8BPP |
785 BYTE_ORDER_LSB_TO_MSB;
786 dp_chain_mask = DP_CHAIN_24BPP;
787 } else if (bpp <= 32) {
789 pix_width = CRTC_PIX_WIDTH_32BPP;
790 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
791 BYTE_ORDER_LSB_TO_MSB;
792 dp_chain_mask = DP_CHAIN_32BPP;
796 if (vxres * vyres * bpp / 8 > info->fix.smem_len)
797 FAIL("not enough video RAM");
799 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
800 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
802 if((xres > 1600) || (yres > 1200)) {
803 FAIL("MACH64 chips are designed for max 1600x1200\n"
804 "select anoter resolution.");
806 h_sync_strt = h_disp + var->right_margin;
807 h_sync_end = h_sync_strt + var->hsync_len;
808 h_sync_dly = var->right_margin & 7;
809 h_total = h_sync_end + h_sync_dly + var->left_margin;
811 v_sync_strt = v_disp + var->lower_margin;
812 v_sync_end = v_sync_strt + var->vsync_len;
813 v_total = v_sync_end + var->upper_margin;
815 #ifdef CONFIG_FB_ATY_GENERIC_LCD
816 if (par->lcd_table != 0) {
817 if(!M64_HAS(LT_LCD_REGS)) {
818 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
819 crtc->lcd_index = lcd_index &
820 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
821 aty_st_le32(LCD_INDEX, lcd_index, par);
824 if (!M64_HAS(MOBIL_BUS))
825 crtc->lcd_index |= CRTC2_DISPLAY_DIS;
827 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
828 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
830 crtc->lcd_gen_cntl &=
831 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
832 /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
833 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
834 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
836 if((crtc->lcd_gen_cntl & LCD_ON) &&
837 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
838 /* We cannot display the mode on the LCD. If the CRT is enabled
839 we can turn off the LCD.
840 If the CRT is off, it isn't a good idea to switch it on; we don't
841 know if one is connected. So it's better to fail then.
843 if (crtc->lcd_gen_cntl & CRT_ON) {
844 PRINTKI("Disable lcd panel, because video mode does not fit.\n");
845 crtc->lcd_gen_cntl &= ~LCD_ON;
846 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
848 FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode.");
853 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
855 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
856 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
857 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */
859 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
861 /* This is horror! When we simulate, say 640x480 on an 800x600
862 lcd monitor, the CRTC should be programmed 800x600 values for
863 the non visible part, but 640x480 for the visible part.
864 This code has been tested on a laptop with it's 1400x1050 lcd
865 monitor and a conventional monitor both switched on.
866 Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
867 works with little glitches also with DOUBLESCAN modes
869 if (yres < par->lcd_height) {
870 VScan = par->lcd_height / yres;
873 vmode |= FB_VMODE_DOUBLE;
877 h_sync_strt = h_disp + par->lcd_right_margin;
878 h_sync_end = h_sync_strt + par->lcd_hsync_len;
879 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
880 h_total = h_disp + par->lcd_hblank_len;
882 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
883 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
884 v_total = v_disp + par->lcd_vblank_len / VScan;
886 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
888 h_disp = (h_disp >> 3) - 1;
889 h_sync_strt = (h_sync_strt >> 3) - 1;
890 h_sync_end = (h_sync_end >> 3) - 1;
891 h_total = (h_total >> 3) - 1;
892 h_sync_wid = h_sync_end - h_sync_strt;
894 FAIL_MAX("h_disp too large", h_disp, 0xff);
895 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
896 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
897 if(h_sync_wid > 0x1f)
899 FAIL_MAX("h_total too large", h_total, 0x1ff);
901 if (vmode & FB_VMODE_DOUBLE) {
909 #ifdef CONFIG_FB_ATY_GENERIC_LCD
910 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
911 vdisplay = par->lcd_height;
918 v_sync_wid = v_sync_end - v_sync_strt;
920 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
921 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
922 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
923 if(v_sync_wid > 0x1f)
925 FAIL_MAX("v_total too large", v_total, 0x7ff);
927 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
932 crtc->xoffset = xoffset;
933 crtc->yoffset = yoffset;
935 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
936 crtc->vline_crnt_vline = 0;
938 crtc->h_tot_disp = h_total | (h_disp<<16);
939 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
940 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21);
941 crtc->v_tot_disp = v_total | (v_disp<<16);
942 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
944 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
945 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
946 crtc->gen_cntl |= CRTC_VGA_LINEAR;
948 /* Enable doublescan mode if requested */
949 if (vmode & FB_VMODE_DOUBLE)
950 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
951 /* Enable interlaced mode if requested */
952 if (vmode & FB_VMODE_INTERLACED)
953 crtc->gen_cntl |= CRTC_INTERLACE_EN;
954 #ifdef CONFIG_FB_ATY_GENERIC_LCD
955 if (par->lcd_table != 0) {
957 if(vmode & FB_VMODE_DOUBLE)
959 if(vmode & FB_VMODE_INTERLACED) {
962 /* The prefered mode for the lcd is not interlaced, so disable it if
963 it was enabled. For doublescan there is no problem, because we can
964 compensate for it in the hardware stretching (we stretch half as much)
966 vmode &= ~FB_VMODE_INTERLACED;
967 /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/
969 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
970 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
971 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
972 USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
973 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
975 /* MOBILITY M1 tested, FIXME: LT */
976 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
977 if (!M64_HAS(LT_LCD_REGS))
978 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
979 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
981 crtc->horz_stretching &=
982 ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
983 HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
984 if (xres < par->lcd_width) {
987 * The horizontal blender misbehaves when HDisplay is less than a
988 * a certain threshold (440 for a 1024-wide panel). It doesn't
989 * stretch such modes enough. Use pixel replication instead of
990 * blending to stretch modes that can be made to exactly fit the
991 * panel width. The undocumented "NoLCDBlend" option allows the
992 * pixel-replicated mode to be slightly wider or narrower than the
993 * panel width. It also causes a mode that is exactly half as wide
994 * as the panel to be pixel-replicated, rather than blended.
996 int HDisplay = xres & ~7;
997 int nStretch = par->lcd_width / HDisplay;
998 int Remainder = par->lcd_width % HDisplay;
1000 if ((!Remainder && ((nStretch > 2))) ||
1001 (((HDisplay * 16) / par->lcd_width) < 7)) {
1002 static const char StretchLoops[] = {10, 12, 13, 15, 16};
1003 int horz_stretch_loop = -1, BestRemainder;
1004 int Numerator = HDisplay, Denominator = par->lcd_width;
1006 ATIReduceRatio(&Numerator, &Denominator);
1008 BestRemainder = (Numerator * 16) / Denominator;
1009 while (--Index >= 0) {
1010 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1012 if (Remainder < BestRemainder) {
1013 horz_stretch_loop = Index;
1014 if (!(BestRemainder = Remainder))
1019 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1020 int horz_stretch_ratio = 0, Accumulator = 0;
1021 int reuse_previous = 1;
1023 Index = StretchLoops[horz_stretch_loop];
1025 while (--Index >= 0) {
1026 if (Accumulator > 0)
1027 horz_stretch_ratio |= reuse_previous;
1029 Accumulator += Denominator;
1030 Accumulator -= Numerator;
1031 reuse_previous <<= 1;
1034 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1035 ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1036 (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1037 break; /* Out of the do { ... } while (0) */
1041 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1042 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1046 if (vdisplay < par->lcd_height) {
1047 crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1048 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1050 if (!M64_HAS(LT_LCD_REGS) &&
1051 xres <= (M64_HAS(MOBIL_BUS)?1024:800))
1052 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1055 * Don't use vertical blending if the mode is too wide or not
1056 * vertically stretched.
1058 crtc->vert_stretching = 0;
1060 /* copy to shadow crtc */
1061 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1062 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1063 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1064 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1066 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1068 if (M64_HAS(MAGIC_FIFO)) {
1070 /* FIXME: magic FIFO values */
1071 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH);
1073 crtc->dp_pix_width = dp_pix_width;
1074 crtc->dp_chain_mask = dp_chain_mask;
1079 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var)
1081 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1082 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
1084 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1086 u32 double_scan, interlace;
1089 h_total = crtc->h_tot_disp & 0x1ff;
1090 h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1091 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1092 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1093 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1094 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1095 v_total = crtc->v_tot_disp & 0x7ff;
1096 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1097 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1098 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1099 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1100 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1101 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1102 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1103 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1106 xres = (h_disp + 1) * 8;
1108 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1109 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1110 hslen = h_sync_wid * 8;
1111 upper = v_total - v_sync_strt - v_sync_wid;
1112 lower = v_sync_strt - v_disp;
1114 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1115 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1116 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1118 switch (pix_width) {
1120 case CRTC_PIX_WIDTH_4BPP:
1122 var->red.offset = 0;
1123 var->red.length = 8;
1124 var->green.offset = 0;
1125 var->green.length = 8;
1126 var->blue.offset = 0;
1127 var->blue.length = 8;
1128 var->transp.offset = 0;
1129 var->transp.length = 0;
1132 case CRTC_PIX_WIDTH_8BPP:
1134 var->red.offset = 0;
1135 var->red.length = 8;
1136 var->green.offset = 0;
1137 var->green.length = 8;
1138 var->blue.offset = 0;
1139 var->blue.length = 8;
1140 var->transp.offset = 0;
1141 var->transp.length = 0;
1143 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
1145 var->red.offset = 10;
1146 var->red.length = 5;
1147 var->green.offset = 5;
1148 var->green.length = 5;
1149 var->blue.offset = 0;
1150 var->blue.length = 5;
1151 var->transp.offset = 0;
1152 var->transp.length = 0;
1154 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
1156 var->red.offset = 11;
1157 var->red.length = 5;
1158 var->green.offset = 5;
1159 var->green.length = 6;
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_24BPP: /* RGB 888 */
1167 var->red.offset = 16;
1168 var->red.length = 8;
1169 var->green.offset = 8;
1170 var->green.length = 8;
1171 var->blue.offset = 0;
1172 var->blue.length = 8;
1173 var->transp.offset = 0;
1174 var->transp.length = 0;
1176 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
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 = 24;
1185 var->transp.length = 8;
1188 FAIL("Invalid pixel width");
1194 var->xres_virtual = crtc->vxres;
1195 var->yres_virtual = crtc->vyres;
1196 var->bits_per_pixel = bpp;
1197 var->left_margin = left;
1198 var->right_margin = right;
1199 var->upper_margin = upper;
1200 var->lower_margin = lower;
1201 var->hsync_len = hslen;
1202 var->vsync_len = vslen;
1204 var->vmode = FB_VMODE_NONINTERLACED;
1205 /* In double scan mode, the vertical parameters are doubled, so we need to
1206 half them to get the right values.
1207 In interlaced mode the values are already correct, so no correction is
1211 var->vmode = FB_VMODE_INTERLACED;
1214 var->vmode = FB_VMODE_DOUBLE;
1216 var->upper_margin>>=1;
1217 var->lower_margin>>=1;
1224 /* ------------------------------------------------------------------------- */
1226 static int atyfb_set_par(struct fb_info *info)
1228 struct atyfb_par *par = (struct atyfb_par *) info->par;
1229 struct fb_var_screeninfo *var = &info->var;
1233 struct fb_var_screeninfo debug;
1239 if ((err = aty_var_to_crtc(info, var, &par->crtc)))
1242 pixclock = atyfb_get_pixclock(var, par);
1244 if (pixclock == 0) {
1245 FAIL("Invalid pixclock");
1247 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
1251 par->accel_flags = var->accel_flags; /* hack */
1253 if (par->blitter_may_be_busy)
1256 aty_set_crtc(par, &par->crtc);
1257 par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
1258 par->pll_ops->set_pll(info, &par->pll);
1261 if(par->pll_ops && par->pll_ops->pll_to_var)
1262 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll));
1266 if(0 == pixclock_in_ps) {
1267 PRINTKE("ALERT ops->pll_to_var get 0\n");
1268 pixclock_in_ps = pixclock;
1271 memset(&debug, 0, sizeof(debug));
1272 if(!aty_crtc_to_var(&(par->crtc), &debug)) {
1273 u32 hSync, vRefresh;
1274 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1275 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1277 h_disp = debug.xres;
1278 h_sync_strt = h_disp + debug.right_margin;
1279 h_sync_end = h_sync_strt + debug.hsync_len;
1280 h_total = h_sync_end + debug.left_margin;
1281 v_disp = debug.yres;
1282 v_sync_strt = v_disp + debug.lower_margin;
1283 v_sync_end = v_sync_strt + debug.vsync_len;
1284 v_total = v_sync_end + debug.upper_margin;
1286 hSync = 1000000000 / (pixclock_in_ps * h_total);
1287 vRefresh = (hSync * 1000) / v_total;
1288 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1290 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1293 DPRINTK("atyfb_set_par\n");
1294 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
1295 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
1296 var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
1297 DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps);
1298 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1299 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1300 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1301 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1302 h_disp, h_sync_strt, h_sync_end, h_total,
1303 v_disp, v_sync_strt, v_sync_end, v_total);
1304 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
1306 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1307 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1311 if (!M64_HAS(INTEGRATED)) {
1312 /* Don't forget MEM_CNTL */
1313 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1314 switch (var->bits_per_pixel) {
1325 aty_st_le32(MEM_CNTL, tmp, par);
1327 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1328 if (!M64_HAS(MAGIC_POSTDIV))
1329 tmp |= par->mem_refresh_rate << 20;
1330 switch (var->bits_per_pixel) {
1342 if (M64_HAS(CT_BUS)) {
1343 aty_st_le32(DAC_CNTL, 0x87010184, par);
1344 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1345 } else if (M64_HAS(VT_BUS)) {
1346 aty_st_le32(DAC_CNTL, 0x87010184, par);
1347 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1348 } else if (M64_HAS(MOBIL_BUS)) {
1349 aty_st_le32(DAC_CNTL, 0x80010102, par);
1350 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1353 aty_st_le32(DAC_CNTL, 0x86010102, par);
1354 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1355 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1357 aty_st_le32(MEM_CNTL, tmp, par);
1359 aty_st_8(DAC_MASK, 0xff, par);
1361 info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
1362 info->fix.visual = var->bits_per_pixel <= 8 ?
1363 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1365 /* Initialize the graphics engine */
1366 if (par->accel_flags & FB_ACCELF_TEXT)
1367 aty_init_engine(par, info);
1369 #ifdef CONFIG_BOOTX_TEXT
1370 btext_update_display(info->fix.smem_start,
1371 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1372 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1373 var->bits_per_pixel,
1374 par->crtc.vxres * var->bits_per_pixel / 8);
1375 #endif /* CONFIG_BOOTX_TEXT */
1377 /* switch to accelerator mode */
1378 if (!(par->crtc.gen_cntl & CRTC_EXT_DISP_EN))
1379 aty_st_le32(CRTC_GEN_CNTL, par->crtc.gen_cntl | CRTC_EXT_DISP_EN, par);
1383 /* dump non shadow CRTC, pll, LCD registers */
1386 /* CRTC registers */
1388 printk("debug atyfb: Mach64 non-shadow register values:");
1389 for (i = 0; i < 256; i = i+4) {
1390 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
1391 printk(" %08X", aty_ld_le32(i, par));
1395 #ifdef CONFIG_FB_ATY_CT
1398 printk("debug atyfb: Mach64 PLL register values:");
1399 for (i = 0; i < 64; i++) {
1400 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1401 if(i%4 == 0) printk(" ");
1402 printk("%02X", aty_ld_pll_ct(i, par));
1405 #endif /* CONFIG_FB_ATY_CT */
1407 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1408 if (par->lcd_table != 0) {
1411 printk("debug atyfb: LCD register values:");
1412 if(M64_HAS(LT_LCD_REGS)) {
1413 for(i = 0; i <= POWER_MANAGEMENT; i++) {
1414 if(i == EXT_VERT_STRETCH)
1416 printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
1417 printk(" %08X", aty_ld_lcd(i, par));
1421 for (i = 0; i < 64; i++) {
1422 if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1423 printk(" %08X", aty_ld_lcd(i, par));
1428 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1434 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1436 struct atyfb_par *par = (struct atyfb_par *) info->par;
1442 memcpy(&pll, &(par->pll), sizeof(pll));
1444 if((err = aty_var_to_crtc(info, var, &crtc)))
1447 pixclock = atyfb_get_pixclock(var, par);
1449 if (pixclock == 0) {
1450 FAIL("Invalid pixclock");
1452 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
1456 if (var->accel_flags & FB_ACCELF_TEXT)
1457 info->var.accel_flags = FB_ACCELF_TEXT;
1459 info->var.accel_flags = 0;
1461 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
1462 if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
1465 aty_crtc_to_var(&crtc, var);
1466 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1470 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1472 u32 xoffset = info->var.xoffset;
1473 u32 yoffset = info->var.yoffset;
1474 u32 vxres = par->crtc.vxres;
1475 u32 bpp = info->var.bits_per_pixel;
1477 par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
1482 * Open/Release the frame buffer device
1485 static int atyfb_open(struct fb_info *info, int user)
1487 struct atyfb_par *par = (struct atyfb_par *) info->par;
1498 static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp)
1500 struct atyfb_par *par = dev_id;
1504 spin_lock(&par->int_lock);
1506 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1508 if (int_cntl & CRTC_VBLANK_INT) {
1509 /* clear interrupt */
1510 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
1511 par->vblank.count++;
1512 if (par->vblank.pan_display) {
1513 par->vblank.pan_display = 0;
1514 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1516 wake_up_interruptible(&par->vblank.wait);
1520 spin_unlock(&par->int_lock);
1522 return IRQ_RETVAL(handled);
1525 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1529 if (!test_and_set_bit(0, &par->irq_flags)) {
1530 if (request_irq(par->irq, aty_irq, SA_SHIRQ, "atyfb", par)) {
1531 clear_bit(0, &par->irq_flags);
1534 spin_lock_irq(&par->int_lock);
1535 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1536 /* clear interrupt */
1537 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1538 /* enable interrupt */
1539 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1540 spin_unlock_irq(&par->int_lock);
1541 } else if (reenable) {
1542 spin_lock_irq(&par->int_lock);
1543 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1544 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1545 printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
1546 /* re-enable interrupt */
1547 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
1549 spin_unlock_irq(&par->int_lock);
1555 static int aty_disable_irq(struct atyfb_par *par)
1559 if (test_and_clear_bit(0, &par->irq_flags)) {
1560 if (par->vblank.pan_display) {
1561 par->vblank.pan_display = 0;
1562 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1564 spin_lock_irq(&par->int_lock);
1565 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1566 /* disable interrupt */
1567 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
1568 spin_unlock_irq(&par->int_lock);
1569 free_irq(par->irq, par);
1575 static int atyfb_release(struct fb_info *info, int user)
1577 struct atyfb_par *par = (struct atyfb_par *) info->par;
1584 int was_mmaped = par->mmaped;
1589 struct fb_var_screeninfo var;
1591 /* Now reset the default display config, we have no
1592 * idea what the program(s) which mmap'd the chip did
1593 * to the configuration, nor whether it restored it
1598 var.accel_flags &= ~FB_ACCELF_TEXT;
1600 var.accel_flags |= FB_ACCELF_TEXT;
1601 if (var.yres == var.yres_virtual) {
1602 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1603 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
1604 if (var.yres_virtual < var.yres)
1605 var.yres_virtual = var.yres;
1609 aty_disable_irq(par);
1616 * Pan or Wrap the Display
1618 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1621 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1623 struct atyfb_par *par = (struct atyfb_par *) info->par;
1624 u32 xres, yres, xoffset, yoffset;
1626 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1627 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1628 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1630 xoffset = (var->xoffset + 7) & ~7;
1631 yoffset = var->yoffset;
1632 if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres)
1634 info->var.xoffset = xoffset;
1635 info->var.yoffset = yoffset;
1639 set_off_pitch(par, info);
1640 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1641 par->vblank.pan_display = 1;
1643 par->vblank.pan_display = 0;
1644 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1650 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1652 struct aty_interrupt *vbl;
1664 ret = aty_enable_irq(par, 0);
1669 ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
1674 aty_enable_irq(par, 1);
1683 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
1684 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
1690 u8 mclk_post_div; /* 1,2,3,4,8 */
1691 u8 mclk_fb_mult; /* 2 or 4 */
1692 u8 xclk_post_div; /* 1,2,3,4,8 */
1694 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
1695 u32 dsp_xclks_per_row; /* 0-16383 */
1696 u32 dsp_loop_latency; /* 0-15 */
1697 u32 dsp_precision; /* 0-7 */
1698 u32 dsp_on; /* 0-2047 */
1699 u32 dsp_off; /* 0-2047 */
1702 #define ATYIO_FEATR 0x41545902 /* ATY\02 */
1703 #define ATYIO_FEATW 0x41545903 /* ATY\03 */
1706 #ifndef FBIO_WAITFORVSYNC
1707 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
1710 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
1711 u_long arg, struct fb_info *info)
1713 struct atyfb_par *par = (struct atyfb_par *) info->par;
1715 struct fbtype fbtyp;
1721 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1722 fbtyp.fb_width = par->crtc.vxres;
1723 fbtyp.fb_height = par->crtc.vyres;
1724 fbtyp.fb_depth = info->var.bits_per_pixel;
1725 fbtyp.fb_cmsize = info->cmap.len;
1726 fbtyp.fb_size = info->fix.smem_len;
1727 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp)))
1730 #endif /* __sparc__ */
1732 case FBIO_WAITFORVSYNC:
1736 if (get_user(crtc, (__u32 __user *) arg))
1739 return aty_waitforvblank(par, crtc);
1743 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1745 if (M64_HAS(INTEGRATED)) {
1747 union aty_pll *pll = &(par->pll);
1748 u32 dsp_config = pll->ct.dsp_config;
1749 u32 dsp_on_off = pll->ct.dsp_on_off;
1750 clk.ref_clk_per = par->ref_clk_per;
1751 clk.pll_ref_div = pll->ct.pll_ref_div;
1752 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1753 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1754 clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1755 clk.xclk_post_div = pll->ct.xclk_post_div_real;
1756 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1757 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1758 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1759 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1760 clk.dsp_precision = (dsp_config >> 20) & 7;
1761 clk.dsp_off = dsp_on_off & 0x7ff;
1762 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1763 if (copy_to_user((struct atyclk __user *) arg, &clk,
1770 if (M64_HAS(INTEGRATED)) {
1772 union aty_pll *pll = &(par->pll);
1773 if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk)))
1775 par->ref_clk_per = clk.ref_clk_per;
1776 pll->ct.pll_ref_div = clk.pll_ref_div;
1777 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1778 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1779 pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1780 pll->ct.xclk_post_div_real = clk.xclk_post_div;
1781 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1782 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1783 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1784 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20);
1785 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16);
1786 /*aty_calc_pll_ct(info, &pll->ct);*/
1787 aty_set_pll_ct(info, pll);
1792 if (get_user(par->features, (u32 __user *) arg))
1796 if (put_user(par->features, (u32 __user *) arg))
1799 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1806 static int atyfb_sync(struct fb_info *info)
1808 struct atyfb_par *par = (struct atyfb_par *) info->par;
1810 if (par->blitter_may_be_busy)
1816 static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
1818 struct atyfb_par *par = (struct atyfb_par *) info->par;
1819 unsigned int size, page, map_size = 0;
1820 unsigned long map_offset = 0;
1827 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1830 off = vma->vm_pgoff << PAGE_SHIFT;
1831 size = vma->vm_end - vma->vm_start;
1833 /* To stop the swapper from even considering these pages. */
1834 vma->vm_flags |= (VM_IO | VM_RESERVED);
1836 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1837 ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1838 off += 0x8000000000000000UL;
1840 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
1842 /* Each page, see which map applies */
1843 for (page = 0; page < size;) {
1845 for (i = 0; par->mmap_map[i].size; i++) {
1846 unsigned long start = par->mmap_map[i].voff;
1847 unsigned long end = start + par->mmap_map[i].size;
1848 unsigned long offset = off + page;
1855 map_size = par->mmap_map[i].size - (offset - start);
1857 par->mmap_map[i].poff + (offset - start);
1864 if (page + map_size > size)
1865 map_size = size - page;
1867 pgprot_val(vma->vm_page_prot) &=
1868 ~(par->mmap_map[i].prot_mask);
1869 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1871 if (remap_pfn_range(vma, vma->vm_start + page,
1872 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1893 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1897 for (i = 0; i < 256; i++) {
1898 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1899 if (M64_HAS(EXTRA_BRIGHT))
1901 aty_st_8(DAC_CNTL, tmp, par);
1902 aty_st_8(DAC_MASK, 0xff, par);
1904 writeb(i, &par->aty_cmap_regs->rindex);
1905 atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
1906 atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
1907 atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
1908 writeb(i, &par->aty_cmap_regs->windex);
1909 writeb(atyfb_save.r[1 - enter][i],
1910 &par->aty_cmap_regs->lut);
1911 writeb(atyfb_save.g[1 - enter][i],
1912 &par->aty_cmap_regs->lut);
1913 writeb(atyfb_save.b[1 - enter][i],
1914 &par->aty_cmap_regs->lut);
1918 static void atyfb_palette(int enter)
1920 struct atyfb_par *par;
1921 struct fb_info *info;
1924 for (i = 0; i < FB_MAX; i++) {
1925 info = registered_fb[i];
1926 if (info && info->fbops == &atyfb_ops) {
1927 par = (struct atyfb_par *) info->par;
1929 atyfb_save_palette(par, enter);
1931 atyfb_save.yoffset = info->var.yoffset;
1932 info->var.yoffset = 0;
1933 set_off_pitch(par, info);
1935 info->var.yoffset = atyfb_save.yoffset;
1936 set_off_pitch(par, info);
1938 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1943 #endif /* __sparc__ */
1947 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1949 /* Power management routines. Those are used for PowerBook sleep.
1951 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1956 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1957 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1958 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1959 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1965 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1966 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1968 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1970 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1971 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1974 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1976 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1978 if ((--timeout) == 0)
1980 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
1984 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1985 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1988 pm |= (PWR_BLON | AUTO_PWR_UP);
1989 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1990 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1993 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1995 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1997 if ((--timeout) == 0)
1999 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2003 return timeout ? 0 : -EIO;
2006 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2008 struct fb_info *info = pci_get_drvdata(pdev);
2009 struct atyfb_par *par = (struct atyfb_par *) info->par;
2011 #ifndef CONFIG_PPC_PMAC
2012 /* HACK ALERT ! Once I find a proper way to say to each driver
2013 * individually what will happen with it's PCI slot, I'll change
2014 * that. On laptops, the AGP slot is just unclocked, so D2 is
2015 * expected, while on desktops, the card is powered off
2018 #endif /* CONFIG_PPC_PMAC */
2020 if (state.event == pdev->dev.power.power_state.event)
2023 acquire_console_sem();
2025 fb_set_suspend(info, 1);
2027 /* Idle & reset engine */
2029 aty_reset_engine(par);
2031 /* Blank display and LCD */
2032 atyfb_blank(FB_BLANK_POWERDOWN, info);
2035 par->lock_blank = 1;
2037 /* Set chip to "suspend" mode */
2038 if (aty_power_mgmt(1, par)) {
2040 par->lock_blank = 0;
2041 atyfb_blank(FB_BLANK_UNBLANK, info);
2042 fb_set_suspend(info, 0);
2043 release_console_sem();
2047 release_console_sem();
2049 pdev->dev.power.power_state = state;
2054 static int atyfb_pci_resume(struct pci_dev *pdev)
2056 struct fb_info *info = pci_get_drvdata(pdev);
2057 struct atyfb_par *par = (struct atyfb_par *) info->par;
2059 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2062 acquire_console_sem();
2064 if (pdev->dev.power.power_state.event == 2)
2065 aty_power_mgmt(0, par);
2068 /* Restore display */
2069 atyfb_set_par(info);
2072 fb_set_suspend(info, 0);
2075 par->lock_blank = 0;
2076 atyfb_blank(FB_BLANK_UNBLANK, info);
2078 release_console_sem();
2080 pdev->dev.power.power_state = PMSG_ON;
2085 #endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */
2087 #ifdef CONFIG_PMAC_BACKLIGHT
2090 * LCD backlight control
2093 static int backlight_conv[] = {
2094 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
2095 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
2098 static int aty_set_backlight_enable(int on, int level, void *data)
2100 struct fb_info *info = (struct fb_info *) data;
2101 struct atyfb_par *par = (struct atyfb_par *) info->par;
2102 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2104 reg |= (BLMOD_EN | BIASMOD_EN);
2105 if (on && level > BACKLIGHT_OFF) {
2106 reg &= ~BIAS_MOD_LEVEL_MASK;
2107 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
2109 reg &= ~BIAS_MOD_LEVEL_MASK;
2110 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
2112 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2116 static int aty_set_backlight_level(int level, void *data)
2118 return aty_set_backlight_enable(1, level, data);
2121 static struct backlight_controller aty_backlight_controller = {
2122 aty_set_backlight_enable,
2123 aty_set_backlight_level
2125 #endif /* CONFIG_PMAC_BACKLIGHT */
2127 static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2129 const int ragepro_tbl[] = {
2130 44, 50, 55, 66, 75, 80, 100
2132 const int ragexl_tbl[] = {
2133 50, 66, 75, 83, 90, 95, 100, 105,
2134 110, 115, 120, 125, 133, 143, 166
2136 const int *refresh_tbl;
2139 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2140 refresh_tbl = ragexl_tbl;
2141 size = sizeof(ragexl_tbl)/sizeof(int);
2143 refresh_tbl = ragepro_tbl;
2144 size = sizeof(ragepro_tbl)/sizeof(int);
2147 for (i=0; i < size; i++) {
2148 if (xclk < refresh_tbl[i])
2151 par->mem_refresh_rate = i;
2158 static struct fb_info *fb_list = NULL;
2160 static int __init aty_init(struct fb_info *info, const char *name)
2162 struct atyfb_par *par = (struct atyfb_par *) info->par;
2163 const char *ramname = NULL, *xtal;
2165 struct fb_var_screeninfo var;
2168 #if defined(CONFIG_PPC)
2172 init_waitqueue_head(&par->vblank.wait);
2173 spin_lock_init(&par->int_lock);
2175 par->aty_cmap_regs =
2176 (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0);
2178 #ifdef CONFIG_PPC_PMAC
2179 /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2180 * and set the frequency manually. */
2181 if (machine_is_compatible("PowerBook2,1")) {
2182 par->pll_limits.mclk = 70;
2183 par->pll_limits.xclk = 53;
2187 par->pll_limits.pll_max = pll;
2189 par->pll_limits.mclk = mclk;
2191 par->pll_limits.xclk = xclk;
2193 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2194 par->pll_per = 1000000/par->pll_limits.pll_max;
2195 par->mclk_per = 1000000/par->pll_limits.mclk;
2196 par->xclk_per = 1000000/par->pll_limits.xclk;
2198 par->ref_clk_per = 1000000000000ULL / 14318180;
2201 #ifdef CONFIG_FB_ATY_GX
2202 if (!M64_HAS(INTEGRATED)) {
2204 u8 dac_type, dac_subtype, clk_type;
2205 stat0 = aty_ld_le32(CONFIG_STAT0, par);
2206 par->bus_type = (stat0 >> 0) & 0x07;
2207 par->ram_type = (stat0 >> 3) & 0x07;
2208 ramname = aty_gx_ram[par->ram_type];
2209 /* FIXME: clockchip/RAMDAC probing? */
2210 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2212 clk_type = CLK_ATI18818_1;
2213 dac_type = (stat0 >> 9) & 0x07;
2214 if (dac_type == 0x07)
2215 dac_subtype = DAC_ATT20C408;
2217 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2219 dac_type = DAC_IBMRGB514;
2220 dac_subtype = DAC_IBMRGB514;
2221 clk_type = CLK_IBMRGB514;
2223 switch (dac_subtype) {
2225 par->dac_ops = &aty_dac_ibm514;
2227 case DAC_ATI68860_B:
2228 case DAC_ATI68860_C:
2229 par->dac_ops = &aty_dac_ati68860b;
2233 par->dac_ops = &aty_dac_att21c498;
2236 PRINTKI("aty_init: DAC type not implemented yet!\n");
2237 par->dac_ops = &aty_dac_unsupported;
2241 case CLK_ATI18818_1:
2242 par->pll_ops = &aty_pll_ati18818_1;
2245 par->pll_ops = &aty_pll_stg1703;
2248 par->pll_ops = &aty_pll_ch8398;
2251 par->pll_ops = &aty_pll_att20c408;
2254 par->pll_ops = &aty_pll_ibm514;
2257 PRINTKI("aty_init: CLK type not implemented yet!");
2258 par->pll_ops = &aty_pll_unsupported;
2262 #endif /* CONFIG_FB_ATY_GX */
2263 #ifdef CONFIG_FB_ATY_CT
2264 if (M64_HAS(INTEGRATED)) {
2265 par->dac_ops = &aty_dac_ct;
2266 par->pll_ops = &aty_pll_ct;
2267 par->bus_type = PCI;
2268 #ifdef CONFIG_FB_ATY_XL_INIT
2269 if (IS_XL(par->pci_id))
2270 atyfb_xl_init(info);
2272 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
2273 ramname = aty_ct_ram[par->ram_type];
2274 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2275 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2276 par->pll_limits.mclk = 63;
2279 if (M64_HAS(GTB_DSP)
2280 && (pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par))) {
2282 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2283 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2288 if (diff2 < diff1) {
2289 par->ref_clk_per = 1000000000000ULL / 29498928;
2293 #endif /* CONFIG_FB_ATY_CT */
2295 /* save previous video mode */
2296 aty_get_crtc(par, &saved_crtc);
2297 if(par->pll_ops->get_pll)
2298 par->pll_ops->get_pll(info, &saved_pll);
2300 i = aty_ld_le32(MEM_CNTL, par);
2301 gtb_memsize = M64_HAS(GTB_DSP);
2303 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
2305 info->fix.smem_len = 0x80000;
2308 info->fix.smem_len = 0x100000;
2310 case MEM_SIZE_2M_GTB:
2311 info->fix.smem_len = 0x200000;
2313 case MEM_SIZE_4M_GTB:
2314 info->fix.smem_len = 0x400000;
2316 case MEM_SIZE_6M_GTB:
2317 info->fix.smem_len = 0x600000;
2319 case MEM_SIZE_8M_GTB:
2320 info->fix.smem_len = 0x800000;
2323 info->fix.smem_len = 0x80000;
2325 switch (i & MEM_SIZE_ALIAS) {
2327 info->fix.smem_len = 0x80000;
2330 info->fix.smem_len = 0x100000;
2333 info->fix.smem_len = 0x200000;
2336 info->fix.smem_len = 0x400000;
2339 info->fix.smem_len = 0x600000;
2342 info->fix.smem_len = 0x800000;
2345 info->fix.smem_len = 0x80000;
2348 if (M64_HAS(MAGIC_VRAM_SIZE)) {
2349 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
2350 info->fix.smem_len += 0x400000;
2354 info->fix.smem_len = vram * 1024;
2355 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2356 if (info->fix.smem_len <= 0x80000)
2358 else if (info->fix.smem_len <= 0x100000)
2360 else if (info->fix.smem_len <= 0x200000)
2361 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2362 else if (info->fix.smem_len <= 0x400000)
2363 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2364 else if (info->fix.smem_len <= 0x600000)
2365 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2367 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2368 aty_st_le32(MEM_CNTL, i, par);
2372 * Reg Block 0 (CT-compatible block) is at mmio_start
2373 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2376 info->fix.mmio_len = 0x400;
2377 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2378 } else if (M64_HAS(CT)) {
2379 info->fix.mmio_len = 0x400;
2380 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2381 } else if (M64_HAS(VT)) {
2382 info->fix.mmio_start -= 0x400;
2383 info->fix.mmio_len = 0x800;
2384 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2386 info->fix.mmio_start -= 0x400;
2387 info->fix.mmio_len = 0x800;
2388 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2391 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2392 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
2393 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
2394 par->pll_limits.mclk, par->pll_limits.xclk);
2396 #if defined(DEBUG) && defined(CONFIG_ATY_CT)
2397 if (M64_HAS(INTEGRATED)) {
2399 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
2400 "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
2401 "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n"
2403 aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
2404 aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
2405 aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
2406 aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par));
2407 for (i = 0; i < 40; i++)
2408 printk(" %02x", aty_ld_pll_ct(i, par));
2412 if(par->pll_ops->init_pll)
2413 par->pll_ops->init_pll(info, &par->pll);
2416 * Last page of 8 MB (4 MB on ISA) aperture is MMIO
2417 * FIXME: we should use the auxiliary aperture instead so we can access
2418 * the full 8 MB of video RAM on 8 MB boards
2421 if (!par->aux_start &&
2422 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2423 info->fix.smem_len -= GUI_RESERVE;
2426 * Disable register access through the linear aperture
2427 * if the auxiliary aperture is used so we can access
2428 * the full 8 MB of video RAM on 8 MB boards.
2431 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2434 par->mtrr_aper = -1;
2437 /* Cover the whole resource. */
2438 par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1);
2439 if (par->mtrr_aper >= 0 && !par->aux_start) {
2440 /* Make a hole for mmio. */
2441 par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE,
2442 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1);
2443 if (par->mtrr_reg < 0) {
2444 mtrr_del(par->mtrr_aper, 0, 0);
2445 par->mtrr_aper = -1;
2451 info->fbops = &atyfb_ops;
2452 info->pseudo_palette = pseudo_palette;
2453 info->flags = FBINFO_FLAG_DEFAULT;
2455 #ifdef CONFIG_PMAC_BACKLIGHT
2456 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2457 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2458 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2459 | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2460 } else if (M64_HAS(MOBIL_BUS))
2461 register_backlight_controller(&aty_backlight_controller, info, "ati");
2462 #endif /* CONFIG_PMAC_BACKLIGHT */
2464 memset(&var, 0, sizeof(var));
2466 if (_machine == _MACH_Pmac) {
2468 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2469 * applies to all Mac video cards
2472 if (!mac_find_mode(&var, info, mode, 8))
2475 if (default_vmode == VMODE_CHOOSE) {
2476 if (M64_HAS(G3_PB_1024x768))
2477 /* G3 PowerBook with 1024x768 LCD */
2478 default_vmode = VMODE_1024_768_60;
2479 else if (machine_is_compatible("iMac"))
2480 default_vmode = VMODE_1024_768_75;
2481 else if (machine_is_compatible
2483 /* iBook with 800x600 LCD */
2484 default_vmode = VMODE_800_600_60;
2486 default_vmode = VMODE_640_480_67;
2487 sense = read_aty_sense(par);
2488 PRINTKI("monitor sense=%x, mode %d\n",
2489 sense, mac_map_monitor_sense(sense));
2491 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2492 default_vmode = VMODE_640_480_60;
2493 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2494 default_cmode = CMODE_8;
2495 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
2499 #endif /* !CONFIG_PPC */
2501 #if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
2502 /* On Sparc, unless the user gave a specific mode
2503 * specification, use the PROM probed values in
2508 !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2512 var.accel_flags &= ~FB_ACCELF_TEXT;
2514 var.accel_flags |= FB_ACCELF_TEXT;
2516 if (comp_sync != -1) {
2518 var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2520 var.sync |= FB_SYNC_COMP_HIGH_ACT;
2523 if (var.yres == var.yres_virtual) {
2524 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2525 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2526 if (var.yres_virtual < var.yres)
2527 var.yres_virtual = var.yres;
2530 if (atyfb_check_var(&var, info)) {
2531 PRINTKE("can't set default video mode\n");
2536 atyfb_save_palette(par, 0);
2539 #ifdef CONFIG_FB_ATY_CT
2540 if (!noaccel && M64_HAS(INTEGRATED))
2541 aty_init_cursor(info);
2542 #endif /* CONFIG_FB_ATY_CT */
2545 fb_alloc_cmap(&info->cmap, 256, 0);
2547 if (register_framebuffer(info) < 0)
2552 PRINTKI("fb%d: %s frame buffer device on %s\n",
2553 info->node, info->fix.id, name);
2557 /* restore video mode */
2558 aty_set_crtc(par, &saved_crtc);
2559 par->pll_ops->set_pll(info, &saved_pll);
2562 if (par->mtrr_reg >= 0) {
2563 mtrr_del(par->mtrr_reg, 0, 0);
2566 if (par->mtrr_aper >= 0) {
2567 mtrr_del(par->mtrr_aper, 0, 0);
2568 par->mtrr_aper = -1;
2575 static int __init store_video_par(char *video_str, unsigned char m64_num)
2578 unsigned long vmembase, size, guiregbase;
2580 PRINTKI("store_video_par() '%s' \n", video_str);
2582 if (!(p = strsep(&video_str, ";")) || !*p)
2583 goto mach64_invalid;
2584 vmembase = simple_strtoul(p, NULL, 0);
2585 if (!(p = strsep(&video_str, ";")) || !*p)
2586 goto mach64_invalid;
2587 size = simple_strtoul(p, NULL, 0);
2588 if (!(p = strsep(&video_str, ";")) || !*p)
2589 goto mach64_invalid;
2590 guiregbase = simple_strtoul(p, NULL, 0);
2592 phys_vmembase[m64_num] = vmembase;
2593 phys_size[m64_num] = size;
2594 phys_guiregbase[m64_num] = guiregbase;
2595 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2600 phys_vmembase[m64_num] = 0;
2603 #endif /* CONFIG_ATARI */
2606 * Blank the display.
2609 static int atyfb_blank(int blank, struct fb_info *info)
2611 struct atyfb_par *par = (struct atyfb_par *) info->par;
2614 if (par->lock_blank || par->asleep)
2617 #ifdef CONFIG_PMAC_BACKLIGHT
2618 if ((_machine == _MACH_Pmac) && blank)
2619 set_backlight_enable(0);
2620 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2621 if (par->lcd_table && blank &&
2622 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2623 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2625 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2629 gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
2631 case FB_BLANK_UNBLANK:
2632 gen_cntl &= ~(0x4c);
2634 case FB_BLANK_NORMAL:
2637 case FB_BLANK_VSYNC_SUSPEND:
2640 case FB_BLANK_HSYNC_SUSPEND:
2643 case FB_BLANK_POWERDOWN:
2647 aty_st_8(CRTC_GEN_CNTL, gen_cntl, par);
2649 #ifdef CONFIG_PMAC_BACKLIGHT
2650 if ((_machine == _MACH_Pmac) && !blank)
2651 set_backlight_enable(1);
2652 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2653 if (par->lcd_table && !blank &&
2654 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2655 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2657 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2664 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2665 const struct atyfb_par *par)
2668 out_8(&par->aty_cmap_regs->windex, regno);
2669 out_8(&par->aty_cmap_regs->lut, red);
2670 out_8(&par->aty_cmap_regs->lut, green);
2671 out_8(&par->aty_cmap_regs->lut, blue);
2673 writeb(regno, &par->aty_cmap_regs->windex);
2674 writeb(red, &par->aty_cmap_regs->lut);
2675 writeb(green, &par->aty_cmap_regs->lut);
2676 writeb(blue, &par->aty_cmap_regs->lut);
2681 * Set a single color register. The values supplied are already
2682 * rounded down to the hardware's capabilities (according to the
2683 * entries in the var structure). Return != 0 for invalid regno.
2684 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
2687 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2688 u_int transp, struct fb_info *info)
2690 struct atyfb_par *par = (struct atyfb_par *) info->par;
2692 u32 *pal = info->pseudo_palette;
2694 depth = info->var.bits_per_pixel;
2696 depth = (info->var.green.length == 5) ? 15 : 16;
2702 (depth == 16 && regno > 63) ||
2703 (depth == 15 && regno > 31))
2710 par->palette[regno].red = red;
2711 par->palette[regno].green = green;
2712 par->palette[regno].blue = blue;
2717 pal[regno] = (regno << 10) | (regno << 5) | regno;
2720 pal[regno] = (regno << 11) | (regno << 5) | regno;
2723 pal[regno] = (regno << 16) | (regno << 8) | regno;
2726 i = (regno << 8) | regno;
2727 pal[regno] = (i << 16) | i;
2732 i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2733 if (M64_HAS(EXTRA_BRIGHT))
2734 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
2735 aty_st_8(DAC_CNTL, i, par);
2736 aty_st_8(DAC_MASK, 0xff, par);
2738 if (M64_HAS(INTEGRATED)) {
2741 aty_st_pal(regno << 3, red,
2742 par->palette[regno<<1].green,
2744 red = par->palette[regno>>1].red;
2745 blue = par->palette[regno>>1].blue;
2747 } else if (depth == 15) {
2749 for(i = 0; i < 8; i++) {
2750 aty_st_pal(regno + i, red, green, blue, par);
2754 aty_st_pal(regno, red, green, blue, par);
2763 extern void (*prom_palette) (int);
2765 static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2766 struct fb_info *info, unsigned long addr)
2768 extern int con_is_present(void);
2770 struct atyfb_par *par = info->par;
2771 struct pcidev_cookie *pcp;
2773 int node, len, i, j, ret;
2776 /* Do not attach when we have a serial console. */
2777 if (!con_is_present())
2781 * Map memory-mapped registers.
2783 par->ati_regbase = (void *)addr + 0x7ffc00UL;
2784 info->fix.mmio_start = addr + 0x7ffc00UL;
2787 * Map in big-endian aperture.
2789 info->screen_base = (char *) (addr + 0x800000UL);
2790 info->fix.smem_start = addr + 0x800000UL;
2793 * Figure mmap addresses from PCI config space.
2794 * Split Framebuffer in big- and little-endian halfs.
2796 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2800 par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
2801 if (!par->mmap_map) {
2802 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2805 memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
2807 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2808 struct resource *rp = &pdev->resource[i];
2809 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2815 io = (rp->flags & IORESOURCE_IO);
2817 size = rp->end - base + 1;
2819 pci_read_config_dword(pdev, breg, &pbase);
2825 * Map the framebuffer a second time, this time without
2826 * the braindead _PAGE_IE setting. This is used by the
2827 * fixed Xserver, but we need to maintain the old mapping
2828 * to stay compatible with older ones...
2831 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
2832 par->mmap_map[j].poff = base & PAGE_MASK;
2833 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2834 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2835 par->mmap_map[j].prot_flag = _PAGE_E;
2840 * Here comes the old framebuffer mapping with _PAGE_IE
2841 * set for the big endian half of the framebuffer...
2844 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
2845 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
2846 par->mmap_map[j].size = 0x800000;
2847 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2848 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
2853 par->mmap_map[j].voff = pbase & PAGE_MASK;
2854 par->mmap_map[j].poff = base & PAGE_MASK;
2855 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2856 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2857 par->mmap_map[j].prot_flag = _PAGE_E;
2861 if((ret = correct_chipset(par)))
2864 if (IS_XL(pdev->device)) {
2866 * Fix PROMs idea of MEM_CNTL settings...
2868 mem = aty_ld_le32(MEM_CNTL, par);
2869 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
2870 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
2871 switch (mem & 0x0f) {
2873 mem = (mem & ~(0x0f)) | 2;
2876 mem = (mem & ~(0x0f)) | 3;
2879 mem = (mem & ~(0x0f)) | 4;
2882 mem = (mem & ~(0x0f)) | 5;
2887 if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
2888 mem &= ~(0x00700000);
2890 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
2891 aty_st_le32(MEM_CNTL, mem, par);
2895 * If this is the console device, we will set default video
2896 * settings to what the PROM left us with.
2898 node = prom_getchild(prom_root_node);
2899 node = prom_searchsiblings(node, "aliases");
2901 len = prom_getproperty(node, "screen", prop, sizeof(prop));
2904 node = prom_finddevice(prop);
2909 pcp = pdev->sysdata;
2910 if (node == pcp->prom_node) {
2911 struct fb_var_screeninfo *var = &default_var;
2912 unsigned int N, P, Q, M, T, R;
2913 u32 v_total, h_total;
2918 crtc.vxres = prom_getintdefault(node, "width", 1024);
2919 crtc.vyres = prom_getintdefault(node, "height", 768);
2920 var->bits_per_pixel = prom_getintdefault(node, "depth", 8);
2921 var->xoffset = var->yoffset = 0;
2922 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
2923 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
2924 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
2925 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
2926 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2927 aty_crtc_to_var(&crtc, var);
2929 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin;
2930 v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
2933 * Read the PLL to figure actual Refresh Rate.
2935 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
2936 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
2937 for (i = 0; i < 16; i++)
2938 pll_regs[i] = aty_ld_pll_ct(i, par);
2941 * PLL Reference Divider M:
2946 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
2948 N = pll_regs[7 + (clock_cntl & 3)];
2951 * PLL Post Divider P (Dependant on CLOCK_CNTL):
2953 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
2967 * where R is XTALIN (= 14318 or 29498 kHz).
2969 if (IS_XL(pdev->device))
2976 default_var.pixclock = 1000000000 / T;
2982 #else /* __sparc__ */
2985 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2986 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
2988 u32 driv_inf_tab, sig;
2991 /* To support an LCD panel, we should know it's dimensions and
2992 * it's desired pixel clock.
2993 * There are two ways to do it:
2994 * - Check the startup video mode and calculate the panel
2995 * size from it. This is unreliable.
2996 * - Read it from the driver information table in the video BIOS.
2998 /* Address of driver information table is at offset 0x78. */
2999 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3001 /* Check for the driver information table signature. */
3002 sig = (*(u32 *)driv_inf_tab);
3003 if ((sig == 0x54504c24) || /* Rage LT pro */
3004 (sig == 0x544d5224) || /* Rage mobility */
3005 (sig == 0x54435824) || /* Rage XC */
3006 (sig == 0x544c5824)) { /* Rage XL */
3007 PRINTKI("BIOS contains driver information table.\n");
3008 lcd_ofs = (*(u16 *)(driv_inf_tab + 10));
3011 par->lcd_table = bios_base + lcd_ofs;
3015 if (par->lcd_table != 0) {
3018 char refresh_rates_buf[100];
3019 int id, tech, f, i, m, default_refresh_rate;
3024 u16 width, height, panel_type, refresh_rates;
3027 u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200};
3028 /* The most important information is the panel size at
3029 * offset 25 and 27, but there's some other nice information
3030 * which we print to the screen.
3032 id = *(u8 *)par->lcd_table;
3033 strncpy(model,(char *)par->lcd_table+1,24);
3036 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3037 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3038 panel_type = *(u16 *)(par->lcd_table+29);
3040 txtcolour = "colour";
3042 txtcolour = "monochrome";
3044 txtdual = "dual (split) ";
3047 tech = (panel_type>>2) & 63;
3050 txtmonitor = "passive matrix";
3053 txtmonitor = "active matrix";
3056 txtmonitor = "active addressed STN";
3062 txtmonitor = "plasma";
3065 txtmonitor = "unknown";
3067 format = *(u32 *)(par->lcd_table+57);
3068 if (tech == 0 || tech == 2) {
3069 switch (format & 7) {
3071 txtformat = "12 bit interface";
3074 txtformat = "16 bit interface";
3077 txtformat = "24 bit interface";
3080 txtformat = "unkown format";
3083 switch (format & 7) {
3085 txtformat = "8 colours";
3088 txtformat = "512 colours";
3091 txtformat = "4096 colours";
3094 txtformat = "262144 colours (LT mode)";
3097 txtformat = "16777216 colours";
3100 txtformat = "262144 colours (FDPI-2 mode)";
3103 txtformat = "unkown format";
3106 PRINTKI("%s%s %s monitor detected: %s\n",
3107 txtdual ,txtcolour, txtmonitor, model);
3108 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3109 id, width, height, txtformat);
3110 refresh_rates_buf[0] = 0;
3111 refresh_rates = *(u16 *)(par->lcd_table+62);
3114 for (i=0;i<16;i++) {
3115 if (refresh_rates & m) {
3117 sprintf(strbuf, "%d", lcd_refresh_rates[i]);
3120 sprintf(strbuf, ",%d", lcd_refresh_rates[i]);
3122 strcat(refresh_rates_buf,strbuf);
3126 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3127 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3128 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3129 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3130 /* We now need to determine the crtc parameters for the
3131 * lcd monitor. This is tricky, because they are not stored
3132 * individually in the BIOS. Instead, the BIOS contains a
3133 * table of display modes that work for this monitor.
3135 * The idea is that we search for a mode of the same dimensions
3136 * as the dimensions of the lcd monitor. Say our lcd monitor
3137 * is 800x600 pixels, we search for a 800x600 monitor.
3138 * The CRTC parameters we find here are the ones that we need
3139 * to use to simulate other resolutions on the lcd screen.
3141 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3142 while (*lcdmodeptr != 0) {
3144 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3145 modeptr = bios_base + *lcdmodeptr;
3147 mwidth = *((u16 *)(modeptr+0));
3148 mheight = *((u16 *)(modeptr+2));
3150 if (mwidth == width && mheight == height) {
3151 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3152 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3153 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3154 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3155 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3156 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3158 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3159 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3160 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3161 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3163 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3164 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3165 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3166 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3172 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3173 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3174 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3175 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3181 if (*lcdmodeptr == 0) {
3182 PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3183 /* To do: Switch to CRT if possible. */
3185 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3186 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3188 par->lcd_hdisp + par->lcd_right_margin,
3189 par->lcd_hdisp + par->lcd_right_margin
3190 + par->lcd_hsync_dly + par->lcd_hsync_len,
3193 par->lcd_vdisp + par->lcd_lower_margin,
3194 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3196 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
3198 par->lcd_hblank_len - (par->lcd_right_margin +
3199 par->lcd_hsync_dly + par->lcd_hsync_len),
3201 par->lcd_right_margin,
3203 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3205 par->lcd_lower_margin,
3206 par->lcd_vsync_len);
3210 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
3212 static int __devinit init_from_bios(struct atyfb_par *par)
3214 u32 bios_base, rom_addr;
3217 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3218 bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3220 /* The BIOS starts with 0xaa55. */
3221 if (*((u16 *)bios_base) == 0xaa55) {
3224 u16 rom_table_offset, freq_table_offset;
3225 PLL_BLOCK_MACH64 pll_block;
3227 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3229 /* check for frequncy table */
3230 bios_ptr = (u8*)bios_base;
3231 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3232 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3233 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3235 PRINTKI("BIOS frequency table:\n");
3236 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3237 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3238 pll_block.ref_freq, pll_block.ref_divider);
3239 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3240 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3241 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3243 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3244 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3245 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3246 par->pll_limits.ref_div = pll_block.ref_divider;
3247 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3248 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3249 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3250 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3251 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3252 aty_init_lcd(par, bios_base);
3256 PRINTKE("no BIOS frequency table found, use parameters\n");
3259 iounmap((void* __iomem )bios_base);
3263 #endif /* __i386__ */
3265 static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr)
3267 struct atyfb_par *par = info->par;
3269 unsigned long raddr;
3270 struct resource *rrp;
3273 raddr = addr + 0x7ff000UL;
3274 rrp = &pdev->resource[2];
3275 if ((rrp->flags & IORESOURCE_MEM) && request_mem_region(rrp->start, rrp->end - rrp->start + 1, "atyfb")) {
3276 par->aux_start = rrp->start;
3277 par->aux_size = rrp->end - rrp->start + 1;
3279 PRINTKI("using auxiliary register aperture\n");
3282 info->fix.mmio_start = raddr;
3283 par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
3284 if (par->ati_regbase == 0)
3287 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3288 par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3291 * Enable memory-space accesses using config-space
3294 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3295 if (!(tmp & PCI_COMMAND_MEMORY)) {
3296 tmp |= PCI_COMMAND_MEMORY;
3297 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3300 /* Use the big-endian aperture */
3304 /* Map in frame buffer */
3305 info->fix.smem_start = addr;
3306 info->screen_base = ioremap(addr, 0x800000);
3307 if (info->screen_base == NULL) {
3309 goto atyfb_setup_generic_fail;
3312 if((ret = correct_chipset(par)))
3313 goto atyfb_setup_generic_fail;
3315 if((ret = init_from_bios(par)))
3316 goto atyfb_setup_generic_fail;
3318 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3319 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3321 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3323 /* according to ATI, we should use clock 3 for acelerated mode */
3324 par->clk_wr_offset = 3;
3328 atyfb_setup_generic_fail:
3329 iounmap(par->ati_regbase);
3330 par->ati_regbase = NULL;
3334 #endif /* !__sparc__ */
3336 static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3338 unsigned long addr, res_start, res_size;
3339 struct fb_info *info;
3340 struct resource *rp;
3341 struct atyfb_par *par;
3342 int i, rc = -ENOMEM;
3344 for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--)
3345 if (pdev->device == aty_chips[i].pci_id)
3351 /* Enable device in PCI config */
3352 if (pci_enable_device(pdev)) {
3353 PRINTKE("Cannot enable PCI device\n");
3357 /* Find which resource to use */
3358 rp = &pdev->resource[0];
3359 if (rp->flags & IORESOURCE_IO)
3360 rp = &pdev->resource[1];
3366 res_start = rp->start;
3367 res_size = rp->end - rp->start + 1;
3368 if (!request_mem_region (res_start, res_size, "atyfb"))
3371 /* Allocate framebuffer */
3372 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3374 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
3378 info->fix = atyfb_fix;
3379 info->device = &pdev->dev;
3380 par->pci_id = aty_chips[i].pci_id;
3381 par->res_start = res_start;
3382 par->res_size = res_size;
3383 par->irq = pdev->irq;
3385 /* Setup "info" structure */
3387 rc = atyfb_setup_sparc(pdev, info, addr);
3389 rc = atyfb_setup_generic(pdev, info, addr);
3392 goto err_release_mem;
3394 pci_set_drvdata(pdev, info);
3396 /* Init chip & register framebuffer */
3397 if (aty_init(info, "PCI"))
3398 goto err_release_io;
3402 prom_palette = atyfb_palette;
3405 * Add /dev/fb mmap values.
3407 par->mmap_map[0].voff = 0x8000000000000000UL;
3408 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3409 par->mmap_map[0].size = info->fix.smem_len;
3410 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3411 par->mmap_map[0].prot_flag = _PAGE_E;
3412 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3413 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3414 par->mmap_map[1].size = PAGE_SIZE;
3415 par->mmap_map[1].prot_mask = _PAGE_CACHE;
3416 par->mmap_map[1].prot_flag = _PAGE_E;
3417 #endif /* __sparc__ */
3423 kfree(par->mmap_map);
3425 if (par->ati_regbase)
3426 iounmap(par->ati_regbase);
3427 if (info->screen_base)
3428 iounmap(info->screen_base);
3432 release_mem_region(par->aux_start, par->aux_size);
3434 release_mem_region(par->res_start, par->res_size);
3435 framebuffer_release(info);
3440 #endif /* CONFIG_PCI */
3444 static int __devinit atyfb_atari_probe(void)
3446 struct aty_par *par;
3447 struct fb_info *info;
3451 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3452 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3453 !phys_guiregbase[m64_num]) {
3454 PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num);
3458 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3460 PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
3465 info->fix = atyfb_fix;
3467 par->irq = (unsigned int) -1; /* something invalid */
3470 * Map the video memory (physical address given) to somewhere in the
3471 * kernel address space.
3473 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
3474 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
3475 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3477 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */
3479 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3480 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3482 switch (clock_r & 0x003F) {
3484 par->clk_wr_offset = 3; /* */
3487 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
3490 par->clk_wr_offset = 1; /* */
3493 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
3497 if (aty_init(info, "ISA bus")) {
3498 framebuffer_release(info);
3499 /* This is insufficient! kernel_map has added two large chunks!! */
3505 #endif /* CONFIG_ATARI */
3507 static void __devexit atyfb_remove(struct fb_info *info)
3509 struct atyfb_par *par = (struct atyfb_par *) info->par;
3511 /* restore video mode */
3512 aty_set_crtc(par, &saved_crtc);
3513 par->pll_ops->set_pll(info, &saved_pll);
3515 unregister_framebuffer(info);
3518 if (par->mtrr_reg >= 0) {
3519 mtrr_del(par->mtrr_reg, 0, 0);
3522 if (par->mtrr_aper >= 0) {
3523 mtrr_del(par->mtrr_aper, 0, 0);
3524 par->mtrr_aper = -1;
3528 if (par->ati_regbase)
3529 iounmap(par->ati_regbase);
3530 if (info->screen_base)
3531 iounmap(info->screen_base);
3533 if (info->sprite.addr)
3534 iounmap(info->sprite.addr);
3538 kfree(par->mmap_map);
3541 release_mem_region(par->aux_start, par->aux_size);
3544 release_mem_region(par->res_start, par->res_size);
3546 framebuffer_release(info);
3551 static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3553 struct fb_info *info = pci_get_drvdata(pdev);
3559 * This driver uses its own matching table. That will be more difficult
3560 * to fix, so for now, we just match against any ATI ID and let the
3561 * probe() function find out what's up. That also mean we don't have
3562 * a module ID table though.
3564 static struct pci_device_id atyfb_pci_tbl[] = {
3565 { PCI_VENDOR_ID_ATI, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
3566 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 },
3570 static struct pci_driver atyfb_driver = {
3572 .id_table = atyfb_pci_tbl,
3573 .probe = atyfb_pci_probe,
3574 .remove = __devexit_p(atyfb_pci_remove),
3576 .suspend = atyfb_pci_suspend,
3577 .resume = atyfb_pci_resume,
3578 #endif /* CONFIG_PM */
3581 #endif /* CONFIG_PCI */
3584 static int __init atyfb_setup(char *options)
3588 if (!options || !*options)
3591 while ((this_opt = strsep(&options, ",")) != NULL) {
3592 if (!strncmp(this_opt, "noaccel", 7)) {
3595 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3598 } else if (!strncmp(this_opt, "vram:", 5))
3599 vram = simple_strtoul(this_opt + 5, NULL, 0);
3600 else if (!strncmp(this_opt, "pll:", 4))
3601 pll = simple_strtoul(this_opt + 4, NULL, 0);
3602 else if (!strncmp(this_opt, "mclk:", 5))
3603 mclk = simple_strtoul(this_opt + 5, NULL, 0);
3604 else if (!strncmp(this_opt, "xclk:", 5))
3605 xclk = simple_strtoul(this_opt+5, NULL, 0);
3606 else if (!strncmp(this_opt, "comp_sync:", 10))
3607 comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3609 else if (!strncmp(this_opt, "vmode:", 6)) {
3610 unsigned int vmode =
3611 simple_strtoul(this_opt + 6, NULL, 0);
3612 if (vmode > 0 && vmode <= VMODE_MAX)
3613 default_vmode = vmode;
3614 } else if (!strncmp(this_opt, "cmode:", 6)) {
3615 unsigned int cmode =
3616 simple_strtoul(this_opt + 6, NULL, 0);
3620 default_cmode = CMODE_8;
3624 default_cmode = CMODE_16;
3628 default_cmode = CMODE_32;
3635 * Why do we need this silly Mach64 argument?
3636 * We are already here because of mach64= so its redundant.
3638 else if (MACH_IS_ATARI
3639 && (!strncmp(this_opt, "Mach64:", 7))) {
3640 static unsigned char m64_num;
3641 static char mach64_str[80];
3642 strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3643 if (!store_video_par(mach64_str, m64_num)) {
3645 mach64_count = m64_num;
3656 static int __init atyfb_init(void)
3659 char *option = NULL;
3661 if (fb_get_options("atyfb", &option))
3663 atyfb_setup(option);
3667 pci_register_driver(&atyfb_driver);
3670 atyfb_atari_probe();
3675 static void __exit atyfb_exit(void)
3678 pci_unregister_driver(&atyfb_driver);
3682 module_init(atyfb_init);
3683 module_exit(atyfb_exit);
3685 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
3686 MODULE_LICENSE("GPL");
3687 module_param(noaccel, bool, 0);
3688 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
3689 module_param(vram, int, 0);
3690 MODULE_PARM_DESC(vram, "int: override size of video ram");
3691 module_param(pll, int, 0);
3692 MODULE_PARM_DESC(pll, "int: override video clock");
3693 module_param(mclk, int, 0);
3694 MODULE_PARM_DESC(mclk, "int: override memory clock");
3695 module_param(xclk, int, 0);
3696 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3697 module_param(comp_sync, int, 0);
3698 MODULE_PARM_DESC(comp_sync,
3699 "Set composite sync signal to low (0) or high (1)");
3700 module_param(mode, charp, 0);
3701 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3703 module_param(nomtrr, bool, 0);
3704 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");