0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #include <linux/compat.h>
0052 #include <linux/module.h>
0053 #include <linux/moduleparam.h>
0054 #include <linux/kernel.h>
0055 #include <linux/errno.h>
0056 #include <linux/string.h>
0057 #include <linux/mm.h>
0058 #include <linux/slab.h>
0059 #include <linux/vmalloc.h>
0060 #include <linux/delay.h>
0061 #include <linux/compiler.h>
0062 #include <linux/console.h>
0063 #include <linux/fb.h>
0064 #include <linux/init.h>
0065 #include <linux/pci.h>
0066 #include <linux/interrupt.h>
0067 #include <linux/spinlock.h>
0068 #include <linux/wait.h>
0069 #include <linux/backlight.h>
0070 #include <linux/reboot.h>
0071 #include <linux/dmi.h>
0072
0073 #include <asm/io.h>
0074 #include <linux/uaccess.h>
0075
0076 #include <video/mach64.h>
0077 #include "atyfb.h"
0078 #include "ati_ids.h"
0079
0080 #ifdef __powerpc__
0081 #include <asm/machdep.h>
0082 #include "../macmodes.h"
0083 #endif
0084 #ifdef __sparc__
0085 #include <asm/fbio.h>
0086 #include <asm/oplib.h>
0087 #include <asm/prom.h>
0088 #endif
0089
0090 #ifdef CONFIG_ADB_PMU
0091 #include <linux/adb.h>
0092 #include <linux/pmu.h>
0093 #endif
0094 #ifdef CONFIG_BOOTX_TEXT
0095 #include <asm/btext.h>
0096 #endif
0097 #ifdef CONFIG_PMAC_BACKLIGHT
0098 #include <asm/backlight.h>
0099 #endif
0100
0101
0102
0103
0104 #undef DEBUG
0105
0106
0107
0108
0109
0110 #define GUI_RESERVE (1 * PAGE_SIZE)
0111
0112
0113 #define FAIL(msg) do { \
0114 if (!(var->activate & FB_ACTIVATE_TEST)) \
0115 printk(KERN_CRIT "atyfb: " msg "\n"); \
0116 return -EINVAL; \
0117 } while (0)
0118 #define FAIL_MAX(msg, x, _max_) do { \
0119 if (x > _max_) { \
0120 if (!(var->activate & FB_ACTIVATE_TEST)) \
0121 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
0122 return -EINVAL; \
0123 } \
0124 } while (0)
0125 #ifdef DEBUG
0126 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
0127 #else
0128 #define DPRINTK(fmt, args...) no_printk(fmt, ##args)
0129 #endif
0130
0131 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
0132 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
0133
0134 #if defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_GENERIC_LCD) || \
0135 defined(CONFIG_FB_ATY_BACKLIGHT) || defined (CONFIG_PPC_PMAC)
0136 static const u32 lt_lcd_regs[] = {
0137 CNFG_PANEL_LG,
0138 LCD_GEN_CNTL_LG,
0139 DSTN_CONTROL_LG,
0140 HFB_PITCH_ADDR_LG,
0141 HORZ_STRETCHING_LG,
0142 VERT_STRETCHING_LG,
0143 0,
0144 LT_GIO_LG,
0145 POWER_MANAGEMENT_LG
0146 };
0147
0148 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
0149 {
0150 if (M64_HAS(LT_LCD_REGS)) {
0151 aty_st_le32(lt_lcd_regs[index], val, par);
0152 } else {
0153 unsigned long temp;
0154
0155
0156 temp = aty_ld_le32(LCD_INDEX, par);
0157 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
0158
0159 aty_st_le32(LCD_DATA, val, par);
0160 }
0161 }
0162
0163 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
0164 {
0165 if (M64_HAS(LT_LCD_REGS)) {
0166 return aty_ld_le32(lt_lcd_regs[index], par);
0167 } else {
0168 unsigned long temp;
0169
0170
0171 temp = aty_ld_le32(LCD_INDEX, par);
0172 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
0173
0174 return aty_ld_le32(LCD_DATA, par);
0175 }
0176 }
0177 #else
0178
0179 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
0180 { }
0181
0182 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
0183 {
0184 return 0;
0185 }
0186 #endif
0187
0188
0189 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0190
0191
0192
0193
0194
0195
0196 static void ATIReduceRatio(int *Numerator, int *Denominator)
0197 {
0198 int Multiplier, Divider, Remainder;
0199
0200 Multiplier = *Numerator;
0201 Divider = *Denominator;
0202
0203 while ((Remainder = Multiplier % Divider)) {
0204 Multiplier = Divider;
0205 Divider = Remainder;
0206 }
0207
0208 *Numerator /= Divider;
0209 *Denominator /= Divider;
0210 }
0211 #endif
0212
0213
0214
0215
0216 struct pci_mmap_map {
0217 unsigned long voff;
0218 unsigned long poff;
0219 unsigned long size;
0220 unsigned long prot_flag;
0221 unsigned long prot_mask;
0222 };
0223
0224 static const struct fb_fix_screeninfo atyfb_fix = {
0225 .id = "ATY Mach64",
0226 .type = FB_TYPE_PACKED_PIXELS,
0227 .visual = FB_VISUAL_PSEUDOCOLOR,
0228 .xpanstep = 8,
0229 .ypanstep = 1,
0230 };
0231
0232
0233
0234
0235
0236 static int atyfb_open(struct fb_info *info, int user);
0237 static int atyfb_release(struct fb_info *info, int user);
0238 static int atyfb_check_var(struct fb_var_screeninfo *var,
0239 struct fb_info *info);
0240 static int atyfb_set_par(struct fb_info *info);
0241 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
0242 u_int transp, struct fb_info *info);
0243 static int atyfb_pan_display(struct fb_var_screeninfo *var,
0244 struct fb_info *info);
0245 static int atyfb_blank(int blank, struct fb_info *info);
0246 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
0247 #ifdef CONFIG_COMPAT
0248 static int atyfb_compat_ioctl(struct fb_info *info, u_int cmd, u_long arg)
0249 {
0250 return atyfb_ioctl(info, cmd, (u_long)compat_ptr(arg));
0251 }
0252 #endif
0253
0254 #ifdef __sparc__
0255 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
0256 #endif
0257 static int atyfb_sync(struct fb_info *info);
0258
0259
0260
0261
0262
0263 static int aty_init(struct fb_info *info);
0264
0265 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
0266
0267 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
0268 static int aty_var_to_crtc(const struct fb_info *info,
0269 const struct fb_var_screeninfo *var,
0270 struct crtc *crtc);
0271 static int aty_crtc_to_var(const struct crtc *crtc,
0272 struct fb_var_screeninfo *var);
0273 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
0274 #ifdef CONFIG_PPC
0275 static int read_aty_sense(const struct atyfb_par *par);
0276 #endif
0277
0278 static DEFINE_MUTEX(reboot_lock);
0279 static struct fb_info *reboot_info;
0280
0281
0282
0283
0284
0285 static struct fb_var_screeninfo default_var = {
0286
0287 640, 480, 640, 480, 0, 0, 8, 0,
0288 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
0289 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
0290 0, FB_VMODE_NONINTERLACED
0291 };
0292
0293 static const struct fb_videomode defmode = {
0294
0295 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
0296 0, FB_VMODE_NONINTERLACED
0297 };
0298
0299 static struct fb_ops atyfb_ops = {
0300 .owner = THIS_MODULE,
0301 .fb_open = atyfb_open,
0302 .fb_release = atyfb_release,
0303 .fb_check_var = atyfb_check_var,
0304 .fb_set_par = atyfb_set_par,
0305 .fb_setcolreg = atyfb_setcolreg,
0306 .fb_pan_display = atyfb_pan_display,
0307 .fb_blank = atyfb_blank,
0308 .fb_ioctl = atyfb_ioctl,
0309 #ifdef CONFIG_COMPAT
0310 .fb_compat_ioctl = atyfb_compat_ioctl,
0311 #endif
0312 .fb_fillrect = atyfb_fillrect,
0313 .fb_copyarea = atyfb_copyarea,
0314 .fb_imageblit = atyfb_imageblit,
0315 #ifdef __sparc__
0316 .fb_mmap = atyfb_mmap,
0317 #endif
0318 .fb_sync = atyfb_sync,
0319 };
0320
0321 static bool noaccel;
0322 static bool nomtrr;
0323 static int vram;
0324 static int pll;
0325 static int mclk;
0326 static int xclk;
0327 static int comp_sync = -1;
0328 static char *mode;
0329 static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);
0330
0331 #ifdef CONFIG_PPC
0332 static int default_vmode = VMODE_CHOOSE;
0333 static int default_cmode = CMODE_CHOOSE;
0334
0335 module_param_named(vmode, default_vmode, int, 0);
0336 MODULE_PARM_DESC(vmode, "int: video mode for mac");
0337 module_param_named(cmode, default_cmode, int, 0);
0338 MODULE_PARM_DESC(cmode, "int: color mode for mac");
0339 #endif
0340
0341 #ifdef CONFIG_ATARI
0342 static unsigned int mach64_count = 0;
0343 static unsigned long phys_vmembase[FB_MAX] = { 0, };
0344 static unsigned long phys_size[FB_MAX] = { 0, };
0345 static unsigned long phys_guiregbase[FB_MAX] = { 0, };
0346 #endif
0347
0348
0349 #define ATI_CHIP_88800GX (M64F_GX)
0350 #define ATI_CHIP_88800CX (M64F_GX)
0351
0352 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
0353 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
0354
0355 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
0356 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
0357
0358 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
0359 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
0360 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
0361
0362
0363 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
0364
0365
0366 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
0367
0368 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
0369
0370 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
0371
0372 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
0373 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
0374 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
0375
0376 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM)
0377 #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS)
0378
0379 static struct {
0380 u16 pci_id;
0381 const char *name;
0382 int pll, mclk, xclk, ecp_max;
0383 u32 features;
0384 } aty_chips[] = {
0385 #ifdef CONFIG_FB_ATY_GX
0386
0387 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
0388 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
0389 #endif
0390
0391 #ifdef CONFIG_FB_ATY_CT
0392 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
0393 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
0394
0395
0396 { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
0397
0398 { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
0399 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
0400
0401 { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
0402 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
0403
0404 { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
0405
0406 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
0407
0408 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
0409 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
0410 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
0411 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
0412
0413 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
0414 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
0415 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
0416 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
0417 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
0418
0419 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
0420 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
0421 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
0422 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
0423 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
0424
0425 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
0426 { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
0427 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
0428 { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
0429 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
0430 { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
0431
0432 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
0433 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
0434 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
0435 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
0436 #endif
0437 };
0438
0439
0440
0441
0442
0443 static void aty_fudge_framebuffer_len(struct fb_info *info)
0444 {
0445 struct atyfb_par *par = (struct atyfb_par *) info->par;
0446
0447 if (!par->aux_start &&
0448 (info->fix.smem_len == 0x800000 ||
0449 (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
0450 info->fix.smem_len -= GUI_RESERVE;
0451 }
0452
0453 static int correct_chipset(struct atyfb_par *par)
0454 {
0455 u8 rev;
0456 u16 type;
0457 u32 chip_id;
0458 const char *name;
0459 int i;
0460
0461 for (i = (int)ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
0462 if (par->pci_id == aty_chips[i].pci_id)
0463 break;
0464
0465 if (i < 0)
0466 return -ENODEV;
0467
0468 name = aty_chips[i].name;
0469 par->pll_limits.pll_max = aty_chips[i].pll;
0470 par->pll_limits.mclk = aty_chips[i].mclk;
0471 par->pll_limits.xclk = aty_chips[i].xclk;
0472 par->pll_limits.ecp_max = aty_chips[i].ecp_max;
0473 par->features = aty_chips[i].features;
0474
0475 chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
0476 type = chip_id & CFG_CHIP_TYPE;
0477 rev = (chip_id & CFG_CHIP_REV) >> 24;
0478
0479 switch (par->pci_id) {
0480 #ifdef CONFIG_FB_ATY_GX
0481 case PCI_CHIP_MACH64GX:
0482 if (type != 0x00d7)
0483 return -ENODEV;
0484 break;
0485 case PCI_CHIP_MACH64CX:
0486 if (type != 0x0057)
0487 return -ENODEV;
0488 break;
0489 #endif
0490 #ifdef CONFIG_FB_ATY_CT
0491 case PCI_CHIP_MACH64VT:
0492 switch (rev & 0x07) {
0493 case 0x00:
0494 switch (rev & 0xc0) {
0495 case 0x00:
0496 name = "ATI264VT (A3) (Mach64 VT)";
0497 par->pll_limits.pll_max = 170;
0498 par->pll_limits.mclk = 67;
0499 par->pll_limits.xclk = 67;
0500 par->pll_limits.ecp_max = 80;
0501 par->features = ATI_CHIP_264VT;
0502 break;
0503 case 0x40:
0504 name = "ATI264VT2 (A4) (Mach64 VT)";
0505 par->pll_limits.pll_max = 200;
0506 par->pll_limits.mclk = 67;
0507 par->pll_limits.xclk = 67;
0508 par->pll_limits.ecp_max = 80;
0509 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
0510 break;
0511 }
0512 break;
0513 case 0x01:
0514 name = "ATI264VT3 (B1) (Mach64 VT)";
0515 par->pll_limits.pll_max = 200;
0516 par->pll_limits.mclk = 67;
0517 par->pll_limits.xclk = 67;
0518 par->pll_limits.ecp_max = 80;
0519 par->features = ATI_CHIP_264VTB;
0520 break;
0521 case 0x02:
0522 name = "ATI264VT3 (B2) (Mach64 VT)";
0523 par->pll_limits.pll_max = 200;
0524 par->pll_limits.mclk = 67;
0525 par->pll_limits.xclk = 67;
0526 par->pll_limits.ecp_max = 80;
0527 par->features = ATI_CHIP_264VT3;
0528 break;
0529 }
0530 break;
0531 case PCI_CHIP_MACH64GT:
0532 switch (rev & 0x07) {
0533 case 0x01:
0534 name = "3D RAGE II (Mach64 GT)";
0535 par->pll_limits.pll_max = 170;
0536 par->pll_limits.mclk = 67;
0537 par->pll_limits.xclk = 67;
0538 par->pll_limits.ecp_max = 80;
0539 par->features = ATI_CHIP_264GTB;
0540 break;
0541 case 0x02:
0542 name = "3D RAGE II+ (Mach64 GT)";
0543 par->pll_limits.pll_max = 200;
0544 par->pll_limits.mclk = 67;
0545 par->pll_limits.xclk = 67;
0546 par->pll_limits.ecp_max = 100;
0547 par->features = ATI_CHIP_264GTB;
0548 break;
0549 }
0550 break;
0551 #endif
0552 }
0553
0554 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
0555 return 0;
0556 }
0557
0558 static char ram_dram[] __maybe_unused = "DRAM";
0559 static char ram_resv[] __maybe_unused = "RESV";
0560 #ifdef CONFIG_FB_ATY_GX
0561 static char ram_vram[] = "VRAM";
0562 #endif
0563 #ifdef CONFIG_FB_ATY_CT
0564 static char ram_edo[] = "EDO";
0565 static char ram_sdram[] = "SDRAM (1:1)";
0566 static char ram_sgram[] = "SGRAM (1:1)";
0567 static char ram_sdram32[] = "SDRAM (2:1) (32-bit)";
0568 static char ram_wram[] = "WRAM";
0569 static char ram_off[] = "OFF";
0570 #endif
0571
0572
0573 #ifdef CONFIG_FB_ATY_GX
0574 static char *aty_gx_ram[8] = {
0575 ram_dram, ram_vram, ram_vram, ram_dram,
0576 ram_dram, ram_vram, ram_vram, ram_resv
0577 };
0578 #endif
0579
0580 #ifdef CONFIG_FB_ATY_CT
0581 static char *aty_ct_ram[8] = {
0582 ram_off, ram_dram, ram_edo, ram_edo,
0583 ram_sdram, ram_sgram, ram_wram, ram_resv
0584 };
0585 static char *aty_xl_ram[8] = {
0586 ram_off, ram_dram, ram_edo, ram_edo,
0587 ram_sdram, ram_sgram, ram_sdram32, ram_resv
0588 };
0589 #endif
0590
0591 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var,
0592 struct atyfb_par *par)
0593 {
0594 u32 pixclock = var->pixclock;
0595 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0596 u32 lcd_on_off;
0597 par->pll.ct.xres = 0;
0598 if (par->lcd_table != 0) {
0599 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
0600 if (lcd_on_off & LCD_ON) {
0601 par->pll.ct.xres = var->xres;
0602 pixclock = par->lcd_pixclock;
0603 }
0604 }
0605 #endif
0606 return pixclock;
0607 }
0608
0609 #if defined(CONFIG_PPC)
0610
0611
0612
0613
0614
0615 static int read_aty_sense(const struct atyfb_par *par)
0616 {
0617 int sense, i;
0618
0619 aty_st_le32(GP_IO, 0x31003100, par);
0620 __delay(200);
0621 aty_st_le32(GP_IO, 0, par);
0622 __delay(2000);
0623 i = aty_ld_le32(GP_IO, par);
0624 sense = ((i & 0x3000) >> 3) | (i & 0x100);
0625
0626
0627 aty_st_le32(GP_IO, 0x20000000, par);
0628 __delay(2000);
0629 i = aty_ld_le32(GP_IO, par);
0630 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
0631 aty_st_le32(GP_IO, 0x20002000, par);
0632 __delay(200);
0633
0634 aty_st_le32(GP_IO, 0x10000000, par);
0635 __delay(2000);
0636 i = aty_ld_le32(GP_IO, par);
0637 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
0638 aty_st_le32(GP_IO, 0x10001000, par);
0639 __delay(200);
0640
0641 aty_st_le32(GP_IO, 0x01000000, par);
0642 __delay(2000);
0643 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
0644 aty_st_le32(GP_IO, 0, par);
0645 return sense;
0646 }
0647
0648 #endif
0649
0650
0651
0652
0653
0654
0655
0656 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
0657 {
0658 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0659 if (par->lcd_table != 0) {
0660 if (!M64_HAS(LT_LCD_REGS)) {
0661 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
0662 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
0663 }
0664 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
0665 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
0666
0667
0668
0669 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
0670 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
0671
0672
0673 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
0674 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
0675 if (!M64_HAS(LT_LCD_REGS))
0676 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
0677 }
0678 #endif
0679 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
0680 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
0681 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
0682 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
0683 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
0684 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
0685 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
0686
0687 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0688 if (par->lcd_table != 0) {
0689
0690 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
0691 SHADOW_EN | SHADOW_RW_EN, par);
0692
0693 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
0694 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
0695 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
0696 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
0697
0698 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
0699 }
0700 #endif
0701 }
0702
0703 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
0704 {
0705 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0706 if (par->lcd_table != 0) {
0707
0708 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl &
0709 ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
0710
0711
0712 aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
0713 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
0714 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
0715
0716
0717 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching &
0718 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
0719 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching &
0720 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
0721 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
0722 }
0723 #endif
0724
0725 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
0726
0727 DPRINTK("setting up CRTC\n");
0728 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
0729 ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3),
0730 (((crtc->v_tot_disp >> 16) & 0x7ff) + 1),
0731 (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P',
0732 (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P',
0733 (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N');
0734
0735 DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp);
0736 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid);
0737 DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp);
0738 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid);
0739 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
0740 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
0741 DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl);
0742
0743 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
0744 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
0745 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
0746 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
0747 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
0748 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
0749
0750 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
0751 #if 0
0752 FIXME
0753 if (par->accel_flags & FB_ACCELF_TEXT)
0754 aty_init_engine(par, info);
0755 #endif
0756 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0757
0758 if (par->lcd_table != 0) {
0759
0760 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
0761 SHADOW_EN | SHADOW_RW_EN, par);
0762
0763 DPRINTK("set shadow CRT to %ix%i %c%c\n",
0764 ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3),
0765 (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1),
0766 (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P',
0767 (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P');
0768
0769 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n",
0770 crtc->shadow_h_tot_disp);
0771 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n",
0772 crtc->shadow_h_sync_strt_wid);
0773 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n",
0774 crtc->shadow_v_tot_disp);
0775 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n",
0776 crtc->shadow_v_sync_strt_wid);
0777
0778 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
0779 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
0780 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
0781 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
0782
0783
0784 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
0785 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
0786 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
0787 if (!M64_HAS(LT_LCD_REGS))
0788 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
0789
0790 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
0791 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
0792 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
0793 if (!M64_HAS(LT_LCD_REGS)) {
0794 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
0795 aty_ld_le32(LCD_INDEX, par);
0796 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
0797 }
0798 }
0799 #endif
0800 }
0801
0802 static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp)
0803 {
0804 u32 line_length = vxres * bpp / 8;
0805
0806 if (par->ram_type == SGRAM ||
0807 (!M64_HAS(XL_MEM) && par->ram_type == WRAM))
0808 line_length = (line_length + 63) & ~63;
0809
0810 return line_length;
0811 }
0812
0813 static int aty_var_to_crtc(const struct fb_info *info,
0814 const struct fb_var_screeninfo *var,
0815 struct crtc *crtc)
0816 {
0817 struct atyfb_par *par = (struct atyfb_par *) info->par;
0818 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
0819 u32 sync, vmode;
0820 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
0821 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
0822 u32 pix_width, dp_pix_width, dp_chain_mask;
0823 u32 line_length;
0824
0825
0826 xres = (var->xres + 7) & ~7;
0827 yres = var->yres;
0828 vxres = (var->xres_virtual + 7) & ~7;
0829 vyres = var->yres_virtual;
0830 xoffset = (var->xoffset + 7) & ~7;
0831 yoffset = var->yoffset;
0832 bpp = var->bits_per_pixel;
0833 if (bpp == 16)
0834 bpp = (var->green.length == 5) ? 15 : 16;
0835 sync = var->sync;
0836 vmode = var->vmode;
0837
0838
0839 if (vxres < xres + xoffset)
0840 vxres = xres + xoffset;
0841 h_disp = xres;
0842
0843 if (vyres < yres + yoffset)
0844 vyres = yres + yoffset;
0845 v_disp = yres;
0846
0847 if (bpp <= 8) {
0848 bpp = 8;
0849 pix_width = CRTC_PIX_WIDTH_8BPP;
0850 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
0851 BYTE_ORDER_LSB_TO_MSB;
0852 dp_chain_mask = DP_CHAIN_8BPP;
0853 } else if (bpp <= 15) {
0854 bpp = 16;
0855 pix_width = CRTC_PIX_WIDTH_15BPP;
0856 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
0857 BYTE_ORDER_LSB_TO_MSB;
0858 dp_chain_mask = DP_CHAIN_15BPP;
0859 } else if (bpp <= 16) {
0860 bpp = 16;
0861 pix_width = CRTC_PIX_WIDTH_16BPP;
0862 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
0863 BYTE_ORDER_LSB_TO_MSB;
0864 dp_chain_mask = DP_CHAIN_16BPP;
0865 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
0866 bpp = 24;
0867 pix_width = CRTC_PIX_WIDTH_24BPP;
0868 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
0869 BYTE_ORDER_LSB_TO_MSB;
0870 dp_chain_mask = DP_CHAIN_24BPP;
0871 } else if (bpp <= 32) {
0872 bpp = 32;
0873 pix_width = CRTC_PIX_WIDTH_32BPP;
0874 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
0875 BYTE_ORDER_LSB_TO_MSB;
0876 dp_chain_mask = DP_CHAIN_32BPP;
0877 } else
0878 FAIL("invalid bpp");
0879
0880 line_length = calc_line_length(par, vxres, bpp);
0881
0882 if (vyres * line_length > info->fix.smem_len)
0883 FAIL("not enough video RAM");
0884
0885 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
0886 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
0887
0888 if ((xres > 1920) || (yres > 1200)) {
0889 FAIL("MACH64 chips are designed for max 1920x1200\n"
0890 "select another resolution.");
0891 }
0892 h_sync_strt = h_disp + var->right_margin;
0893 h_sync_end = h_sync_strt + var->hsync_len;
0894 h_sync_dly = var->right_margin & 7;
0895 h_total = h_sync_end + h_sync_dly + var->left_margin;
0896
0897 v_sync_strt = v_disp + var->lower_margin;
0898 v_sync_end = v_sync_strt + var->vsync_len;
0899 v_total = v_sync_end + var->upper_margin;
0900
0901 #ifdef CONFIG_FB_ATY_GENERIC_LCD
0902 if (par->lcd_table != 0) {
0903 if (!M64_HAS(LT_LCD_REGS)) {
0904 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
0905 crtc->lcd_index = lcd_index &
0906 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS |
0907 LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
0908 aty_st_le32(LCD_INDEX, lcd_index, par);
0909 }
0910
0911 if (!M64_HAS(MOBIL_BUS))
0912 crtc->lcd_index |= CRTC2_DISPLAY_DIS;
0913
0914 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000;
0915 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
0916
0917 crtc->lcd_gen_cntl &=
0918 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
0919
0920 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
0921 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
0922
0923 if ((crtc->lcd_gen_cntl & LCD_ON) &&
0924 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
0925
0926
0927
0928
0929
0930
0931
0932 if (crtc->lcd_gen_cntl & CRT_ON) {
0933 if (!(var->activate & FB_ACTIVATE_TEST))
0934 PRINTKI("Disable LCD panel, because video mode does not fit.\n");
0935 crtc->lcd_gen_cntl &= ~LCD_ON;
0936
0937 } else {
0938 if (!(var->activate & FB_ACTIVATE_TEST))
0939 PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
0940 return -EINVAL;
0941 }
0942 }
0943 }
0944
0945 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
0946 int VScan = 1;
0947
0948
0949
0950
0951 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962 if (yres < par->lcd_height) {
0963 VScan = par->lcd_height / yres;
0964 if (VScan > 1) {
0965 VScan = 2;
0966 vmode |= FB_VMODE_DOUBLE;
0967 }
0968 }
0969
0970 h_sync_strt = h_disp + par->lcd_right_margin;
0971 h_sync_end = h_sync_strt + par->lcd_hsync_len;
0972 h_sync_dly = par->lcd_hsync_dly;
0973 h_total = h_disp + par->lcd_hblank_len;
0974
0975 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
0976 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
0977 v_total = v_disp + par->lcd_vblank_len / VScan;
0978 }
0979 #endif
0980
0981 h_disp = (h_disp >> 3) - 1;
0982 h_sync_strt = (h_sync_strt >> 3) - 1;
0983 h_sync_end = (h_sync_end >> 3) - 1;
0984 h_total = (h_total >> 3) - 1;
0985 h_sync_wid = h_sync_end - h_sync_strt;
0986
0987 FAIL_MAX("h_disp too large", h_disp, 0xff);
0988 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
0989
0990 if (h_sync_wid > 0x1f)
0991 h_sync_wid = 0x1f;
0992 FAIL_MAX("h_total too large", h_total, 0x1ff);
0993
0994 if (vmode & FB_VMODE_DOUBLE) {
0995 v_disp <<= 1;
0996 v_sync_strt <<= 1;
0997 v_sync_end <<= 1;
0998 v_total <<= 1;
0999 }
1000
1001 v_disp--;
1002 v_sync_strt--;
1003 v_sync_end--;
1004 v_total--;
1005 v_sync_wid = v_sync_end - v_sync_strt;
1006
1007 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
1008 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
1009
1010 if (v_sync_wid > 0x1f)
1011 v_sync_wid = 0x1f;
1012 FAIL_MAX("v_total too large", v_total, 0x7ff);
1013
1014 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
1015
1016
1017 crtc->vxres = vxres;
1018 crtc->vyres = vyres;
1019 crtc->xoffset = xoffset;
1020 crtc->yoffset = yoffset;
1021 crtc->bpp = bpp;
1022 crtc->off_pitch =
1023 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1024 ((line_length / bpp) << 22);
1025 crtc->vline_crnt_vline = 0;
1026
1027 crtc->h_tot_disp = h_total | (h_disp << 16);
1028 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) |
1029 ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
1030 (h_sync_pol << 21);
1031 crtc->v_tot_disp = v_total | (v_disp << 16);
1032 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
1033 (v_sync_pol << 21);
1034
1035
1036 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
1037 crtc->gen_cntl |= CRTC_VGA_LINEAR;
1038
1039
1040 if (vmode & FB_VMODE_DOUBLE)
1041 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
1042
1043 if (vmode & FB_VMODE_INTERLACED)
1044 crtc->gen_cntl |= CRTC_INTERLACE_EN;
1045 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1046 if (par->lcd_table != 0) {
1047 u32 vdisplay = yres;
1048 if (vmode & FB_VMODE_DOUBLE)
1049 vdisplay <<= 1;
1050 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
1051 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
1052
1053 USE_SHADOWED_VEND |
1054 USE_SHADOWED_ROWCUR |
1055 SHADOW_EN | SHADOW_RW_EN);
1056 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR;
1057
1058
1059 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
1060 if (!M64_HAS(LT_LCD_REGS))
1061 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
1062 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
1063
1064 crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO |
1065 HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
1066 HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
1067 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
1068 do {
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083 int HDisplay = xres & ~7;
1084 int nStretch = par->lcd_width / HDisplay;
1085 int Remainder = par->lcd_width % HDisplay;
1086
1087 if ((!Remainder && ((nStretch > 2))) ||
1088 (((HDisplay * 16) / par->lcd_width) < 7)) {
1089 static const char StretchLoops[] = { 10, 12, 13, 15, 16 };
1090 int horz_stretch_loop = -1, BestRemainder;
1091 int Numerator = HDisplay, Denominator = par->lcd_width;
1092 int Index = 5;
1093 ATIReduceRatio(&Numerator, &Denominator);
1094
1095 BestRemainder = (Numerator * 16) / Denominator;
1096 while (--Index >= 0) {
1097 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1098 Denominator;
1099 if (Remainder < BestRemainder) {
1100 horz_stretch_loop = Index;
1101 if (!(BestRemainder = Remainder))
1102 break;
1103 }
1104 }
1105
1106 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1107 int horz_stretch_ratio = 0, Accumulator = 0;
1108 int reuse_previous = 1;
1109
1110 Index = StretchLoops[horz_stretch_loop];
1111
1112 while (--Index >= 0) {
1113 if (Accumulator > 0)
1114 horz_stretch_ratio |= reuse_previous;
1115 else
1116 Accumulator += Denominator;
1117 Accumulator -= Numerator;
1118 reuse_previous <<= 1;
1119 }
1120
1121 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1122 ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1123 (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1124 break;
1125 }
1126 }
1127
1128 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1129 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1130 } while (0);
1131 }
1132
1133 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) {
1134 crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1135 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1136
1137 if (!M64_HAS(LT_LCD_REGS) &&
1138 xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800))
1139 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1140 } else {
1141
1142
1143
1144
1145 crtc->vert_stretching = 0;
1146 }
1147
1148 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1149 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1150 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1151 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1152 }
1153 #endif
1154
1155 if (M64_HAS(MAGIC_FIFO)) {
1156
1157 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
1158 }
1159 crtc->dp_pix_width = dp_pix_width;
1160 crtc->dp_chain_mask = dp_chain_mask;
1161
1162 return 0;
1163 }
1164
1165 static int aty_crtc_to_var(const struct crtc *crtc,
1166 struct fb_var_screeninfo *var)
1167 {
1168 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1169 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1170 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1171 u32 pix_width;
1172 u32 double_scan, interlace;
1173
1174
1175 h_total = crtc->h_tot_disp & 0x1ff;
1176 h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1177 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1178 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1179 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1180 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1181 v_total = crtc->v_tot_disp & 0x7ff;
1182 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1183 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1184 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1185 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1186 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1187 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1188 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1189 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1190
1191
1192 xres = (h_disp + 1) * 8;
1193 yres = v_disp + 1;
1194 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1195 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1196 hslen = h_sync_wid * 8;
1197 upper = v_total - v_sync_strt - v_sync_wid;
1198 lower = v_sync_strt - v_disp;
1199 vslen = v_sync_wid;
1200 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1201 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1202 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1203
1204 switch (pix_width) {
1205 case CRTC_PIX_WIDTH_8BPP:
1206 bpp = 8;
1207 var->red.offset = 0;
1208 var->red.length = 8;
1209 var->green.offset = 0;
1210 var->green.length = 8;
1211 var->blue.offset = 0;
1212 var->blue.length = 8;
1213 var->transp.offset = 0;
1214 var->transp.length = 0;
1215 break;
1216 case CRTC_PIX_WIDTH_15BPP:
1217 bpp = 16;
1218 var->red.offset = 10;
1219 var->red.length = 5;
1220 var->green.offset = 5;
1221 var->green.length = 5;
1222 var->blue.offset = 0;
1223 var->blue.length = 5;
1224 var->transp.offset = 0;
1225 var->transp.length = 0;
1226 break;
1227 case CRTC_PIX_WIDTH_16BPP:
1228 bpp = 16;
1229 var->red.offset = 11;
1230 var->red.length = 5;
1231 var->green.offset = 5;
1232 var->green.length = 6;
1233 var->blue.offset = 0;
1234 var->blue.length = 5;
1235 var->transp.offset = 0;
1236 var->transp.length = 0;
1237 break;
1238 case CRTC_PIX_WIDTH_24BPP:
1239 bpp = 24;
1240 var->red.offset = 16;
1241 var->red.length = 8;
1242 var->green.offset = 8;
1243 var->green.length = 8;
1244 var->blue.offset = 0;
1245 var->blue.length = 8;
1246 var->transp.offset = 0;
1247 var->transp.length = 0;
1248 break;
1249 case CRTC_PIX_WIDTH_32BPP:
1250 bpp = 32;
1251 var->red.offset = 16;
1252 var->red.length = 8;
1253 var->green.offset = 8;
1254 var->green.length = 8;
1255 var->blue.offset = 0;
1256 var->blue.length = 8;
1257 var->transp.offset = 24;
1258 var->transp.length = 8;
1259 break;
1260 default:
1261 PRINTKE("Invalid pixel width\n");
1262 return -EINVAL;
1263 }
1264
1265
1266 var->xres = xres;
1267 var->yres = yres;
1268 var->xres_virtual = crtc->vxres;
1269 var->yres_virtual = crtc->vyres;
1270 var->bits_per_pixel = bpp;
1271 var->left_margin = left;
1272 var->right_margin = right;
1273 var->upper_margin = upper;
1274 var->lower_margin = lower;
1275 var->hsync_len = hslen;
1276 var->vsync_len = vslen;
1277 var->sync = sync;
1278 var->vmode = FB_VMODE_NONINTERLACED;
1279
1280
1281
1282
1283
1284
1285 if (interlace)
1286 var->vmode = FB_VMODE_INTERLACED;
1287
1288 if (double_scan) {
1289 var->vmode = FB_VMODE_DOUBLE;
1290 var->yres >>= 1;
1291 var->upper_margin >>= 1;
1292 var->lower_margin >>= 1;
1293 var->vsync_len >>= 1;
1294 }
1295
1296 return 0;
1297 }
1298
1299
1300
1301 static int atyfb_set_par(struct fb_info *info)
1302 {
1303 struct atyfb_par *par = (struct atyfb_par *) info->par;
1304 struct fb_var_screeninfo *var = &info->var;
1305 u32 tmp, pixclock;
1306 int err;
1307 #ifdef DEBUG
1308 struct fb_var_screeninfo debug;
1309 u32 pixclock_in_ps;
1310 #endif
1311 if (par->asleep)
1312 return 0;
1313
1314 err = aty_var_to_crtc(info, var, &par->crtc);
1315 if (err)
1316 return err;
1317
1318 pixclock = atyfb_get_pixclock(var, par);
1319
1320 if (pixclock == 0) {
1321 PRINTKE("Invalid pixclock\n");
1322 return -EINVAL;
1323 } else {
1324 err = par->pll_ops->var_to_pll(info, pixclock,
1325 var->bits_per_pixel, &par->pll);
1326 if (err)
1327 return err;
1328 }
1329
1330 par->accel_flags = var->accel_flags;
1331
1332 if (var->accel_flags) {
1333 atyfb_ops.fb_sync = atyfb_sync;
1334 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1335 } else {
1336 atyfb_ops.fb_sync = NULL;
1337 info->flags |= FBINFO_HWACCEL_DISABLED;
1338 }
1339
1340 if (par->blitter_may_be_busy)
1341 wait_for_idle(par);
1342
1343 aty_set_crtc(par, &par->crtc);
1344 par->dac_ops->set_dac(info, &par->pll,
1345 var->bits_per_pixel, par->accel_flags);
1346 par->pll_ops->set_pll(info, &par->pll);
1347
1348 #ifdef DEBUG
1349 if (par->pll_ops && par->pll_ops->pll_to_var)
1350 pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll);
1351 else
1352 pixclock_in_ps = 0;
1353
1354 if (0 == pixclock_in_ps) {
1355 PRINTKE("ALERT ops->pll_to_var get 0\n");
1356 pixclock_in_ps = pixclock;
1357 }
1358
1359 memset(&debug, 0, sizeof(debug));
1360 if (!aty_crtc_to_var(&par->crtc, &debug)) {
1361 u32 hSync, vRefresh;
1362 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1363 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1364
1365 h_disp = debug.xres;
1366 h_sync_strt = h_disp + debug.right_margin;
1367 h_sync_end = h_sync_strt + debug.hsync_len;
1368 h_total = h_sync_end + debug.left_margin;
1369 v_disp = debug.yres;
1370 v_sync_strt = v_disp + debug.lower_margin;
1371 v_sync_end = v_sync_strt + debug.vsync_len;
1372 v_total = v_sync_end + debug.upper_margin;
1373
1374 hSync = 1000000000 / (pixclock_in_ps * h_total);
1375 vRefresh = (hSync * 1000) / v_total;
1376 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1377 vRefresh *= 2;
1378 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1379 vRefresh /= 2;
1380
1381 DPRINTK("atyfb_set_par\n");
1382 DPRINTK(" Set Visible Mode to %ix%i-%i\n",
1383 var->xres, var->yres, var->bits_per_pixel);
1384 DPRINTK(" Virtual resolution %ix%i, "
1385 "pixclock_in_ps %i (calculated %i)\n",
1386 var->xres_virtual, var->yres_virtual,
1387 pixclock, pixclock_in_ps);
1388 DPRINTK(" Dot clock: %i MHz\n",
1389 1000000 / pixclock_in_ps);
1390 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1391 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1392 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1393 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1394 h_disp, h_sync_strt, h_sync_end, h_total,
1395 v_disp, v_sync_strt, v_sync_end, v_total);
1396 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
1397 pixclock_in_ps,
1398 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1399 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1400 }
1401 #endif
1402
1403 if (!M64_HAS(INTEGRATED)) {
1404
1405 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1406 switch (var->bits_per_pixel) {
1407 case 8:
1408 tmp |= 0x02000000;
1409 break;
1410 case 16:
1411 tmp |= 0x03000000;
1412 break;
1413 case 32:
1414 tmp |= 0x06000000;
1415 break;
1416 }
1417 aty_st_le32(MEM_CNTL, tmp, par);
1418 } else {
1419 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1420 if (!M64_HAS(MAGIC_POSTDIV))
1421 tmp |= par->mem_refresh_rate << 20;
1422 switch (var->bits_per_pixel) {
1423 case 8:
1424 case 24:
1425 tmp |= 0x00000000;
1426 break;
1427 case 16:
1428 tmp |= 0x04000000;
1429 break;
1430 case 32:
1431 tmp |= 0x08000000;
1432 break;
1433 }
1434 if (M64_HAS(CT_BUS)) {
1435 aty_st_le32(DAC_CNTL, 0x87010184, par);
1436 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1437 } else if (M64_HAS(VT_BUS)) {
1438 aty_st_le32(DAC_CNTL, 0x87010184, par);
1439 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1440 } else if (M64_HAS(MOBIL_BUS)) {
1441 aty_st_le32(DAC_CNTL, 0x80010102, par);
1442 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1443 } else {
1444
1445 aty_st_le32(DAC_CNTL, 0x86010102, par);
1446 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1447 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1448 }
1449 aty_st_le32(MEM_CNTL, tmp, par);
1450 }
1451 aty_st_8(DAC_MASK, 0xff, par);
1452
1453 info->fix.line_length = calc_line_length(par, var->xres_virtual,
1454 var->bits_per_pixel);
1455
1456 info->fix.visual = var->bits_per_pixel <= 8 ?
1457 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1458
1459
1460 if (par->accel_flags & FB_ACCELF_TEXT)
1461 aty_init_engine(par, info);
1462
1463 #ifdef CONFIG_BOOTX_TEXT
1464 btext_update_display(info->fix.smem_start,
1465 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1466 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1467 var->bits_per_pixel,
1468 par->crtc.vxres * var->bits_per_pixel / 8);
1469 #endif
1470 #ifdef DEBUG
1471 {
1472
1473 int i; u32 base;
1474
1475
1476 base = 0x2000;
1477 printk("debug atyfb: Mach64 non-shadow register values:");
1478 for (i = 0; i < 256; i = i+4) {
1479 if (i % 16 == 0) {
1480 pr_cont("\n");
1481 printk("debug atyfb: 0x%04X: ", base + i);
1482 }
1483 pr_cont(" %08X", aty_ld_le32(i, par));
1484 }
1485 pr_cont("\n\n");
1486
1487 #ifdef CONFIG_FB_ATY_CT
1488
1489 base = 0x00;
1490 printk("debug atyfb: Mach64 PLL register values:");
1491 for (i = 0; i < 64; i++) {
1492 if (i % 16 == 0) {
1493 pr_cont("\n");
1494 printk("debug atyfb: 0x%02X: ", base + i);
1495 }
1496 if (i % 4 == 0)
1497 pr_cont(" ");
1498 pr_cont("%02X", aty_ld_pll_ct(i, par));
1499 }
1500 pr_cont("\n\n");
1501 #endif
1502
1503 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1504 if (par->lcd_table != 0) {
1505
1506 base = 0x00;
1507 printk("debug atyfb: LCD register values:");
1508 if (M64_HAS(LT_LCD_REGS)) {
1509 for (i = 0; i <= POWER_MANAGEMENT; i++) {
1510 if (i == EXT_VERT_STRETCH)
1511 continue;
1512 pr_cont("\ndebug atyfb: 0x%04X: ",
1513 lt_lcd_regs[i]);
1514 pr_cont(" %08X", aty_ld_lcd(i, par));
1515 }
1516 } else {
1517 for (i = 0; i < 64; i++) {
1518 if (i % 4 == 0)
1519 pr_cont("\ndebug atyfb: 0x%02X: ",
1520 base + i);
1521 pr_cont(" %08X", aty_ld_lcd(i, par));
1522 }
1523 }
1524 pr_cont("\n\n");
1525 }
1526 #endif
1527 }
1528 #endif
1529 return 0;
1530 }
1531
1532 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1533 {
1534 struct atyfb_par *par = (struct atyfb_par *) info->par;
1535 int err;
1536 struct crtc crtc;
1537 union aty_pll pll;
1538 u32 pixclock;
1539
1540 memcpy(&pll, &par->pll, sizeof(pll));
1541
1542 err = aty_var_to_crtc(info, var, &crtc);
1543 if (err)
1544 return err;
1545
1546 pixclock = atyfb_get_pixclock(var, par);
1547
1548 if (pixclock == 0) {
1549 if (!(var->activate & FB_ACTIVATE_TEST))
1550 PRINTKE("Invalid pixclock\n");
1551 return -EINVAL;
1552 } else {
1553 err = par->pll_ops->var_to_pll(info, pixclock,
1554 var->bits_per_pixel, &pll);
1555 if (err)
1556 return err;
1557 }
1558
1559 if (var->accel_flags & FB_ACCELF_TEXT)
1560 info->var.accel_flags = FB_ACCELF_TEXT;
1561 else
1562 info->var.accel_flags = 0;
1563
1564 aty_crtc_to_var(&crtc, var);
1565 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1566 return 0;
1567 }
1568
1569 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1570 {
1571 u32 xoffset = info->var.xoffset;
1572 u32 yoffset = info->var.yoffset;
1573 u32 line_length = info->fix.line_length;
1574 u32 bpp = info->var.bits_per_pixel;
1575
1576 par->crtc.off_pitch =
1577 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1578 ((line_length / bpp) << 22);
1579 }
1580
1581
1582
1583
1584
1585
1586 static int atyfb_open(struct fb_info *info, int user)
1587 {
1588 struct atyfb_par *par = (struct atyfb_par *) info->par;
1589
1590 if (user) {
1591 par->open++;
1592 #ifdef __sparc__
1593 par->mmaped = 0;
1594 #endif
1595 }
1596 return 0;
1597 }
1598
1599 static irqreturn_t aty_irq(int irq, void *dev_id)
1600 {
1601 struct atyfb_par *par = dev_id;
1602 int handled = 0;
1603 u32 int_cntl;
1604
1605 spin_lock(&par->int_lock);
1606
1607 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1608
1609 if (int_cntl & CRTC_VBLANK_INT) {
1610
1611 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) |
1612 CRTC_VBLANK_INT_AK, par);
1613 par->vblank.count++;
1614 if (par->vblank.pan_display) {
1615 par->vblank.pan_display = 0;
1616 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1617 }
1618 wake_up_interruptible(&par->vblank.wait);
1619 handled = 1;
1620 }
1621
1622 spin_unlock(&par->int_lock);
1623
1624 return IRQ_RETVAL(handled);
1625 }
1626
1627 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1628 {
1629 u32 int_cntl;
1630
1631 if (!test_and_set_bit(0, &par->irq_flags)) {
1632 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1633 clear_bit(0, &par->irq_flags);
1634 return -EINVAL;
1635 }
1636 spin_lock_irq(&par->int_lock);
1637 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1638
1639 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1640
1641 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1642 spin_unlock_irq(&par->int_lock);
1643 } else if (reenable) {
1644 spin_lock_irq(&par->int_lock);
1645 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1646 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1647 printk("atyfb: someone disabled IRQ [%08x]\n",
1648 int_cntl);
1649
1650 aty_st_le32(CRTC_INT_CNTL, int_cntl |
1651 CRTC_VBLANK_INT_EN, par);
1652 }
1653 spin_unlock_irq(&par->int_lock);
1654 }
1655
1656 return 0;
1657 }
1658
1659 static int aty_disable_irq(struct atyfb_par *par)
1660 {
1661 u32 int_cntl;
1662
1663 if (test_and_clear_bit(0, &par->irq_flags)) {
1664 if (par->vblank.pan_display) {
1665 par->vblank.pan_display = 0;
1666 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1667 }
1668 spin_lock_irq(&par->int_lock);
1669 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1670
1671 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par);
1672 spin_unlock_irq(&par->int_lock);
1673 free_irq(par->irq, par);
1674 }
1675
1676 return 0;
1677 }
1678
1679 static int atyfb_release(struct fb_info *info, int user)
1680 {
1681 struct atyfb_par *par = (struct atyfb_par *) info->par;
1682 #ifdef __sparc__
1683 int was_mmaped;
1684 #endif
1685
1686 if (!user)
1687 return 0;
1688
1689 par->open--;
1690 mdelay(1);
1691 wait_for_idle(par);
1692
1693 if (par->open)
1694 return 0;
1695
1696 #ifdef __sparc__
1697 was_mmaped = par->mmaped;
1698
1699 par->mmaped = 0;
1700
1701 if (was_mmaped) {
1702 struct fb_var_screeninfo var;
1703
1704
1705
1706
1707
1708
1709
1710 var = default_var;
1711 if (noaccel)
1712 var.accel_flags &= ~FB_ACCELF_TEXT;
1713 else
1714 var.accel_flags |= FB_ACCELF_TEXT;
1715 if (var.yres == var.yres_virtual) {
1716 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1717 var.yres_virtual =
1718 ((videoram * 8) / var.bits_per_pixel) /
1719 var.xres_virtual;
1720 if (var.yres_virtual < var.yres)
1721 var.yres_virtual = var.yres;
1722 }
1723 }
1724 #endif
1725 aty_disable_irq(par);
1726
1727 return 0;
1728 }
1729
1730
1731
1732
1733
1734
1735
1736 static int atyfb_pan_display(struct fb_var_screeninfo *var,
1737 struct fb_info *info)
1738 {
1739 struct atyfb_par *par = (struct atyfb_par *) info->par;
1740 u32 xres, yres, xoffset, yoffset;
1741
1742 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1743 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1744 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1745 yres >>= 1;
1746 xoffset = (var->xoffset + 7) & ~7;
1747 yoffset = var->yoffset;
1748 if (xoffset + xres > par->crtc.vxres ||
1749 yoffset + yres > par->crtc.vyres)
1750 return -EINVAL;
1751 info->var.xoffset = xoffset;
1752 info->var.yoffset = yoffset;
1753 if (par->asleep)
1754 return 0;
1755
1756 set_off_pitch(par, info);
1757 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1758 par->vblank.pan_display = 1;
1759 } else {
1760 par->vblank.pan_display = 0;
1761 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1762 }
1763
1764 return 0;
1765 }
1766
1767 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1768 {
1769 struct aty_interrupt *vbl;
1770 unsigned int count;
1771 int ret;
1772
1773 switch (crtc) {
1774 case 0:
1775 vbl = &par->vblank;
1776 break;
1777 default:
1778 return -ENODEV;
1779 }
1780
1781 ret = aty_enable_irq(par, 0);
1782 if (ret)
1783 return ret;
1784
1785 count = vbl->count;
1786 ret = wait_event_interruptible_timeout(vbl->wait,
1787 count != vbl->count, HZ/10);
1788 if (ret < 0)
1789 return ret;
1790 if (ret == 0) {
1791 aty_enable_irq(par, 1);
1792 return -ETIMEDOUT;
1793 }
1794
1795 return 0;
1796 }
1797
1798
1799 #ifdef DEBUG
1800 #define ATYIO_CLKR 0x41545900
1801 #define ATYIO_CLKW 0x41545901
1802
1803 struct atyclk {
1804 u32 ref_clk_per;
1805 u8 pll_ref_div;
1806 u8 mclk_fb_div;
1807 u8 mclk_post_div;
1808 u8 mclk_fb_mult;
1809 u8 xclk_post_div;
1810 u8 vclk_fb_div;
1811 u8 vclk_post_div;
1812 u32 dsp_xclks_per_row;
1813 u32 dsp_loop_latency;
1814 u32 dsp_precision;
1815 u32 dsp_on;
1816 u32 dsp_off;
1817 };
1818
1819 #define ATYIO_FEATR 0x41545902
1820 #define ATYIO_FEATW 0x41545903
1821 #endif
1822
1823 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1824 {
1825 struct atyfb_par *par = (struct atyfb_par *) info->par;
1826 #ifdef __sparc__
1827 struct fbtype fbtyp;
1828 #endif
1829
1830 switch (cmd) {
1831 #ifdef __sparc__
1832 case FBIOGTYPE:
1833 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1834 fbtyp.fb_width = par->crtc.vxres;
1835 fbtyp.fb_height = par->crtc.vyres;
1836 fbtyp.fb_depth = info->var.bits_per_pixel;
1837 fbtyp.fb_cmsize = info->cmap.len;
1838 fbtyp.fb_size = info->fix.smem_len;
1839 if (copy_to_user((struct fbtype __user *) arg, &fbtyp,
1840 sizeof(fbtyp)))
1841 return -EFAULT;
1842 break;
1843 #endif
1844
1845 case FBIO_WAITFORVSYNC:
1846 {
1847 u32 crtc;
1848
1849 if (get_user(crtc, (__u32 __user *) arg))
1850 return -EFAULT;
1851
1852 return aty_waitforvblank(par, crtc);
1853 }
1854
1855 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1856 case ATYIO_CLKR:
1857 if (M64_HAS(INTEGRATED)) {
1858 struct atyclk clk = { 0 };
1859 union aty_pll *pll = &par->pll;
1860 u32 dsp_config = pll->ct.dsp_config;
1861 u32 dsp_on_off = pll->ct.dsp_on_off;
1862 clk.ref_clk_per = par->ref_clk_per;
1863 clk.pll_ref_div = pll->ct.pll_ref_div;
1864 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1865 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1866 clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1867 clk.xclk_post_div = pll->ct.xclk_post_div_real;
1868 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1869 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1870 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1871 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1872 clk.dsp_precision = (dsp_config >> 20) & 7;
1873 clk.dsp_off = dsp_on_off & 0x7ff;
1874 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1875 if (copy_to_user((struct atyclk __user *) arg, &clk,
1876 sizeof(clk)))
1877 return -EFAULT;
1878 } else
1879 return -EINVAL;
1880 break;
1881 case ATYIO_CLKW:
1882 if (M64_HAS(INTEGRATED)) {
1883 struct atyclk clk;
1884 union aty_pll *pll = &par->pll;
1885 if (copy_from_user(&clk, (struct atyclk __user *) arg,
1886 sizeof(clk)))
1887 return -EFAULT;
1888 par->ref_clk_per = clk.ref_clk_per;
1889 pll->ct.pll_ref_div = clk.pll_ref_div;
1890 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1891 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1892 pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1893 pll->ct.xclk_post_div_real = clk.xclk_post_div;
1894 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1895 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1896 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1897 ((clk.dsp_loop_latency & 0xf) << 16) |
1898 ((clk.dsp_precision & 7) << 20);
1899 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) |
1900 ((clk.dsp_on & 0x7ff) << 16);
1901
1902 aty_set_pll_ct(info, pll);
1903 } else
1904 return -EINVAL;
1905 break;
1906 case ATYIO_FEATR:
1907 if (get_user(par->features, (u32 __user *) arg))
1908 return -EFAULT;
1909 break;
1910 case ATYIO_FEATW:
1911 if (put_user(par->features, (u32 __user *) arg))
1912 return -EFAULT;
1913 break;
1914 #endif
1915 default:
1916 return -EINVAL;
1917 }
1918 return 0;
1919 }
1920
1921 static int atyfb_sync(struct fb_info *info)
1922 {
1923 struct atyfb_par *par = (struct atyfb_par *) info->par;
1924
1925 if (par->blitter_may_be_busy)
1926 wait_for_idle(par);
1927 return 0;
1928 }
1929
1930 #ifdef __sparc__
1931 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1932 {
1933 struct atyfb_par *par = (struct atyfb_par *) info->par;
1934 unsigned int size, page, map_size = 0;
1935 unsigned long map_offset = 0;
1936 unsigned long off;
1937 int i;
1938
1939 if (!par->mmap_map)
1940 return -ENXIO;
1941
1942 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1943 return -EINVAL;
1944
1945 off = vma->vm_pgoff << PAGE_SHIFT;
1946 size = vma->vm_end - vma->vm_start;
1947
1948
1949
1950 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1951 ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1952 off += 0x8000000000000000UL;
1953
1954 vma->vm_pgoff = off >> PAGE_SHIFT;
1955
1956
1957 for (page = 0; page < size;) {
1958 map_size = 0;
1959 for (i = 0; par->mmap_map[i].size; i++) {
1960 unsigned long start = par->mmap_map[i].voff;
1961 unsigned long end = start + par->mmap_map[i].size;
1962 unsigned long offset = off + page;
1963
1964 if (start > offset)
1965 continue;
1966 if (offset >= end)
1967 continue;
1968
1969 map_size = par->mmap_map[i].size - (offset - start);
1970 map_offset = par->mmap_map[i].poff + (offset - start);
1971 break;
1972 }
1973 if (!map_size) {
1974 page += PAGE_SIZE;
1975 continue;
1976 }
1977 if (page + map_size > size)
1978 map_size = size - page;
1979
1980 pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
1981 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1982
1983 if (remap_pfn_range(vma, vma->vm_start + page,
1984 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1985 return -EAGAIN;
1986
1987 page += map_size;
1988 }
1989
1990 if (!map_size)
1991 return -EINVAL;
1992
1993 if (!par->mmaped)
1994 par->mmaped = 1;
1995 return 0;
1996 }
1997 #endif
1998
1999
2000
2001 #if defined(CONFIG_PCI)
2002
2003 #ifdef CONFIG_PPC_PMAC
2004
2005
2006 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
2007 {
2008 u32 pm;
2009 int timeout;
2010
2011 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2012 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
2013 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2014 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2015
2016 timeout = 2000;
2017 if (sleep) {
2018
2019 pm &= ~PWR_MGT_ON;
2020 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2021 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2022 udelay(10);
2023 pm &= ~(PWR_BLON | AUTO_PWR_UP);
2024 pm |= SUSPEND_NOW;
2025 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2026 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2027 udelay(10);
2028 pm |= PWR_MGT_ON;
2029 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2030 do {
2031 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2032 mdelay(1);
2033 if ((--timeout) == 0)
2034 break;
2035 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
2036 } else {
2037
2038 pm &= ~PWR_MGT_ON;
2039 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2040 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2041 udelay(10);
2042 pm &= ~SUSPEND_NOW;
2043 pm |= (PWR_BLON | AUTO_PWR_UP);
2044 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2045 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2046 udelay(10);
2047 pm |= PWR_MGT_ON;
2048 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2049 do {
2050 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2051 mdelay(1);
2052 if ((--timeout) == 0)
2053 break;
2054 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2055 }
2056 mdelay(500);
2057
2058 return timeout ? 0 : -EIO;
2059 }
2060 #endif
2061
2062 static int atyfb_pci_suspend_late(struct device *dev, pm_message_t state)
2063 {
2064 struct pci_dev *pdev = to_pci_dev(dev);
2065 struct fb_info *info = pci_get_drvdata(pdev);
2066 struct atyfb_par *par = (struct atyfb_par *) info->par;
2067
2068 if (state.event == pdev->dev.power.power_state.event)
2069 return 0;
2070
2071 console_lock();
2072
2073 fb_set_suspend(info, 1);
2074
2075
2076 wait_for_idle(par);
2077 aty_reset_engine(par);
2078
2079
2080 atyfb_blank(FB_BLANK_POWERDOWN, info);
2081
2082 par->asleep = 1;
2083 par->lock_blank = 1;
2084
2085
2086
2087
2088
2089
2090
2091 #ifdef CONFIG_PPC_PMAC
2092
2093 if (machine_is(powermac) && aty_power_mgmt(1, par)) {
2094 par->asleep = 0;
2095 par->lock_blank = 0;
2096 atyfb_blank(FB_BLANK_UNBLANK, info);
2097 fb_set_suspend(info, 0);
2098 console_unlock();
2099 return -EIO;
2100 }
2101 #endif
2102
2103 console_unlock();
2104
2105 pdev->dev.power.power_state = state;
2106
2107 return 0;
2108 }
2109
2110 static int __maybe_unused atyfb_pci_suspend(struct device *dev)
2111 {
2112 return atyfb_pci_suspend_late(dev, PMSG_SUSPEND);
2113 }
2114
2115 static int __maybe_unused atyfb_pci_hibernate(struct device *dev)
2116 {
2117 return atyfb_pci_suspend_late(dev, PMSG_HIBERNATE);
2118 }
2119
2120 static int __maybe_unused atyfb_pci_freeze(struct device *dev)
2121 {
2122 return atyfb_pci_suspend_late(dev, PMSG_FREEZE);
2123 }
2124
2125 static void aty_resume_chip(struct fb_info *info)
2126 {
2127 struct atyfb_par *par = info->par;
2128
2129 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2130
2131 if (par->pll_ops->resume_pll)
2132 par->pll_ops->resume_pll(info, &par->pll);
2133
2134 if (par->aux_start)
2135 aty_st_le32(BUS_CNTL,
2136 aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2137 }
2138
2139 static int __maybe_unused atyfb_pci_resume(struct device *dev)
2140 {
2141 struct pci_dev *pdev = to_pci_dev(dev);
2142 struct fb_info *info = pci_get_drvdata(pdev);
2143 struct atyfb_par *par = (struct atyfb_par *) info->par;
2144
2145 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2146 return 0;
2147
2148 console_lock();
2149
2150
2151
2152
2153
2154
2155
2156 #ifdef CONFIG_PPC_PMAC
2157 if (machine_is(powermac) &&
2158 pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
2159 aty_power_mgmt(0, par);
2160 #endif
2161
2162 aty_resume_chip(info);
2163
2164 par->asleep = 0;
2165
2166
2167 atyfb_set_par(info);
2168
2169
2170 fb_set_suspend(info, 0);
2171
2172
2173 par->lock_blank = 0;
2174 atyfb_blank(FB_BLANK_UNBLANK, info);
2175
2176 console_unlock();
2177
2178 pdev->dev.power.power_state = PMSG_ON;
2179
2180 return 0;
2181 }
2182
2183 static const struct dev_pm_ops atyfb_pci_pm_ops = {
2184 #ifdef CONFIG_PM_SLEEP
2185 .suspend = atyfb_pci_suspend,
2186 .resume = atyfb_pci_resume,
2187 .freeze = atyfb_pci_freeze,
2188 .thaw = atyfb_pci_resume,
2189 .poweroff = atyfb_pci_hibernate,
2190 .restore = atyfb_pci_resume,
2191 #endif
2192 };
2193
2194 #endif
2195
2196
2197 #ifdef CONFIG_FB_ATY_BACKLIGHT
2198 #define MAX_LEVEL 0xFF
2199
2200 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2201 {
2202 struct fb_info *info = pci_get_drvdata(par->pdev);
2203 int atylevel;
2204
2205
2206
2207 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2208
2209 if (atylevel < 0)
2210 atylevel = 0;
2211 else if (atylevel > MAX_LEVEL)
2212 atylevel = MAX_LEVEL;
2213
2214 return atylevel;
2215 }
2216
2217 static int aty_bl_update_status(struct backlight_device *bd)
2218 {
2219 struct atyfb_par *par = bl_get_data(bd);
2220 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2221 int level;
2222
2223 if (bd->props.power != FB_BLANK_UNBLANK ||
2224 bd->props.fb_blank != FB_BLANK_UNBLANK)
2225 level = 0;
2226 else
2227 level = bd->props.brightness;
2228
2229 reg |= (BLMOD_EN | BIASMOD_EN);
2230 if (level > 0) {
2231 reg &= ~BIAS_MOD_LEVEL_MASK;
2232 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2233 } else {
2234 reg &= ~BIAS_MOD_LEVEL_MASK;
2235 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2236 }
2237 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2238
2239 return 0;
2240 }
2241
2242 static const struct backlight_ops aty_bl_data = {
2243 .update_status = aty_bl_update_status,
2244 };
2245
2246 static void aty_bl_init(struct atyfb_par *par)
2247 {
2248 struct backlight_properties props;
2249 struct fb_info *info = pci_get_drvdata(par->pdev);
2250 struct backlight_device *bd;
2251 char name[12];
2252
2253 #ifdef CONFIG_PMAC_BACKLIGHT
2254 if (!pmac_has_backlight_type("ati"))
2255 return;
2256 #endif
2257
2258 snprintf(name, sizeof(name), "atybl%d", info->node);
2259
2260 memset(&props, 0, sizeof(struct backlight_properties));
2261 props.type = BACKLIGHT_RAW;
2262 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2263 bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
2264 &props);
2265 if (IS_ERR(bd)) {
2266 info->bl_dev = NULL;
2267 printk(KERN_WARNING "aty: Backlight registration failed\n");
2268 goto error;
2269 }
2270
2271 info->bl_dev = bd;
2272 fb_bl_default_curve(info, 0,
2273 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2274 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2275
2276 bd->props.brightness = bd->props.max_brightness;
2277 bd->props.power = FB_BLANK_UNBLANK;
2278 backlight_update_status(bd);
2279
2280 printk("aty: Backlight initialized (%s)\n", name);
2281
2282 return;
2283
2284 error:
2285 return;
2286 }
2287
2288 #ifdef CONFIG_PCI
2289 static void aty_bl_exit(struct backlight_device *bd)
2290 {
2291 backlight_device_unregister(bd);
2292 printk("aty: Backlight unloaded\n");
2293 }
2294 #endif
2295
2296 #endif
2297
2298 static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2299 {
2300 static const int ragepro_tbl[] = {
2301 44, 50, 55, 66, 75, 80, 100
2302 };
2303 static const int ragexl_tbl[] = {
2304 50, 66, 75, 83, 90, 95, 100, 105,
2305 110, 115, 120, 125, 133, 143, 166
2306 };
2307 const int *refresh_tbl;
2308 int i, size;
2309
2310 if (M64_HAS(XL_MEM)) {
2311 refresh_tbl = ragexl_tbl;
2312 size = ARRAY_SIZE(ragexl_tbl);
2313 } else {
2314 refresh_tbl = ragepro_tbl;
2315 size = ARRAY_SIZE(ragepro_tbl);
2316 }
2317
2318 for (i = 0; i < size; i++) {
2319 if (xclk < refresh_tbl[i])
2320 break;
2321 }
2322 par->mem_refresh_rate = i;
2323 }
2324
2325
2326
2327
2328
2329 static struct fb_info *fb_list = NULL;
2330
2331 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2332 static int atyfb_get_timings_from_lcd(struct atyfb_par *par,
2333 struct fb_var_screeninfo *var)
2334 {
2335 int ret = -EINVAL;
2336
2337 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2338 *var = default_var;
2339 var->xres = var->xres_virtual = par->lcd_hdisp;
2340 var->right_margin = par->lcd_right_margin;
2341 var->left_margin = par->lcd_hblank_len -
2342 (par->lcd_right_margin + par->lcd_hsync_dly +
2343 par->lcd_hsync_len);
2344 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2345 var->yres = var->yres_virtual = par->lcd_vdisp;
2346 var->lower_margin = par->lcd_lower_margin;
2347 var->upper_margin = par->lcd_vblank_len -
2348 (par->lcd_lower_margin + par->lcd_vsync_len);
2349 var->vsync_len = par->lcd_vsync_len;
2350 var->pixclock = par->lcd_pixclock;
2351 ret = 0;
2352 }
2353
2354 return ret;
2355 }
2356 #endif
2357
2358 static int aty_init(struct fb_info *info)
2359 {
2360 struct atyfb_par *par = (struct atyfb_par *) info->par;
2361 const char *ramname = NULL, *xtal;
2362 int gtb_memsize, has_var = 0;
2363 struct fb_var_screeninfo var;
2364 int ret;
2365 #ifdef CONFIG_ATARI
2366 u8 dac_type;
2367 #endif
2368
2369 init_waitqueue_head(&par->vblank.wait);
2370 spin_lock_init(&par->int_lock);
2371
2372 #ifdef CONFIG_FB_ATY_GX
2373 if (!M64_HAS(INTEGRATED)) {
2374 u32 stat0;
2375 u8 dac_subtype, clk_type;
2376 stat0 = aty_ld_le32(CNFG_STAT0, par);
2377 par->bus_type = (stat0 >> 0) & 0x07;
2378 par->ram_type = (stat0 >> 3) & 0x07;
2379 ramname = aty_gx_ram[par->ram_type];
2380
2381 #ifdef CONFIG_ATARI
2382 clk_type = CLK_ATI18818_1;
2383 dac_type = (stat0 >> 9) & 0x07;
2384 if (dac_type == 0x07)
2385 dac_subtype = DAC_ATT20C408;
2386 else
2387 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2388 #else
2389 dac_subtype = DAC_IBMRGB514;
2390 clk_type = CLK_IBMRGB514;
2391 #endif
2392 switch (dac_subtype) {
2393 case DAC_IBMRGB514:
2394 par->dac_ops = &aty_dac_ibm514;
2395 break;
2396 #ifdef CONFIG_ATARI
2397 case DAC_ATI68860_B:
2398 case DAC_ATI68860_C:
2399 par->dac_ops = &aty_dac_ati68860b;
2400 break;
2401 case DAC_ATT20C408:
2402 case DAC_ATT21C498:
2403 par->dac_ops = &aty_dac_att21c498;
2404 break;
2405 #endif
2406 default:
2407 PRINTKI("aty_init: DAC type not implemented yet!\n");
2408 par->dac_ops = &aty_dac_unsupported;
2409 break;
2410 }
2411 switch (clk_type) {
2412 #ifdef CONFIG_ATARI
2413 case CLK_ATI18818_1:
2414 par->pll_ops = &aty_pll_ati18818_1;
2415 break;
2416 #else
2417 case CLK_IBMRGB514:
2418 par->pll_ops = &aty_pll_ibm514;
2419 break;
2420 #endif
2421 default:
2422 PRINTKI("aty_init: CLK type not implemented yet!");
2423 par->pll_ops = &aty_pll_unsupported;
2424 break;
2425 }
2426 }
2427 #endif
2428 #ifdef CONFIG_FB_ATY_CT
2429 if (M64_HAS(INTEGRATED)) {
2430 par->dac_ops = &aty_dac_ct;
2431 par->pll_ops = &aty_pll_ct;
2432 par->bus_type = PCI;
2433 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
2434 if (M64_HAS(XL_MEM))
2435 ramname = aty_xl_ram[par->ram_type];
2436 else
2437 ramname = aty_ct_ram[par->ram_type];
2438
2439 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2440 par->pll_limits.mclk = 63;
2441
2442 if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
2443 par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
2444 }
2445 #endif
2446 #ifdef CONFIG_PPC_PMAC
2447
2448
2449
2450
2451 if (of_machine_is_compatible("PowerBook2,1")) {
2452 par->pll_limits.mclk = 70;
2453 par->pll_limits.xclk = 53;
2454 }
2455 #endif
2456
2457
2458 if (pll)
2459 par->pll_limits.pll_max = pll;
2460 if (mclk)
2461 par->pll_limits.mclk = mclk;
2462 if (xclk)
2463 par->pll_limits.xclk = xclk;
2464
2465 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2466 par->pll_per = 1000000/par->pll_limits.pll_max;
2467 par->mclk_per = 1000000/par->pll_limits.mclk;
2468 par->xclk_per = 1000000/par->pll_limits.xclk;
2469
2470 par->ref_clk_per = 1000000000000ULL / 14318180;
2471 xtal = "14.31818";
2472
2473 #ifdef CONFIG_FB_ATY_CT
2474 if (M64_HAS(GTB_DSP)) {
2475 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2476
2477 if (pll_ref_div) {
2478 int diff1, diff2;
2479 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2480 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2481 if (diff1 < 0)
2482 diff1 = -diff1;
2483 if (diff2 < 0)
2484 diff2 = -diff2;
2485 if (diff2 < diff1) {
2486 par->ref_clk_per = 1000000000000ULL / 29498928;
2487 xtal = "29.498928";
2488 }
2489 }
2490 }
2491 #endif
2492
2493
2494 aty_get_crtc(par, &par->saved_crtc);
2495 if (par->pll_ops->get_pll)
2496 par->pll_ops->get_pll(info, &par->saved_pll);
2497
2498 par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
2499 gtb_memsize = M64_HAS(GTB_DSP);
2500 if (gtb_memsize)
2501
2502 switch (par->mem_cntl & 0xF) {
2503 case MEM_SIZE_512K:
2504 info->fix.smem_len = 0x80000;
2505 break;
2506 case MEM_SIZE_1M:
2507 info->fix.smem_len = 0x100000;
2508 break;
2509 case MEM_SIZE_2M_GTB:
2510 info->fix.smem_len = 0x200000;
2511 break;
2512 case MEM_SIZE_4M_GTB:
2513 info->fix.smem_len = 0x400000;
2514 break;
2515 case MEM_SIZE_6M_GTB:
2516 info->fix.smem_len = 0x600000;
2517 break;
2518 case MEM_SIZE_8M_GTB:
2519 info->fix.smem_len = 0x800000;
2520 break;
2521 default:
2522 info->fix.smem_len = 0x80000;
2523 } else
2524 switch (par->mem_cntl & MEM_SIZE_ALIAS) {
2525 case MEM_SIZE_512K:
2526 info->fix.smem_len = 0x80000;
2527 break;
2528 case MEM_SIZE_1M:
2529 info->fix.smem_len = 0x100000;
2530 break;
2531 case MEM_SIZE_2M:
2532 info->fix.smem_len = 0x200000;
2533 break;
2534 case MEM_SIZE_4M:
2535 info->fix.smem_len = 0x400000;
2536 break;
2537 case MEM_SIZE_6M:
2538 info->fix.smem_len = 0x600000;
2539 break;
2540 case MEM_SIZE_8M:
2541 info->fix.smem_len = 0x800000;
2542 break;
2543 default:
2544 info->fix.smem_len = 0x80000;
2545 }
2546
2547 if (M64_HAS(MAGIC_VRAM_SIZE)) {
2548 if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
2549 info->fix.smem_len += 0x400000;
2550 }
2551
2552 if (vram) {
2553 info->fix.smem_len = vram * 1024;
2554 par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2555 if (info->fix.smem_len <= 0x80000)
2556 par->mem_cntl |= MEM_SIZE_512K;
2557 else if (info->fix.smem_len <= 0x100000)
2558 par->mem_cntl |= MEM_SIZE_1M;
2559 else if (info->fix.smem_len <= 0x200000)
2560 par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2561 else if (info->fix.smem_len <= 0x400000)
2562 par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2563 else if (info->fix.smem_len <= 0x600000)
2564 par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2565 else
2566 par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2567 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2568 }
2569
2570
2571
2572
2573
2574 if (M64_HAS(GX)) {
2575 info->fix.mmio_len = 0x400;
2576 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2577 } else if (M64_HAS(CT)) {
2578 info->fix.mmio_len = 0x400;
2579 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2580 } else if (M64_HAS(VT)) {
2581 info->fix.mmio_start -= 0x400;
2582 info->fix.mmio_len = 0x800;
2583 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2584 } else {
2585 info->fix.mmio_start -= 0x400;
2586 info->fix.mmio_len = 0x800;
2587 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2588 }
2589
2590 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2591 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20),
2592 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal,
2593 par->pll_limits.pll_max, par->pll_limits.mclk,
2594 par->pll_limits.xclk);
2595
2596 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
2597 if (M64_HAS(INTEGRATED)) {
2598 int i;
2599 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL "
2600 "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG "
2601 "DSP_ON_OFF CLOCK_CNTL\n"
2602 "debug atyfb: %08x %08x %08x "
2603 "%08x %08x %08x "
2604 "%08x %08x\n"
2605 "debug atyfb: PLL",
2606 aty_ld_le32(BUS_CNTL, par),
2607 aty_ld_le32(DAC_CNTL, par),
2608 aty_ld_le32(MEM_CNTL, par),
2609 aty_ld_le32(EXT_MEM_CNTL, par),
2610 aty_ld_le32(CRTC_GEN_CNTL, par),
2611 aty_ld_le32(DSP_CONFIG, par),
2612 aty_ld_le32(DSP_ON_OFF, par),
2613 aty_ld_le32(CLOCK_CNTL, par));
2614 for (i = 0; i < 40; i++)
2615 pr_cont(" %02x", aty_ld_pll_ct(i, par));
2616 pr_cont("\n");
2617 }
2618 #endif
2619 if (par->pll_ops->init_pll)
2620 par->pll_ops->init_pll(info, &par->pll);
2621 if (par->pll_ops->resume_pll)
2622 par->pll_ops->resume_pll(info, &par->pll);
2623
2624 aty_fudge_framebuffer_len(info);
2625
2626
2627
2628
2629
2630
2631 if (par->aux_start)
2632 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
2633 BUS_APER_REG_DIS, par);
2634
2635 if (!nomtrr)
2636
2637
2638
2639
2640 par->wc_cookie = arch_phys_wc_add(par->res_start,
2641 par->res_size);
2642
2643 info->fbops = &atyfb_ops;
2644 info->pseudo_palette = par->pseudo_palette;
2645 info->flags = FBINFO_DEFAULT |
2646 FBINFO_HWACCEL_IMAGEBLIT |
2647 FBINFO_HWACCEL_FILLRECT |
2648 FBINFO_HWACCEL_COPYAREA |
2649 FBINFO_HWACCEL_YPAN |
2650 FBINFO_READS_FAST;
2651
2652 #ifdef CONFIG_PMAC_BACKLIGHT
2653 if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
2654
2655
2656
2657
2658 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) |
2659 USE_F32KHZ | TRISTATE_MEM_EN, par);
2660 } else
2661 #endif
2662 if (M64_HAS(MOBIL_BUS) && backlight) {
2663 #ifdef CONFIG_FB_ATY_BACKLIGHT
2664 aty_bl_init(par);
2665 #endif
2666 }
2667
2668 memset(&var, 0, sizeof(var));
2669 #ifdef CONFIG_PPC
2670 if (machine_is(powermac)) {
2671
2672
2673
2674
2675 if (mode) {
2676 if (mac_find_mode(&var, info, mode, 8))
2677 has_var = 1;
2678 } else {
2679 if (default_vmode == VMODE_CHOOSE) {
2680 int sense;
2681 if (M64_HAS(G3_PB_1024x768))
2682
2683 default_vmode = VMODE_1024_768_60;
2684 else if (of_machine_is_compatible("iMac"))
2685 default_vmode = VMODE_1024_768_75;
2686 else if (of_machine_is_compatible("PowerBook2,1"))
2687
2688 default_vmode = VMODE_800_600_60;
2689 else
2690 default_vmode = VMODE_640_480_67;
2691 sense = read_aty_sense(par);
2692 PRINTKI("monitor sense=%x, mode %d\n",
2693 sense, mac_map_monitor_sense(sense));
2694 }
2695 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2696 default_vmode = VMODE_640_480_60;
2697 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2698 default_cmode = CMODE_8;
2699 if (!mac_vmode_to_var(default_vmode, default_cmode,
2700 &var))
2701 has_var = 1;
2702 }
2703 }
2704
2705 #endif
2706
2707 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2708 if (!atyfb_get_timings_from_lcd(par, &var))
2709 has_var = 1;
2710 #endif
2711
2712 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2713 has_var = 1;
2714
2715 if (!has_var)
2716 var = default_var;
2717
2718 if (noaccel)
2719 var.accel_flags &= ~FB_ACCELF_TEXT;
2720 else
2721 var.accel_flags |= FB_ACCELF_TEXT;
2722
2723 if (comp_sync != -1) {
2724 if (!comp_sync)
2725 var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2726 else
2727 var.sync |= FB_SYNC_COMP_HIGH_ACT;
2728 }
2729
2730 if (var.yres == var.yres_virtual) {
2731 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2732 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2733 if (var.yres_virtual < var.yres)
2734 var.yres_virtual = var.yres;
2735 }
2736
2737 ret = atyfb_check_var(&var, info);
2738 if (ret) {
2739 PRINTKE("can't set default video mode\n");
2740 goto aty_init_exit;
2741 }
2742
2743 #ifdef CONFIG_FB_ATY_CT
2744 if (!noaccel && M64_HAS(INTEGRATED))
2745 aty_init_cursor(info, &atyfb_ops);
2746 #endif
2747 info->var = var;
2748
2749 ret = fb_alloc_cmap(&info->cmap, 256, 0);
2750 if (ret < 0)
2751 goto aty_init_exit;
2752
2753 ret = register_framebuffer(info);
2754 if (ret < 0) {
2755 fb_dealloc_cmap(&info->cmap);
2756 goto aty_init_exit;
2757 }
2758
2759 fb_list = info;
2760
2761 PRINTKI("fb%d: %s frame buffer device on %s\n",
2762 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2763 return 0;
2764
2765 aty_init_exit:
2766
2767 aty_set_crtc(par, &par->saved_crtc);
2768 par->pll_ops->set_pll(info, &par->saved_pll);
2769 arch_phys_wc_del(par->wc_cookie);
2770
2771 return ret;
2772 }
2773
2774 #if defined(CONFIG_ATARI) && !defined(MODULE)
2775 static int store_video_par(char *video_str, unsigned char m64_num)
2776 {
2777 char *p;
2778 unsigned long vmembase, size, guiregbase;
2779
2780 PRINTKI("store_video_par() '%s' \n", video_str);
2781
2782 if (!(p = strsep(&video_str, ";")) || !*p)
2783 goto mach64_invalid;
2784 vmembase = simple_strtoul(p, NULL, 0);
2785 if (!(p = strsep(&video_str, ";")) || !*p)
2786 goto mach64_invalid;
2787 size = simple_strtoul(p, NULL, 0);
2788 if (!(p = strsep(&video_str, ";")) || !*p)
2789 goto mach64_invalid;
2790 guiregbase = simple_strtoul(p, NULL, 0);
2791
2792 phys_vmembase[m64_num] = vmembase;
2793 phys_size[m64_num] = size;
2794 phys_guiregbase[m64_num] = guiregbase;
2795 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2796 guiregbase);
2797 return 0;
2798
2799 mach64_invalid:
2800 phys_vmembase[m64_num] = 0;
2801 return -1;
2802 }
2803 #endif
2804
2805
2806
2807
2808
2809 static int atyfb_blank(int blank, struct fb_info *info)
2810 {
2811 struct atyfb_par *par = (struct atyfb_par *) info->par;
2812 u32 gen_cntl;
2813
2814 if (par->lock_blank || par->asleep)
2815 return 0;
2816
2817 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2818 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2819 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2820 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2821 pm &= ~PWR_BLON;
2822 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2823 }
2824 #endif
2825
2826 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2827 gen_cntl &= ~0x400004c;
2828 switch (blank) {
2829 case FB_BLANK_UNBLANK:
2830 break;
2831 case FB_BLANK_NORMAL:
2832 gen_cntl |= 0x4000040;
2833 break;
2834 case FB_BLANK_VSYNC_SUSPEND:
2835 gen_cntl |= 0x4000048;
2836 break;
2837 case FB_BLANK_HSYNC_SUSPEND:
2838 gen_cntl |= 0x4000044;
2839 break;
2840 case FB_BLANK_POWERDOWN:
2841 gen_cntl |= 0x400004c;
2842 break;
2843 }
2844 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2845
2846 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2847 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2848 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2849 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2850 pm |= PWR_BLON;
2851 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2852 }
2853 #endif
2854
2855 return 0;
2856 }
2857
2858 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2859 const struct atyfb_par *par)
2860 {
2861 aty_st_8(DAC_W_INDEX, regno, par);
2862 aty_st_8(DAC_DATA, red, par);
2863 aty_st_8(DAC_DATA, green, par);
2864 aty_st_8(DAC_DATA, blue, par);
2865 }
2866
2867
2868
2869
2870
2871
2872
2873
2874 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2875 u_int transp, struct fb_info *info)
2876 {
2877 struct atyfb_par *par = (struct atyfb_par *) info->par;
2878 int i, depth;
2879 u32 *pal = info->pseudo_palette;
2880
2881 depth = info->var.bits_per_pixel;
2882 if (depth == 16)
2883 depth = (info->var.green.length == 5) ? 15 : 16;
2884
2885 if (par->asleep)
2886 return 0;
2887
2888 if (regno > 255 ||
2889 (depth == 16 && regno > 63) ||
2890 (depth == 15 && regno > 31))
2891 return 1;
2892
2893 red >>= 8;
2894 green >>= 8;
2895 blue >>= 8;
2896
2897 par->palette[regno].red = red;
2898 par->palette[regno].green = green;
2899 par->palette[regno].blue = blue;
2900
2901 if (regno < 16) {
2902 switch (depth) {
2903 case 15:
2904 pal[regno] = (regno << 10) | (regno << 5) | regno;
2905 break;
2906 case 16:
2907 pal[regno] = (regno << 11) | (regno << 5) | regno;
2908 break;
2909 case 24:
2910 pal[regno] = (regno << 16) | (regno << 8) | regno;
2911 break;
2912 case 32:
2913 i = (regno << 8) | regno;
2914 pal[regno] = (i << 16) | i;
2915 break;
2916 }
2917 }
2918
2919 i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2920 if (M64_HAS(EXTRA_BRIGHT))
2921 i |= 0x2;
2922 aty_st_8(DAC_CNTL, i, par);
2923 aty_st_8(DAC_MASK, 0xff, par);
2924
2925 if (M64_HAS(INTEGRATED)) {
2926 if (depth == 16) {
2927 if (regno < 32)
2928 aty_st_pal(regno << 3, red,
2929 par->palette[regno << 1].green,
2930 blue, par);
2931 red = par->palette[regno >> 1].red;
2932 blue = par->palette[regno >> 1].blue;
2933 regno <<= 2;
2934 } else if (depth == 15) {
2935 regno <<= 3;
2936 for (i = 0; i < 8; i++)
2937 aty_st_pal(regno + i, red, green, blue, par);
2938 }
2939 }
2940 aty_st_pal(regno, red, green, blue, par);
2941
2942 return 0;
2943 }
2944
2945 #ifdef CONFIG_PCI
2946
2947 #ifdef __sparc__
2948
2949 static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info,
2950 unsigned long addr)
2951 {
2952 struct atyfb_par *par = info->par;
2953 struct device_node *dp;
2954 u32 mem, chip_id;
2955 int i, j, ret;
2956
2957
2958
2959
2960 par->ati_regbase = (void *)addr + 0x7ffc00UL;
2961 info->fix.mmio_start = addr + 0x7ffc00UL;
2962
2963
2964
2965
2966 info->screen_base = (char *) (addr + 0x800000UL);
2967 info->fix.smem_start = addr + 0x800000UL;
2968
2969
2970
2971
2972
2973 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2974 ;
2975 j = i + 4;
2976
2977 par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC);
2978 if (!par->mmap_map) {
2979 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2980 return -ENOMEM;
2981 }
2982
2983 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2984 struct resource *rp = &pdev->resource[i];
2985 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2986 unsigned long base;
2987 u32 size, pbase;
2988
2989 base = rp->start;
2990
2991 io = (rp->flags & IORESOURCE_IO);
2992
2993 size = rp->end - base + 1;
2994
2995 pci_read_config_dword(pdev, breg, &pbase);
2996
2997 if (io)
2998 size &= ~1;
2999
3000
3001
3002
3003
3004
3005
3006 if (base == addr) {
3007 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
3008 par->mmap_map[j].poff = base & PAGE_MASK;
3009 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3010 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3011 par->mmap_map[j].prot_flag = _PAGE_E;
3012 j++;
3013 }
3014
3015
3016
3017
3018
3019 if (base == addr) {
3020 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
3021 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
3022 par->mmap_map[j].size = 0x800000;
3023 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3024 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
3025 size -= 0x800000;
3026 j++;
3027 }
3028
3029 par->mmap_map[j].voff = pbase & PAGE_MASK;
3030 par->mmap_map[j].poff = base & PAGE_MASK;
3031 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3032 par->mmap_map[j].prot_mask = _PAGE_CACHE;
3033 par->mmap_map[j].prot_flag = _PAGE_E;
3034 j++;
3035 }
3036
3037 ret = correct_chipset(par);
3038 if (ret)
3039 return ret;
3040
3041 if (IS_XL(pdev->device)) {
3042
3043
3044
3045 mem = aty_ld_le32(MEM_CNTL, par);
3046 chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
3047 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
3048 switch (mem & 0x0f) {
3049 case 3:
3050 mem = (mem & ~(0x0f)) | 2;
3051 break;
3052 case 7:
3053 mem = (mem & ~(0x0f)) | 3;
3054 break;
3055 case 9:
3056 mem = (mem & ~(0x0f)) | 4;
3057 break;
3058 case 11:
3059 mem = (mem & ~(0x0f)) | 5;
3060 break;
3061 default:
3062 break;
3063 }
3064 if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM)
3065 mem &= ~(0x00700000);
3066 }
3067 mem &= ~(0xcf80e000);
3068 aty_st_le32(MEM_CNTL, mem, par);
3069 }
3070
3071 dp = pci_device_to_OF_node(pdev);
3072 if (dp == of_console_device) {
3073 struct fb_var_screeninfo *var = &default_var;
3074 unsigned int N, P, Q, M, T, R;
3075 struct crtc crtc;
3076 u8 pll_regs[16];
3077 u8 clock_cntl;
3078
3079 crtc.vxres = of_getintprop_default(dp, "width", 1024);
3080 crtc.vyres = of_getintprop_default(dp, "height", 768);
3081 var->bits_per_pixel = of_getintprop_default(dp, "depth", 8);
3082 var->xoffset = var->yoffset = 0;
3083 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
3084 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
3085 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
3086 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
3087 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
3088 aty_crtc_to_var(&crtc, var);
3089
3090
3091
3092
3093 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
3094
3095 for (i = 0; i < 16; i++)
3096 pll_regs[i] = aty_ld_pll_ct(i, par);
3097
3098
3099
3100
3101 M = pll_regs[PLL_REF_DIV];
3102
3103
3104
3105
3106 N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)];
3107
3108
3109
3110
3111 P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) |
3112 ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)];
3113
3114
3115
3116
3117 Q = N / P;
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128 if (IS_XL(pdev->device))
3129 R = 29498;
3130 else
3131 R = 14318;
3132
3133 T = 2 * Q * R / M;
3134
3135 default_var.pixclock = 1000000000 / T;
3136 }
3137
3138 return 0;
3139 }
3140
3141 #else
3142
3143 #ifdef __i386__
3144 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3145 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3146 {
3147 u32 driv_inf_tab, sig;
3148 u16 lcd_ofs;
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3160
3161
3162 sig = *(u32 *)driv_inf_tab;
3163 if ((sig == 0x54504c24) ||
3164 (sig == 0x544d5224) ||
3165 (sig == 0x54435824) ||
3166 (sig == 0x544c5824)) {
3167 PRINTKI("BIOS contains driver information table.\n");
3168 lcd_ofs = *(u16 *)(driv_inf_tab + 10);
3169 par->lcd_table = 0;
3170 if (lcd_ofs != 0)
3171 par->lcd_table = bios_base + lcd_ofs;
3172 }
3173
3174 if (par->lcd_table != 0) {
3175 char model[24];
3176 char strbuf[16];
3177 char refresh_rates_buf[100];
3178 int id, tech, f, i, m, default_refresh_rate;
3179 char *txtcolour;
3180 char *txtmonitor;
3181 char *txtdual;
3182 char *txtformat;
3183 u16 width, height, panel_type, refresh_rates;
3184 u16 *lcdmodeptr;
3185 u32 format;
3186 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85,
3187 90, 100, 120, 140, 150, 160, 200 };
3188
3189
3190
3191
3192
3193 id = *(u8 *)par->lcd_table;
3194 strncpy(model, (char *)par->lcd_table+1, 24);
3195 model[23] = 0;
3196
3197 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3198 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3199 panel_type = *(u16 *)(par->lcd_table+29);
3200 if (panel_type & 1)
3201 txtcolour = "colour";
3202 else
3203 txtcolour = "monochrome";
3204 if (panel_type & 2)
3205 txtdual = "dual (split) ";
3206 else
3207 txtdual = "";
3208 tech = (panel_type >> 2) & 63;
3209 switch (tech) {
3210 case 0:
3211 txtmonitor = "passive matrix";
3212 break;
3213 case 1:
3214 txtmonitor = "active matrix";
3215 break;
3216 case 2:
3217 txtmonitor = "active addressed STN";
3218 break;
3219 case 3:
3220 txtmonitor = "EL";
3221 break;
3222 case 4:
3223 txtmonitor = "plasma";
3224 break;
3225 default:
3226 txtmonitor = "unknown";
3227 }
3228 format = *(u32 *)(par->lcd_table+57);
3229 if (tech == 0 || tech == 2) {
3230 switch (format & 7) {
3231 case 0:
3232 txtformat = "12 bit interface";
3233 break;
3234 case 1:
3235 txtformat = "16 bit interface";
3236 break;
3237 case 2:
3238 txtformat = "24 bit interface";
3239 break;
3240 default:
3241 txtformat = "unknown format";
3242 }
3243 } else {
3244 switch (format & 7) {
3245 case 0:
3246 txtformat = "8 colours";
3247 break;
3248 case 1:
3249 txtformat = "512 colours";
3250 break;
3251 case 2:
3252 txtformat = "4096 colours";
3253 break;
3254 case 4:
3255 txtformat = "262144 colours (LT mode)";
3256 break;
3257 case 5:
3258 txtformat = "16777216 colours";
3259 break;
3260 case 6:
3261 txtformat = "262144 colours (FDPI-2 mode)";
3262 break;
3263 default:
3264 txtformat = "unknown format";
3265 }
3266 }
3267 PRINTKI("%s%s %s monitor detected: %s\n",
3268 txtdual, txtcolour, txtmonitor, model);
3269 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3270 id, width, height, txtformat);
3271 refresh_rates_buf[0] = 0;
3272 refresh_rates = *(u16 *)(par->lcd_table+62);
3273 m = 1;
3274 f = 0;
3275 for (i = 0; i < 16; i++) {
3276 if (refresh_rates & m) {
3277 if (f == 0) {
3278 sprintf(strbuf, "%d",
3279 lcd_refresh_rates[i]);
3280 f++;
3281 } else {
3282 sprintf(strbuf, ",%d",
3283 lcd_refresh_rates[i]);
3284 }
3285 strcat(refresh_rates_buf, strbuf);
3286 }
3287 m = m << 1;
3288 }
3289 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3290 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3291 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3292 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3306 while (*lcdmodeptr != 0) {
3307 u32 modeptr;
3308 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3309 modeptr = bios_base + *lcdmodeptr;
3310
3311 mwidth = *((u16 *)(modeptr+0));
3312 mheight = *((u16 *)(modeptr+2));
3313
3314 if (mwidth == width && mheight == height) {
3315 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3316 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3317 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3318 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3319 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3320 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3321
3322 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3323 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3324 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3325 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3326
3327 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3328 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3329 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3330 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3331
3332 par->lcd_vtotal++;
3333 par->lcd_vdisp++;
3334 lcd_vsync_start++;
3335
3336 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3337 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3338 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3339 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3340 break;
3341 }
3342
3343 lcdmodeptr++;
3344 }
3345 if (*lcdmodeptr == 0) {
3346 PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3347
3348 } else {
3349 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3350 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3351 par->lcd_hdisp,
3352 par->lcd_hdisp + par->lcd_right_margin,
3353 par->lcd_hdisp + par->lcd_right_margin
3354 + par->lcd_hsync_dly + par->lcd_hsync_len,
3355 par->lcd_htotal,
3356 par->lcd_vdisp,
3357 par->lcd_vdisp + par->lcd_lower_margin,
3358 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3359 par->lcd_vtotal);
3360 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
3361 par->lcd_pixclock,
3362 par->lcd_hblank_len - (par->lcd_right_margin +
3363 par->lcd_hsync_dly + par->lcd_hsync_len),
3364 par->lcd_hdisp,
3365 par->lcd_right_margin,
3366 par->lcd_hsync_len,
3367 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3368 par->lcd_vdisp,
3369 par->lcd_lower_margin,
3370 par->lcd_vsync_len);
3371 }
3372 }
3373 }
3374 #endif
3375
3376 static int init_from_bios(struct atyfb_par *par)
3377 {
3378 u32 bios_base, rom_addr;
3379 int ret;
3380
3381 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3382 bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3383
3384
3385 if (*((u16 *)bios_base) == 0xaa55) {
3386
3387 u8 *bios_ptr;
3388 u16 rom_table_offset, freq_table_offset;
3389 PLL_BLOCK_MACH64 pll_block;
3390
3391 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3392
3393
3394 bios_ptr = (u8*)bios_base;
3395 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3396 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3397 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3398
3399 PRINTKI("BIOS frequency table:\n");
3400 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3401 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3402 pll_block.ref_freq, pll_block.ref_divider);
3403 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3404 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3405 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3406
3407 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3408 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3409 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3410 par->pll_limits.ref_div = pll_block.ref_divider;
3411 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3412 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3413 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3414 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3415 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3416 aty_init_lcd(par, bios_base);
3417 #endif
3418 ret = 0;
3419 } else {
3420 PRINTKE("no BIOS frequency table found, use parameters\n");
3421 ret = -ENXIO;
3422 }
3423 iounmap((void __iomem *)bios_base);
3424
3425 return ret;
3426 }
3427 #endif
3428
3429 static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info,
3430 unsigned long addr)
3431 {
3432 struct atyfb_par *par = info->par;
3433 u16 tmp;
3434 unsigned long raddr;
3435 struct resource *rrp;
3436 int ret = 0;
3437
3438 raddr = addr + 0x7ff000UL;
3439 rrp = &pdev->resource[2];
3440 if ((rrp->flags & IORESOURCE_MEM) &&
3441 request_mem_region(rrp->start, resource_size(rrp), "atyfb")) {
3442 par->aux_start = rrp->start;
3443 par->aux_size = resource_size(rrp);
3444 raddr = rrp->start;
3445 PRINTKI("using auxiliary register aperture\n");
3446 }
3447
3448 info->fix.mmio_start = raddr;
3449
3450
3451
3452
3453 par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
3454 if (par->ati_regbase == NULL)
3455 return -ENOMEM;
3456
3457 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3458 par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3459
3460
3461
3462
3463
3464 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3465 if (!(tmp & PCI_COMMAND_MEMORY)) {
3466 tmp |= PCI_COMMAND_MEMORY;
3467 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3468 }
3469 #ifdef __BIG_ENDIAN
3470
3471 addr += 0x800000;
3472 #endif
3473
3474
3475 info->fix.smem_start = addr;
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488 info->fix.smem_len = 0x800000;
3489
3490 aty_fudge_framebuffer_len(info);
3491
3492 info->screen_base = ioremap_wc(info->fix.smem_start,
3493 info->fix.smem_len);
3494 if (info->screen_base == NULL) {
3495 ret = -ENOMEM;
3496 goto atyfb_setup_generic_fail;
3497 }
3498
3499 ret = correct_chipset(par);
3500 if (ret)
3501 goto atyfb_setup_generic_fail;
3502 #ifdef __i386__
3503 ret = init_from_bios(par);
3504 if (ret)
3505 goto atyfb_setup_generic_fail;
3506 #endif
3507 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3508 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3509 else
3510 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3511
3512
3513 par->clk_wr_offset = 3;
3514
3515 return 0;
3516
3517 atyfb_setup_generic_fail:
3518 iounmap(par->ati_regbase);
3519 par->ati_regbase = NULL;
3520 if (info->screen_base) {
3521 iounmap(info->screen_base);
3522 info->screen_base = NULL;
3523 }
3524 return ret;
3525 }
3526
3527 #endif
3528
3529 static int atyfb_pci_probe(struct pci_dev *pdev,
3530 const struct pci_device_id *ent)
3531 {
3532 unsigned long addr, res_start, res_size;
3533 struct fb_info *info;
3534 struct resource *rp;
3535 struct atyfb_par *par;
3536 int rc = -ENOMEM;
3537
3538
3539 if (pci_enable_device(pdev)) {
3540 PRINTKE("Cannot enable PCI device\n");
3541 return -ENXIO;
3542 }
3543
3544
3545 rp = &pdev->resource[0];
3546 if (rp->flags & IORESOURCE_IO)
3547 rp = &pdev->resource[1];
3548 addr = rp->start;
3549 if (!addr)
3550 return -ENXIO;
3551
3552
3553 res_start = rp->start;
3554 res_size = resource_size(rp);
3555 if (!request_mem_region(res_start, res_size, "atyfb"))
3556 return -EBUSY;
3557
3558
3559 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3560 if (!info)
3561 return -ENOMEM;
3562
3563 par = info->par;
3564 par->bus_type = PCI;
3565 info->fix = atyfb_fix;
3566 info->device = &pdev->dev;
3567 par->pci_id = pdev->device;
3568 par->res_start = res_start;
3569 par->res_size = res_size;
3570 par->irq = pdev->irq;
3571 par->pdev = pdev;
3572
3573
3574 #ifdef __sparc__
3575 rc = atyfb_setup_sparc(pdev, info, addr);
3576 #else
3577 rc = atyfb_setup_generic(pdev, info, addr);
3578 #endif
3579 if (rc)
3580 goto err_release_mem;
3581
3582 pci_set_drvdata(pdev, info);
3583
3584
3585 rc = aty_init(info);
3586 if (rc)
3587 goto err_release_io;
3588
3589 #ifdef __sparc__
3590
3591
3592
3593 par->mmap_map[0].voff = 0x8000000000000000UL;
3594 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3595 par->mmap_map[0].size = info->fix.smem_len;
3596 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3597 par->mmap_map[0].prot_flag = _PAGE_E;
3598 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3599 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3600 par->mmap_map[1].size = PAGE_SIZE;
3601 par->mmap_map[1].prot_mask = _PAGE_CACHE;
3602 par->mmap_map[1].prot_flag = _PAGE_E;
3603 #endif
3604
3605 mutex_lock(&reboot_lock);
3606 if (!reboot_info)
3607 reboot_info = info;
3608 mutex_unlock(&reboot_lock);
3609
3610 return 0;
3611
3612 err_release_io:
3613 #ifdef __sparc__
3614 kfree(par->mmap_map);
3615 #else
3616 if (par->ati_regbase)
3617 iounmap(par->ati_regbase);
3618 if (info->screen_base)
3619 iounmap(info->screen_base);
3620 #endif
3621 err_release_mem:
3622 if (par->aux_start)
3623 release_mem_region(par->aux_start, par->aux_size);
3624
3625 release_mem_region(par->res_start, par->res_size);
3626 framebuffer_release(info);
3627
3628 return rc;
3629 }
3630
3631 #endif
3632
3633 #ifdef CONFIG_ATARI
3634
3635 static int __init atyfb_atari_probe(void)
3636 {
3637 struct atyfb_par *par;
3638 struct fb_info *info;
3639 int m64_num;
3640 u32 clock_r;
3641 int num_found = 0;
3642
3643 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3644 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3645 !phys_guiregbase[m64_num]) {
3646 PRINTKI("phys_*[%d] parameters not set => "
3647 "returning early. \n", m64_num);
3648 continue;
3649 }
3650
3651 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3652 if (!info)
3653 return -ENOMEM;
3654
3655 par = info->par;
3656
3657 info->fix = atyfb_fix;
3658
3659 par->irq = (unsigned int) -1;
3660
3661
3662
3663
3664
3665 info->screen_base = ioremap_wc(phys_vmembase[m64_num],
3666 phys_size[m64_num]);
3667 info->fix.smem_start = (unsigned long)info->screen_base;
3668 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3669 0xFC00ul;
3670 info->fix.mmio_start = (unsigned long)par->ati_regbase;
3671
3672 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3673 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3674
3675 switch (clock_r & 0x003F) {
3676 case 0x12:
3677 par->clk_wr_offset = 3;
3678 break;
3679 case 0x34:
3680 par->clk_wr_offset = 2;
3681 break;
3682 case 0x16:
3683 par->clk_wr_offset = 1;
3684 break;
3685 case 0x38:
3686 par->clk_wr_offset = 0;
3687 break;
3688 }
3689
3690
3691 switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) {
3692 case 0x00d7:
3693 par->pci_id = PCI_CHIP_MACH64GX;
3694 break;
3695 case 0x0057:
3696 par->pci_id = PCI_CHIP_MACH64CX;
3697 break;
3698 default:
3699 break;
3700 }
3701
3702 if (correct_chipset(par) || aty_init(info)) {
3703 iounmap(info->screen_base);
3704 iounmap(par->ati_regbase);
3705 framebuffer_release(info);
3706 } else {
3707 num_found++;
3708 }
3709 }
3710
3711 return num_found ? 0 : -ENXIO;
3712 }
3713
3714 #endif
3715
3716 #ifdef CONFIG_PCI
3717
3718 static void atyfb_remove(struct fb_info *info)
3719 {
3720 struct atyfb_par *par = (struct atyfb_par *) info->par;
3721
3722
3723 aty_set_crtc(par, &par->saved_crtc);
3724 par->pll_ops->set_pll(info, &par->saved_pll);
3725
3726 unregister_framebuffer(info);
3727
3728 #ifdef CONFIG_FB_ATY_BACKLIGHT
3729 if (M64_HAS(MOBIL_BUS))
3730 aty_bl_exit(info->bl_dev);
3731 #endif
3732 arch_phys_wc_del(par->wc_cookie);
3733
3734 #ifndef __sparc__
3735 if (par->ati_regbase)
3736 iounmap(par->ati_regbase);
3737 if (info->screen_base)
3738 iounmap(info->screen_base);
3739 #ifdef __BIG_ENDIAN
3740 if (info->sprite.addr)
3741 iounmap(info->sprite.addr);
3742 #endif
3743 #endif
3744 #ifdef __sparc__
3745 kfree(par->mmap_map);
3746 #endif
3747 if (par->aux_start)
3748 release_mem_region(par->aux_start, par->aux_size);
3749
3750 if (par->res_start)
3751 release_mem_region(par->res_start, par->res_size);
3752
3753 framebuffer_release(info);
3754 }
3755
3756
3757 static void atyfb_pci_remove(struct pci_dev *pdev)
3758 {
3759 struct fb_info *info = pci_get_drvdata(pdev);
3760
3761 mutex_lock(&reboot_lock);
3762 if (reboot_info == info)
3763 reboot_info = NULL;
3764 mutex_unlock(&reboot_lock);
3765
3766 atyfb_remove(info);
3767 }
3768
3769 static const struct pci_device_id atyfb_pci_tbl[] = {
3770 #ifdef CONFIG_FB_ATY_GX
3771 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) },
3772 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) },
3773 #endif
3774
3775 #ifdef CONFIG_FB_ATY_CT
3776 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CT) },
3777 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64ET) },
3778
3779 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LT) },
3780
3781 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VT) },
3782 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GT) },
3783
3784 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VU) },
3785 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GU) },
3786
3787 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LG) },
3788
3789 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VV) },
3790
3791 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GV) },
3792 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GW) },
3793 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GY) },
3794 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GZ) },
3795
3796 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GB) },
3797 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GD) },
3798 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GI) },
3799 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GP) },
3800 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GQ) },
3801
3802 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LB) },
3803 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LD) },
3804 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LI) },
3805 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LP) },
3806 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LQ) },
3807
3808 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GM) },
3809 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GN) },
3810 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GO) },
3811 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GL) },
3812 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GR) },
3813 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GS) },
3814
3815 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LM) },
3816 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LN) },
3817 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LR) },
3818 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LS) },
3819 #endif
3820 { }
3821 };
3822
3823 MODULE_DEVICE_TABLE(pci, atyfb_pci_tbl);
3824
3825 static struct pci_driver atyfb_driver = {
3826 .name = "atyfb",
3827 .id_table = atyfb_pci_tbl,
3828 .probe = atyfb_pci_probe,
3829 .remove = atyfb_pci_remove,
3830 .driver.pm = &atyfb_pci_pm_ops,
3831 };
3832
3833 #endif
3834
3835 #ifndef MODULE
3836 static int __init atyfb_setup(char *options)
3837 {
3838 char *this_opt;
3839
3840 if (!options || !*options)
3841 return 0;
3842
3843 while ((this_opt = strsep(&options, ",")) != NULL) {
3844 if (!strncmp(this_opt, "noaccel", 7)) {
3845 noaccel = true;
3846 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3847 nomtrr = true;
3848 } else if (!strncmp(this_opt, "vram:", 5))
3849 vram = simple_strtoul(this_opt + 5, NULL, 0);
3850 else if (!strncmp(this_opt, "pll:", 4))
3851 pll = simple_strtoul(this_opt + 4, NULL, 0);
3852 else if (!strncmp(this_opt, "mclk:", 5))
3853 mclk = simple_strtoul(this_opt + 5, NULL, 0);
3854 else if (!strncmp(this_opt, "xclk:", 5))
3855 xclk = simple_strtoul(this_opt+5, NULL, 0);
3856 else if (!strncmp(this_opt, "comp_sync:", 10))
3857 comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3858 else if (!strncmp(this_opt, "backlight:", 10))
3859 backlight = simple_strtoul(this_opt+10, NULL, 0);
3860 #ifdef CONFIG_PPC
3861 else if (!strncmp(this_opt, "vmode:", 6)) {
3862 unsigned int vmode =
3863 simple_strtoul(this_opt + 6, NULL, 0);
3864 if (vmode > 0 && vmode <= VMODE_MAX)
3865 default_vmode = vmode;
3866 } else if (!strncmp(this_opt, "cmode:", 6)) {
3867 unsigned int cmode =
3868 simple_strtoul(this_opt + 6, NULL, 0);
3869 switch (cmode) {
3870 case 0:
3871 case 8:
3872 default_cmode = CMODE_8;
3873 break;
3874 case 15:
3875 case 16:
3876 default_cmode = CMODE_16;
3877 break;
3878 case 24:
3879 case 32:
3880 default_cmode = CMODE_32;
3881 break;
3882 }
3883 }
3884 #endif
3885 #ifdef CONFIG_ATARI
3886
3887
3888
3889
3890 else if (MACH_IS_ATARI
3891 && (!strncmp(this_opt, "Mach64:", 7))) {
3892 static unsigned char m64_num;
3893 static char mach64_str[80];
3894 strscpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3895 if (!store_video_par(mach64_str, m64_num)) {
3896 m64_num++;
3897 mach64_count = m64_num;
3898 }
3899 }
3900 #endif
3901 else
3902 mode = this_opt;
3903 }
3904 return 0;
3905 }
3906 #endif
3907
3908 static int atyfb_reboot_notify(struct notifier_block *nb,
3909 unsigned long code, void *unused)
3910 {
3911 struct atyfb_par *par;
3912
3913 if (code != SYS_RESTART)
3914 return NOTIFY_DONE;
3915
3916 mutex_lock(&reboot_lock);
3917
3918 if (!reboot_info)
3919 goto out;
3920
3921 lock_fb_info(reboot_info);
3922
3923 par = reboot_info->par;
3924
3925
3926
3927
3928
3929
3930 aty_set_crtc(par, &par->saved_crtc);
3931 par->pll_ops->set_pll(reboot_info, &par->saved_pll);
3932
3933 unlock_fb_info(reboot_info);
3934 out:
3935 mutex_unlock(&reboot_lock);
3936
3937 return NOTIFY_DONE;
3938 }
3939
3940 static struct notifier_block atyfb_reboot_notifier = {
3941 .notifier_call = atyfb_reboot_notify,
3942 };
3943
3944 static const struct dmi_system_id atyfb_reboot_ids[] __initconst = {
3945 {
3946 .ident = "HP OmniBook 500",
3947 .matches = {
3948 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
3949 DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
3950 DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"),
3951 },
3952 },
3953
3954 { }
3955 };
3956 static bool registered_notifier = false;
3957
3958 static int __init atyfb_init(void)
3959 {
3960 int err1 = 1, err2 = 1;
3961 #ifndef MODULE
3962 char *option = NULL;
3963
3964 if (fb_get_options("atyfb", &option))
3965 return -ENODEV;
3966 atyfb_setup(option);
3967 #endif
3968
3969 #ifdef CONFIG_PCI
3970 err1 = pci_register_driver(&atyfb_driver);
3971 #endif
3972 #ifdef CONFIG_ATARI
3973 err2 = atyfb_atari_probe();
3974 #endif
3975
3976 if (err1 && err2)
3977 return -ENODEV;
3978
3979 if (dmi_check_system(atyfb_reboot_ids)) {
3980 register_reboot_notifier(&atyfb_reboot_notifier);
3981 registered_notifier = true;
3982 }
3983
3984 return 0;
3985 }
3986
3987 static void __exit atyfb_exit(void)
3988 {
3989 if (registered_notifier)
3990 unregister_reboot_notifier(&atyfb_reboot_notifier);
3991
3992 #ifdef CONFIG_PCI
3993 pci_unregister_driver(&atyfb_driver);
3994 #endif
3995 }
3996
3997 module_init(atyfb_init);
3998 module_exit(atyfb_exit);
3999
4000 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
4001 MODULE_LICENSE("GPL");
4002 module_param(noaccel, bool, 0);
4003 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
4004 module_param(vram, int, 0);
4005 MODULE_PARM_DESC(vram, "int: override size of video ram");
4006 module_param(pll, int, 0);
4007 MODULE_PARM_DESC(pll, "int: override video clock");
4008 module_param(mclk, int, 0);
4009 MODULE_PARM_DESC(mclk, "int: override memory clock");
4010 module_param(xclk, int, 0);
4011 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
4012 module_param(comp_sync, int, 0);
4013 MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)");
4014 module_param(mode, charp, 0);
4015 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
4016 module_param(nomtrr, bool, 0);
4017 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");