static int nomtrr = 0;
#endif
-int radeonfb_noaccel = 0;
-
/*
* prototypes
*/
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
return 0;
}
-#endif /* __i386__ */
+#endif
#ifdef CONFIG_PPC_OF
/*
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;
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;
/* 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;
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;
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);
if (CRTC_CRT_ON & tmp)
value |= 0x02;
- return put_user(value, (__u32*)arg);
+ return put_user(value, (__u32 __user *)arg);
default:
return -EINVAL;
}
break;
}
+ radeon_fifo_wait(1);
switch (rinfo->mon1_type) {
case MT_LCD:
OUTREG(LVDS_GEN_CNTL, val2);
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);
{
int i;
+ radeon_fifo_wait(20);
+
/* Workaround from XFree */
if (rinfo->is_mobility) {
/* A temporal workaround for the occational blanking on certain laptop panels.
{
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);
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);
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);
radeon_screen_blank(rinfo, VESA_NO_BLANKING);
+ radeon_fifo_wait(2);
OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
return;
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;
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
-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;
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;
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));
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;
}
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)) {
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);
/*
* 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);
int __init radeonfb_init (void)
{
- radeonfb_noaccel = noaccel;
return pci_module_init (&radeonfb_driver);
}
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)) {