X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Faty%2Fatyfb_base.c;fp=drivers%2Fvideo%2Faty%2Fatyfb_base.c;h=d9d7d3c4cae2ed83b81b4b8db846d7fa8d826ed6;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=8c42538dc8c12db3ff65be3721bf6f3935e0533e;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 8c42538dc..d9d7d3c4c 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -75,6 +75,7 @@ #include "ati_ids.h" #ifdef __powerpc__ +#include #include #include "../macmodes.h" #endif @@ -109,9 +110,18 @@ #define GUI_RESERVE (1 * PAGE_SIZE) /* FIXME: remove the FAIL definition */ -#define FAIL(msg) do { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0) -#define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0) - +#define FAIL(msg) do { \ + if (!(var->activate & FB_ACTIVATE_TEST)) \ + printk(KERN_CRIT "atyfb: " msg "\n"); \ + return -EINVAL; \ +} while (0) +#define FAIL_MAX(msg, x, _max_) do { \ + if (x > _max_) { \ + if (!(var->activate & FB_ACTIVATE_TEST)) \ + printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \ + return -EINVAL; \ + } \ +} while (0) #ifdef DEBUG #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args) #else @@ -229,13 +239,12 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info); static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); static int atyfb_blank(int blank, struct fb_info *info); -static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg, struct fb_info *info); +static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image); #ifdef __sparc__ -static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma); +static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); #endif static int atyfb_sync(struct fb_info *info); @@ -292,7 +301,6 @@ static struct fb_ops atyfb_ops = { .fb_fillrect = atyfb_fillrect, .fb_copyarea = atyfb_copyarea, .fb_imageblit = atyfb_imageblit, - .fb_cursor = soft_cursor, #ifdef __sparc__ .fb_mmap = atyfb_mmap, #endif @@ -341,6 +349,7 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL) #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP) +/* FIXME what is this chip? */ #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP) /* make sets shorter */ @@ -360,58 +369,60 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; static struct { u16 pci_id; const char *name; - int pll, mclk, xclk; + int pll, mclk, xclk, ecp_max; u32 features; } aty_chips[] __devinitdata = { #ifdef CONFIG_FB_ATY_GX /* Mach64 GX */ - { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX }, - { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX }, + { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX }, + { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX }, #endif /* CONFIG_FB_ATY_GX */ #ifdef CONFIG_FB_ATY_CT - { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT }, - { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET }, - { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT }, - { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT }, - /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */ - { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB }, - { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 }, - - { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT }, - /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */ - { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, - - { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 }, - - { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, - - { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, - { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO }, - - { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, - { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, - - { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL }, - - { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT }, + { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET }, + + /* FIXME what is this chip? */ + { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT }, + + { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT }, + { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT }, + + { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 }, + { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB }, + + { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, + + { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 }, + + { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + + { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, + { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + + { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + { 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 }, + { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + + { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, + { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL }, + + { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, #endif /* CONFIG_FB_ATY_CT */ }; @@ -424,7 +435,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) const char *name; int i; - for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) + for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) if (par->pci_id == aty_chips[i].pci_id) break; @@ -432,6 +443,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) par->pll_limits.pll_max = aty_chips[i].pll; par->pll_limits.mclk = aty_chips[i].mclk; par->pll_limits.xclk = aty_chips[i].xclk; + par->pll_limits.ecp_max = aty_chips[i].ecp_max; par->features = aty_chips[i].features; chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); @@ -451,39 +463,63 @@ static int __devinit correct_chipset(struct atyfb_par *par) #endif #ifdef CONFIG_FB_ATY_CT case PCI_CHIP_MACH64VT: - rev &= 0xc7; - if(rev == 0x00) { - name = "ATI264VTA3 (Mach64 VT)"; - par->pll_limits.pll_max = 170; - par->pll_limits.mclk = 67; - par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VT; - } else if(rev == 0x40) { - name = "ATI264VTA4 (Mach64 VT)"; + switch (rev & 0x07) { + case 0x00: + switch (rev & 0xc0) { + case 0x00: + name = "ATI264VT (A3) (Mach64 VT)"; + par->pll_limits.pll_max = 170; + par->pll_limits.mclk = 67; + par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT; + break; + case 0x40: + name = "ATI264VT2 (A4) (Mach64 VT)"; + par->pll_limits.pll_max = 200; + par->pll_limits.mclk = 67; + par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; + break; + } + break; + case 0x01: + name = "ATI264VT3 (B1) (Mach64 VT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; - } else { - name = "ATI264VTB (Mach64 VT)"; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VTB; + break; + case 0x02: + name = "ATI264VT3 (B2) (Mach64 VT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VTB; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT3; + break; } break; case PCI_CHIP_MACH64GT: - rev &= 0x07; - if(rev == 0x01) { + switch (rev & 0x07) { + case 0x01: + name = "3D RAGE II (Mach64 GT)"; par->pll_limits.pll_max = 170; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; par->features = ATI_CHIP_264GTB; - } else if(rev == 0x02) { + break; + case 0x02: + name = "3D RAGE II+ (Mach64 GT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 100; par->features = ATI_CHIP_264GTB; + break; } break; #endif @@ -693,7 +729,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | (SHADOW_EN | SHADOW_RW_EN), par); - DPRINTK("set secondary CRT to %ix%i %c%c\n", + DPRINTK("set shadow CRT to %ix%i %c%c\n", ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); @@ -841,11 +877,14 @@ static int aty_var_to_crtc(const struct fb_info *info, know if one is connected. So it's better to fail then. */ if (crtc->lcd_gen_cntl & CRT_ON) { - PRINTKI("Disable lcd panel, because video mode does not fit.\n"); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKI("Disable LCD panel, because video mode does not fit.\n"); crtc->lcd_gen_cntl &= ~LCD_ON; /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/ } else { - FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode."); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n"); + return -EINVAL; } } } @@ -859,9 +898,9 @@ static int aty_var_to_crtc(const struct fb_info *info, vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); /* This is horror! When we simulate, say 640x480 on an 800x600 - lcd monitor, the CRTC should be programmed 800x600 values for + LCD monitor, the CRTC should be programmed 800x600 values for the non visible part, but 640x480 for the visible part. - This code has been tested on a laptop with it's 1400x1050 lcd + This code has been tested on a laptop with it's 1400x1050 LCD monitor and a conventional monitor both switched on. Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, works with little glitches also with DOUBLESCAN modes @@ -911,20 +950,6 @@ static int aty_var_to_crtc(const struct fb_info *info, vdisplay = par->lcd_height; #endif - if(vdisplay < 400) { - h_sync_pol = 1; - v_sync_pol = 0; - } else if(vdisplay < 480) { - h_sync_pol = 0; - v_sync_pol = 1; - } else if(vdisplay < 768) { - h_sync_pol = 0; - v_sync_pol = 0; - } else { - h_sync_pol = 1; - v_sync_pol = 1; - } - v_disp--; v_sync_strt--; v_sync_end--; @@ -970,16 +995,6 @@ static int aty_var_to_crtc(const struct fb_info *info, vdisplay = yres; if(vmode & FB_VMODE_DOUBLE) vdisplay <<= 1; - if(vmode & FB_VMODE_INTERLACED) { - vdisplay >>= 1; - - /* The prefered mode for the lcd is not interlaced, so disable it if - it was enabled. For doublescan there is no problem, because we can - compensate for it in the hardware stretching (we stretch half as much) - */ - vmode &= ~FB_VMODE_INTERLACED; - /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/ - } crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ @@ -995,7 +1010,7 @@ static int aty_var_to_crtc(const struct fb_info *info, crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); - if (xres < par->lcd_width) { + if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { do { /* * The horizontal blender misbehaves when HDisplay is less than a @@ -1057,7 +1072,7 @@ static int aty_var_to_crtc(const struct fb_info *info, } while (0); } - if (vdisplay < par->lcd_height) { + if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) { crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); @@ -1080,9 +1095,8 @@ static int aty_var_to_crtc(const struct fb_info *info, #endif /* CONFIG_FB_ATY_GENERIC_LCD */ if (M64_HAS(MAGIC_FIFO)) { - /* Not VTB/GTB */ - /* FIXME: magic FIFO values */ - crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH); + /* FIXME: display FIFO low watermark values */ + crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM); } crtc->dp_pix_width = dp_pix_width; crtc->dp_chain_mask = dp_chain_mask; @@ -1199,7 +1213,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va var->transp.length = 8; break; default: - FAIL("Invalid pixel width"); + PRINTKE("Invalid pixel width\n"); + return -EINVAL; } /* output */ @@ -1256,7 +1271,8 @@ static int atyfb_set_par(struct fb_info *info) pixclock = atyfb_get_pixclock(var, par); if (pixclock == 0) { - FAIL("Invalid pixclock"); + PRINTKE("Invalid pixclock\n"); + return -EINVAL; } else { if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) return err; @@ -1461,7 +1477,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) pixclock = atyfb_get_pixclock(var, par); if (pixclock == 0) { - FAIL("Invalid pixclock"); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKE("Invalid pixclock\n"); + return -EINVAL; } else { if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) return err; @@ -1721,8 +1739,7 @@ struct atyclk { #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) #endif -static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg, struct fb_info *info) +static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) { struct atyfb_par *par = (struct atyfb_par *) info->par; #ifdef __sparc__ @@ -1827,7 +1844,7 @@ static int atyfb_sync(struct fb_info *info) } #ifdef __sparc__ -static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) +static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct atyfb_par *par = (struct atyfb_par *) info->par; unsigned int size, page, map_size = 0; @@ -2022,17 +2039,16 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct fb_info *info = pci_get_drvdata(pdev); struct atyfb_par *par = (struct atyfb_par *) info->par; -#ifdef CONFIG_PPC_PMAC +#ifndef CONFIG_PPC_PMAC /* HACK ALERT ! Once I find a proper way to say to each driver * individually what will happen with it's PCI slot, I'll change * that. On laptops, the AGP slot is just unclocked, so D2 is * expected, while on desktops, the card is powered off */ - if (state >= 3) - state = 2; + return 0; #endif /* CONFIG_PPC_PMAC */ - if (state != 2 || state == pdev->dev.power.power_state) + if (state.event == pdev->dev.power.power_state.event) return 0; acquire_console_sem(); @@ -2071,12 +2087,12 @@ static int atyfb_pci_resume(struct pci_dev *pdev) struct fb_info *info = pci_get_drvdata(pdev); struct atyfb_par *par = (struct atyfb_par *) info->par; - if (pdev->dev.power.power_state == 0) + if (pdev->dev.power.power_state.event == PM_EVENT_ON) return 0; acquire_console_sem(); - if (pdev->dev.power.power_state == 2) + if (pdev->dev.power.power_state.event == 2) aty_power_mgmt(0, par); par->asleep = 0; @@ -2153,10 +2169,10 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { refresh_tbl = ragexl_tbl; - size = sizeof(ragexl_tbl)/sizeof(int); + size = ARRAY_SIZE(ragexl_tbl); } else { refresh_tbl = ragepro_tbl; - size = sizeof(ragepro_tbl)/sizeof(int); + size = ARRAY_SIZE(ragepro_tbl); } for (i=0; i < size; i++) { @@ -2172,11 +2188,38 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) static struct fb_info *fb_list = NULL; +#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) +static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par, + struct fb_var_screeninfo *var) +{ + int ret = -EINVAL; + + if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { + *var = default_var; + var->xres = var->xres_virtual = par->lcd_hdisp; + var->right_margin = par->lcd_right_margin; + var->left_margin = par->lcd_hblank_len - + (par->lcd_right_margin + par->lcd_hsync_dly + + par->lcd_hsync_len); + var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly; + var->yres = var->yres_virtual = par->lcd_vdisp; + var->lower_margin = par->lcd_lower_margin; + var->upper_margin = par->lcd_vblank_len - + (par->lcd_lower_margin + par->lcd_vsync_len); + var->vsync_len = par->lcd_vsync_len; + var->pixclock = par->lcd_pixclock; + ret = 0; + } + + return ret; +} +#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ + static int __init aty_init(struct fb_info *info, const char *name) { struct atyfb_par *par = (struct atyfb_par *) info->par; const char *ramname = NULL, *xtal; - int gtb_memsize; + int gtb_memsize, has_var = 0; struct fb_var_screeninfo var; u8 pll_ref_div; u32 i; @@ -2256,6 +2299,10 @@ static int __init aty_init(struct fb_info *info, const char *name) case CLK_ATI18818_1: par->pll_ops = &aty_pll_ati18818_1; break; + case CLK_IBMRGB514: + par->pll_ops = &aty_pll_ibm514; + break; +#if 0 /* dead code */ case CLK_STG1703: par->pll_ops = &aty_pll_stg1703; break; @@ -2265,9 +2312,7 @@ static int __init aty_init(struct fb_info *info, const char *name) case CLK_ATT20C408: par->pll_ops = &aty_pll_att20c408; break; - case CLK_IBMRGB514: - par->pll_ops = &aty_pll_ibm514; - break; +#endif default: PRINTKI("aty_init: CLK type not implemented yet!"); par->pll_ops = &aty_pll_unsupported; @@ -2280,10 +2325,6 @@ static int __init aty_init(struct fb_info *info, const char *name) par->dac_ops = &aty_dac_ct; par->pll_ops = &aty_pll_ct; par->bus_type = PCI; -#ifdef CONFIG_FB_ATY_XL_INIT - if (IS_XL(par->pci_id)) - atyfb_xl_init(info); -#endif par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); ramname = aty_ct_ram[par->ram_type]; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ @@ -2478,14 +2519,14 @@ static int __init aty_init(struct fb_info *info, const char *name) memset(&var, 0, sizeof(var)); #ifdef CONFIG_PPC - if (_machine == _MACH_Pmac) { + if (machine_is(powermac)) { /* * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it * applies to all Mac video cards */ if (mode) { - if (!mac_find_mode(&var, info, mode, 8)) - var = default_var; + if (mac_find_mode(&var, info, mode, 8)) + has_var = 1; } else { if (default_vmode == VMODE_CHOOSE) { if (M64_HAS(G3_PB_1024x768)) @@ -2507,20 +2548,23 @@ static int __init aty_init(struct fb_info *info, const char *name) default_vmode = VMODE_640_480_60; if (default_cmode < CMODE_8 || default_cmode > CMODE_32) default_cmode = CMODE_8; - if (mac_vmode_to_var(default_vmode, default_cmode, &var)) - var = default_var; + if (!mac_vmode_to_var(default_vmode, default_cmode, + &var)) + has_var = 1; } - } else + } + #endif /* !CONFIG_PPC */ - if ( -#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) - /* On Sparc, unless the user gave a specific mode - * specification, use the PROM probed values in - * default_var. - */ - !mode || + +#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) + if (!atyfb_get_timings_from_lcd(par, &var)) + has_var = 1; #endif - !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) + + if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) + has_var = 1; + + if (!has_var) var = default_var; if (noaccel) @@ -2624,16 +2668,16 @@ static int __init store_video_par(char *video_str, unsigned char m64_num) static int atyfb_blank(int blank, struct fb_info *info) { struct atyfb_par *par = (struct atyfb_par *) info->par; - u8 gen_cntl; + u32 gen_cntl; if (par->lock_blank || par->asleep) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if ((_machine == _MACH_Pmac) && blank) + if (machine_is(powermac) && blank > FB_BLANK_NORMAL) set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) - if (par->lcd_table && blank && + if (par->lcd_table && blank > FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); pm &= ~PWR_BLON; @@ -2641,31 +2685,31 @@ static int atyfb_blank(int blank, struct fb_info *info) } #endif - gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par); + gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); switch (blank) { case FB_BLANK_UNBLANK: - gen_cntl &= ~(0x4c); + gen_cntl &= ~0x400004c; break; case FB_BLANK_NORMAL: - gen_cntl |= 0x40; + gen_cntl |= 0x4000040; break; case FB_BLANK_VSYNC_SUSPEND: - gen_cntl |= 0x8; + gen_cntl |= 0x4000048; break; case FB_BLANK_HSYNC_SUSPEND: - gen_cntl |= 0x4; + gen_cntl |= 0x4000044; break; case FB_BLANK_POWERDOWN: - gen_cntl |= 0x4c; + gen_cntl |= 0x400004c; break; } - aty_st_8(CRTC_GEN_CNTL, gen_cntl, par); + aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if ((_machine == _MACH_Pmac) && !blank) + if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) - if (par->lcd_table && !blank && + if (par->lcd_table && blank <= FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); pm |= PWR_BLON; @@ -3143,15 +3187,15 @@ static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; /* We now need to determine the crtc parameters for the - * lcd monitor. This is tricky, because they are not stored + * LCD monitor. This is tricky, because they are not stored * individually in the BIOS. Instead, the BIOS contains a * table of display modes that work for this monitor. * * The idea is that we search for a mode of the same dimensions - * as the dimensions of the lcd monitor. Say our lcd monitor + * as the dimensions of the LCD monitor. Say our LCD monitor * is 800x600 pixels, we search for a 800x600 monitor. * The CRTC parameters we find here are the ones that we need - * to use to simulate other resolutions on the lcd screen. + * to use to simulate other resolutions on the LCD screen. */ lcdmodeptr = (u16 *)(par->lcd_table + 64); while (*lcdmodeptr != 0) { @@ -3356,7 +3400,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi struct atyfb_par *par; int i, rc = -ENOMEM; - for (i = sizeof(aty_chips) / sizeof(*aty_chips) - 1; i >= 0; i--) + for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) if (pdev->device == aty_chips[i].pci_id) break; @@ -3458,7 +3502,7 @@ err_release_mem: static int __devinit atyfb_atari_probe(void) { - struct aty_par *par; + struct atyfb_par *par; struct fb_info *info; int m64_num; u32 clock_r; @@ -3678,9 +3722,7 @@ static int __init atyfb_init(void) atyfb_setup(option); #endif -#ifdef CONFIG_PCI pci_register_driver(&atyfb_driver); -#endif #ifdef CONFIG_ATARI atyfb_atari_probe(); #endif @@ -3689,9 +3731,7 @@ static int __init atyfb_init(void) static void __exit atyfb_exit(void) { -#ifdef CONFIG_PCI pci_unregister_driver(&atyfb_driver); -#endif } module_init(atyfb_init);