VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / video / aty / radeon_base.c
index d88079e..bd3b24c 100644 (file)
@@ -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)) {