X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Faty%2Fradeon_base.c;h=bd3b24caad4fbe8c29dd70f0b3bfc64d74d6beb3;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=d88079eb98fffb9b37b1b8aa8b507325bc0f6e1b;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index d88079eb9..bd3b24caa 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -242,8 +242,6 @@ static int force_measure_pll = 0; static int nomtrr = 0; #endif -int radeonfb_noaccel = 0; - /* * prototypes */ @@ -388,7 +386,7 @@ static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev return -ENXIO; } -#ifdef __i386__ +#ifdef CONFIG_X86 static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo) { /* I simplified this code as we used to miss the signatures in @@ -417,7 +415,7 @@ static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo) return 0; } -#endif /* __i386__ */ +#endif #ifdef CONFIG_PPC_OF /* @@ -434,7 +432,7 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) printk(KERN_WARNING "radeonfb: Cannot match card to OF node !\n"); return -ENODEV; } - val = (u32 *) get_property(dp, "ATY,RefCLK", 0); + val = (u32 *) get_property(dp, "ATY,RefCLK", NULL); if (!val || !*val) { printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); return -EINVAL; @@ -442,11 +440,11 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) rinfo->pll.ref_clk = (*val) / 10; - val = (u32 *) get_property(dp, "ATY,SCLK", 0); + val = (u32 *) get_property(dp, "ATY,SCLK", NULL); if (val && *val) rinfo->pll.sclk = (*val) / 10; - val = (u32 *) get_property(dp, "ATY,MCLK", 0); + val = (u32 *) get_property(dp, "ATY,MCLK", NULL); if (val && *val) rinfo->pll.mclk = (*val) / 10; @@ -810,9 +808,8 @@ static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *in /* XXX I'm adjusting xres_virtual to the pitch, that may help XFree * with some panels, though I don't quite like this solution */ - if (radeon_accel_disabled()) { + if (rinfo->info->flags & FBINFO_HWACCEL_DISABLED) { v.xres_virtual = v.xres_virtual & ~7ul; - v.accel_flags = 0; } else { pitch = ((v.xres_virtual * ((v.bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; @@ -858,6 +855,7 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, if (rinfo->asleep) return 0; + radeon_fifo_wait(2); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -882,11 +880,12 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int if (!rinfo->is_mobility) return -EINVAL; - rc = get_user(value, (__u32*)arg); + rc = get_user(value, (__u32 __user *)arg); if (rc) return rc; + radeon_fifo_wait(2); if (value & 0x01) { tmp = INREG(LVDS_GEN_CNTL); @@ -926,7 +925,7 @@ static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int if (CRTC_CRT_ON & tmp) value |= 0x02; - return put_user(value, (__u32*)arg); + return put_user(value, (__u32 __user *)arg); default: return -EINVAL; } @@ -963,6 +962,7 @@ static int radeon_screen_blank (struct radeonfb_info *rinfo, int blank) break; } + radeon_fifo_wait(1); switch (rinfo->mon1_type) { case MT_LCD: OUTREG(LVDS_GEN_CNTL, val2); @@ -1021,6 +1021,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, if (!rinfo->asleep) { u32 dac_cntl2, vclk_cntl = 0; + radeon_fifo_wait(9); if (rinfo->is_mobility) { vclk_cntl = INPLL(VCLK_ECP_CNTL); OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); @@ -1112,6 +1113,8 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg { int i; + radeon_fifo_wait(20); + /* Workaround from XFree */ if (rinfo->is_mobility) { /* A temporal workaround for the occational blanking on certain laptop panels. @@ -1198,6 +1201,8 @@ static void radeon_lvds_timer_func(unsigned long data) { struct radeonfb_info *rinfo = (struct radeonfb_info *)data; + radeon_fifo_wait(3); + OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); if (rinfo->pending_pixclks_cntl) { OUTPLL(PIXCLKS_CNTL, rinfo->pending_pixclks_cntl); @@ -1222,6 +1227,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo, radeon_screen_blank(rinfo, VESA_POWERDOWN); + radeon_fifo_wait(31); for (i=0; i<10; i++) OUTREG(common_regs[i].reg, common_regs[i].val); @@ -1249,6 +1255,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo, radeon_write_pll_regs(rinfo, mode); if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { + radeon_fifo_wait(10); OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); @@ -1288,6 +1295,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo, radeon_screen_blank(rinfo, VESA_NO_BLANKING); + radeon_fifo_wait(2); OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); return; @@ -1524,7 +1532,7 @@ int radeonfb_set_par(struct fb_info *info) newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); - if (!radeon_accel_disabled()) { + if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { /* We first calculate the engine pitch */ rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; @@ -1672,12 +1680,11 @@ int radeonfb_set_par(struct fb_info *info) if (!rinfo->asleep) { radeon_write_mode (rinfo, &newmode); /* (re)initialize the engine */ - if (!radeon_accel_disabled()) + if (!(info->flags & FBINFO_HWACCEL_DISABLED)) radeonfb_engine_init (rinfo); - } /* Update fix */ - if (!radeon_accel_disabled()) + if (!(info->flags & FBINFO_HWACCEL_DISABLED)) info->fix.line_length = rinfo->pitch*64; else info->fix.line_length = mode->xres_virtual @@ -1696,7 +1703,7 @@ int radeonfb_set_par(struct fb_info *info) -static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t radeonfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; struct inode *inode = file->f_dentry->d_inode; @@ -1723,7 +1730,7 @@ static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t return count; } -static ssize_t radeonfb_write(struct file *file, const char *buf, size_t count, +static ssize_t radeonfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; @@ -1782,9 +1789,13 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->currcon = -1; info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; - info->flags = FBINFO_FLAG_DEFAULT; - info->fbops = &radeonfb_ops; - info->screen_base = (char *)rinfo->fb_base; + info->flags = FBINFO_DEFAULT + | FBINFO_HWACCEL_COPYAREA + | FBINFO_HWACCEL_FILLRECT + | FBINFO_HWACCEL_XPAN + | FBINFO_HWACCEL_YPAN; + info->fbops = &radeonfb_ops; + info->screen_base = (char *)rinfo->fb_base; /* Fill fix common fields */ strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); @@ -1798,17 +1809,11 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->fix.type_aux = 0; info->fix.mmio_start = rinfo->mmio_base_phys; info->fix.mmio_len = RADEON_REGSIZE; - if (radeon_accel_disabled()) - info->fix.accel = FB_ACCEL_NONE; - else - info->fix.accel = FB_ACCEL_ATI_RADEON; fb_alloc_cmap(&info->cmap, 256, 0); - if (radeon_accel_disabled()) - info->var.accel_flags &= ~FB_ACCELF_TEXT; - else - info->var.accel_flags |= FB_ACCELF_TEXT; + if (noaccel) + info->flags |= FBINFO_HWACCEL_DISABLED; return 0; } @@ -1864,6 +1869,7 @@ static int radeon_set_backlight_enable(int on, int level, void *data) del_timer_sync(&rinfo->lvds_timer); lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON); + radeon_fifo_wait(3); if (on && (level > BACKLIGHT_OFF)) { lvds_gen_cntl |= LVDS_DIGON; if (!(lvds_gen_cntl & LVDS_ON)) { @@ -2136,6 +2142,7 @@ static int radeonfb_pci_register (struct pci_dev *pdev, u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + radeon_fifo_wait(6); OUTREG(MC_FB_LOCATION, tom); OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); @@ -2255,20 +2262,34 @@ static int radeonfb_pci_register (struct pci_dev *pdev, /* * Map the BIOS ROM if any and retreive PLL parameters from - * either BIOS or Open Firmware + * the BIOS. We skip that on mobility chips as the real panel + * values we need aren't in the ROM but in the BIOS image in + * memory. This is definitely not the best meacnism though, + * we really need the arch code to tell us which is the "primary" + * video adapter to use the memory image (or better, the arch + * should provide us a copy of the BIOS image to shield us from + * archs who would store that elsewhere and/or could initialize + * more than one adapter during boot). */ - radeon_map_ROM(rinfo, pdev); + if (!rinfo->is_mobility) + radeon_map_ROM(rinfo, pdev); /* * On x86, the primary display on laptop may have it's BIOS * ROM elsewhere, try to locate it at the legacy memory hole. - * We probably need to make sure this is the primary dispay, + * We probably need to make sure this is the primary display, * but that is difficult without some arch support. */ -#ifdef __i386__ +#ifdef CONFIG_X86 if (rinfo->bios_seg == NULL) radeon_find_mem_vbios(rinfo); -#endif /* __i386__ */ +#endif + + /* If both above failed, try the BIOS ROM again for mobility + * chips + */ + if (rinfo->bios_seg == NULL && rinfo->is_mobility) + radeon_map_ROM(rinfo, pdev); /* Get informations about the board's PLL */ radeon_get_pllinfo(rinfo); @@ -2424,7 +2445,6 @@ static struct pci_driver radeonfb_driver = { int __init radeonfb_init (void) { - radeonfb_noaccel = noaccel; return pci_module_init (&radeonfb_driver); } @@ -2446,7 +2466,7 @@ int __init radeonfb_setup (char *options) continue; if (!strncmp(this_opt, "noaccel", 7)) { - noaccel = radeonfb_noaccel = 1; + noaccel = 1; } else if (!strncmp(this_opt, "mirror", 6)) { mirror = 1; } else if (!strncmp(this_opt, "force_dfp", 9)) {