* Anthony Tong <atong@uiuc.edu>
*
* Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
- * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
+ * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
#include <linux/backlight.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <video/mach64.h>
#include "atyfb.h"
#include "../macmodes.h"
#endif
#ifdef __sparc__
-#include <asm/pbm.h>
#include <asm/fbio.h>
+#include <asm/oplib.h>
+#include <asm/prom.h>
#endif
#ifdef CONFIG_ADB_PMU
#define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
-#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
+#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
+defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
static const u32 lt_lcd_regs[] = {
CONFIG_PANEL_LG,
LCD_GEN_CNTL_LG,
* The Hardware parameters for each card
*/
-struct aty_cmap_regs {
- u8 windex;
- u8 lut;
- u8 mask;
- u8 rindex;
- u8 cntl;
-};
-
struct pci_mmap_map {
unsigned long voff;
unsigned long poff;
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 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 vm_area_struct *vma);
#endif
* Internal routines
*/
-static int aty_init(struct fb_info *info, const char *name);
+static int aty_init(struct fb_info *info);
+static void aty_resume_chip(struct fb_info *info);
#ifdef CONFIG_ATARI
static int store_video_par(char *videopar, unsigned char m64_num);
#endif
static int comp_sync __devinitdata = -1;
static char *mode;
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight __devinitdata = 1;
+#else
+static int backlight __devinitdata = 0;
+#endif
+
#ifdef CONFIG_PPC
static int default_vmode __devinitdata = VMODE_CHOOSE;
static int default_cmode __devinitdata = CMODE_CHOOSE;
{ 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_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
{ 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 },
#endif /* CONFIG_FB_ATY_CT */
-static u32 pseudo_palette[17];
-
#ifdef CONFIG_FB_ATY_GX
static char *aty_gx_ram[8] __devinitdata = {
ram_dram, ram_vram, ram_vram, ram_dram,
else
info->var.accel_flags = 0;
-#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
- if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
- return -EINVAL;
-#endif
aty_crtc_to_var(&crtc, var);
var->pixclock = par->pll_ops->pll_to_var(info, &pll);
return 0;
return (0);
}
-static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t aty_irq(int irq, void *dev_id)
{
struct atyfb_par *par = dev_id;
int handled = 0;
par->mmaped = 1;
return 0;
}
-
-static struct {
- u32 yoffset;
- u8 r[2][256];
- u8 g[2][256];
- u8 b[2][256];
-} atyfb_save;
-
-static void atyfb_save_palette(struct atyfb_par *par, int enter)
-{
- int i, tmp;
-
- for (i = 0; i < 256; i++) {
- tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
- if (M64_HAS(EXTRA_BRIGHT))
- tmp |= 0x2;
- aty_st_8(DAC_CNTL, tmp, par);
- aty_st_8(DAC_MASK, 0xff, par);
-
- writeb(i, &par->aty_cmap_regs->rindex);
- atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
- atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
- atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
- writeb(i, &par->aty_cmap_regs->windex);
- writeb(atyfb_save.r[1 - enter][i],
- &par->aty_cmap_regs->lut);
- writeb(atyfb_save.g[1 - enter][i],
- &par->aty_cmap_regs->lut);
- writeb(atyfb_save.b[1 - enter][i],
- &par->aty_cmap_regs->lut);
- }
-}
-
-static void atyfb_palette(int enter)
-{
- struct atyfb_par *par;
- struct fb_info *info;
- int i;
-
- for (i = 0; i < FB_MAX; i++) {
- info = registered_fb[i];
- if (info && info->fbops == &atyfb_ops) {
- par = (struct atyfb_par *) info->par;
-
- atyfb_save_palette(par, enter);
- if (enter) {
- atyfb_save.yoffset = info->var.yoffset;
- info->var.yoffset = 0;
- set_off_pitch(par, info);
- } else {
- info->var.yoffset = atyfb_save.yoffset;
- set_off_pitch(par, info);
- }
- aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
- break;
- }
- }
-}
#endif /* __sparc__ */
#if defined(CONFIG_PM) && defined(CONFIG_PCI)
+#ifdef CONFIG_PPC_PMAC
/* Power management routines. Those are used for PowerBook sleep.
*/
static int aty_power_mgmt(int sleep, struct atyfb_par *par)
return timeout ? 0 : -EIO;
}
+#endif
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;
-#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
- */
- return 0;
-#endif /* CONFIG_PPC_PMAC */
-
if (state.event == pdev->dev.power.power_state.event)
return 0;
par->asleep = 1;
par->lock_blank = 1;
+#ifdef CONFIG_PPC_PMAC
/* Set chip to "suspend" mode */
if (aty_power_mgmt(1, par)) {
par->asleep = 0;
release_console_sem();
return -EIO;
}
+#else
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#endif
release_console_sem();
acquire_console_sem();
+#ifdef CONFIG_PPC_PMAC
if (pdev->dev.power.power_state.event == 2)
aty_power_mgmt(0, par);
+#else
+ pci_set_power_state(pdev, PCI_D0);
+#endif
+
+ aty_resume_chip(info);
+
par->asleep = 0;
/* Restore display */
#ifdef CONFIG_FB_ATY_BACKLIGHT
#define MAX_LEVEL 0xFF
-static struct backlight_properties aty_bl_data;
-
static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
int atylevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
+ /* No locking of bl_curve since we read a single value */
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
if (atylevel < 0)
atylevel = 0;
static int aty_bl_update_status(struct backlight_device *bd)
{
- struct atyfb_par *par = class_get_devdata(&bd->class_dev);
+ struct atyfb_par *par = bl_get_data(bd);
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
int level;
- if (bd->props->power != FB_BLANK_UNBLANK ||
- bd->props->fb_blank != FB_BLANK_UNBLANK)
+ if (bd->props.power != FB_BLANK_UNBLANK ||
+ bd->props.fb_blank != FB_BLANK_UNBLANK)
level = 0;
else
- level = bd->props->brightness;
+ level = bd->props.brightness;
reg |= (BLMOD_EN | BIASMOD_EN);
if (level > 0) {
static int aty_bl_get_brightness(struct backlight_device *bd)
{
- return bd->props->brightness;
+ return bd->props.brightness;
}
-static struct backlight_properties aty_bl_data = {
- .owner = THIS_MODULE,
+static struct backlight_ops aty_bl_data = {
.get_brightness = aty_bl_get_brightness,
.update_status = aty_bl_update_status,
- .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
static void aty_bl_init(struct atyfb_par *par)
snprintf(name, sizeof(name), "atybl%d", info->node);
- bd = backlight_device_register(name, par, &aty_bl_data);
+ bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
- printk("aty: Backlight registration failed\n");
+ printk(KERN_WARNING "aty: Backlight registration failed\n");
goto error;
}
- mutex_lock(&info->bl_mutex);
info->bl_dev = bd;
fb_bl_default_curve(info, 0,
0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
- mutex_unlock(&info->bl_mutex);
-
- up(&bd->sem);
- bd->props->brightness = aty_bl_data.max_brightness;
- bd->props->power = FB_BLANK_UNBLANK;
- bd->props->update_status(bd);
- down(&bd->sem);
-#ifdef CONFIG_PMAC_BACKLIGHT
- mutex_lock(&pmac_backlight_mutex);
- if (!pmac_backlight)
- pmac_backlight = bd;
- mutex_unlock(&pmac_backlight_mutex);
-#endif
+ bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd->props.brightness = bd->props.max_brightness;
+ bd->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(bd);
printk("aty: Backlight initialized (%s)\n", name);
return;
}
-static void aty_bl_exit(struct atyfb_par *par)
+static void aty_bl_exit(struct backlight_device *bd)
{
- struct fb_info *info = pci_get_drvdata(par->pdev);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
- mutex_lock(&pmac_backlight_mutex);
-#endif
-
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (pmac_backlight == info->bl_dev)
- pmac_backlight = NULL;
-#endif
-
- backlight_device_unregister(info->bl_dev);
-
- printk("aty: Backlight unloaded\n");
- }
- mutex_unlock(&info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
- mutex_unlock(&pmac_backlight_mutex);
-#endif
+ backlight_device_unregister(bd);
+ printk("aty: Backlight unloaded\n");
}
#endif /* CONFIG_FB_ATY_BACKLIGHT */
}
#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
-static int __devinit aty_init(struct fb_info *info, const char *name)
+static int __devinit aty_init(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
const char *ramname = NULL, *xtal;
int gtb_memsize, has_var = 0;
struct fb_var_screeninfo var;
- u8 pll_ref_div;
- u32 i;
-#if defined(CONFIG_PPC)
- int sense;
-#endif
init_waitqueue_head(&par->vblank.wait);
spin_lock_init(&par->int_lock);
- par->aty_cmap_regs =
- (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0);
-
-#ifdef CONFIG_PPC_PMAC
- /* The Apple iBook1 uses non-standard memory frequencies. We detect it
- * and set the frequency manually. */
- if (machine_is_compatible("PowerBook2,1")) {
- par->pll_limits.mclk = 70;
- par->pll_limits.xclk = 53;
- }
-#endif
- if (pll)
- par->pll_limits.pll_max = pll;
- if (mclk)
- par->pll_limits.mclk = mclk;
- if (xclk)
- par->pll_limits.xclk = xclk;
-
- aty_calc_mem_refresh(par, par->pll_limits.xclk);
- par->pll_per = 1000000/par->pll_limits.pll_max;
- par->mclk_per = 1000000/par->pll_limits.mclk;
- par->xclk_per = 1000000/par->pll_limits.xclk;
-
- par->ref_clk_per = 1000000000000ULL / 14318180;
- xtal = "14.31818";
-
#ifdef CONFIG_FB_ATY_GX
if (!M64_HAS(INTEGRATED)) {
u32 stat0;
case DAC_IBMRGB514:
par->dac_ops = &aty_dac_ibm514;
break;
+#ifdef CONFIG_ATARI
case DAC_ATI68860_B:
case DAC_ATI68860_C:
par->dac_ops = &aty_dac_ati68860b;
case DAC_ATT21C498:
par->dac_ops = &aty_dac_att21c498;
break;
+#endif
default:
PRINTKI("aty_init: DAC type not implemented yet!\n");
par->dac_ops = &aty_dac_unsupported;
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
par->pll_limits.mclk = 63;
+ /* Mobility + 32bit memory interface need halved XCLK. */
+ if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
+ par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
+ }
+#endif
+#ifdef CONFIG_PPC_PMAC
+ /* The Apple iBook1 uses non-standard memory frequencies. We detect it
+ * and set the frequency manually. */
+ if (machine_is_compatible("PowerBook2,1")) {
+ par->pll_limits.mclk = 70;
+ par->pll_limits.xclk = 53;
}
+#endif
+
+ /* Allow command line to override clocks. */
+ if (pll)
+ par->pll_limits.pll_max = pll;
+ if (mclk)
+ par->pll_limits.mclk = mclk;
+ if (xclk)
+ par->pll_limits.xclk = xclk;
+
+ aty_calc_mem_refresh(par, par->pll_limits.xclk);
+ par->pll_per = 1000000/par->pll_limits.pll_max;
+ par->mclk_per = 1000000/par->pll_limits.mclk;
+ par->xclk_per = 1000000/par->pll_limits.xclk;
+
+ par->ref_clk_per = 1000000000000ULL / 14318180;
+ xtal = "14.31818";
- if (M64_HAS(GTB_DSP)
- && (pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par))) {
- int diff1, diff2;
- diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
- diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
- if (diff1 < 0)
- diff1 = -diff1;
- if (diff2 < 0)
- diff2 = -diff2;
- if (diff2 < diff1) {
- par->ref_clk_per = 1000000000000ULL / 29498928;
- xtal = "29.498928";
+#ifdef CONFIG_FB_ATY_CT
+ if (M64_HAS(GTB_DSP)) {
+ u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
+
+ if (pll_ref_div) {
+ int diff1, diff2;
+ diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
+ diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
+ if (diff1 < 0)
+ diff1 = -diff1;
+ if (diff2 < 0)
+ diff2 = -diff2;
+ if (diff2 < diff1) {
+ par->ref_clk_per = 1000000000000ULL / 29498928;
+ xtal = "29.498928";
+ }
}
}
#endif /* CONFIG_FB_ATY_CT */
if(par->pll_ops->get_pll)
par->pll_ops->get_pll(info, &saved_pll);
- i = aty_ld_le32(MEM_CNTL, par);
+ par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
gtb_memsize = M64_HAS(GTB_DSP);
if (gtb_memsize)
- switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
+ switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
case MEM_SIZE_512K:
info->fix.smem_len = 0x80000;
break;
default:
info->fix.smem_len = 0x80000;
} else
- switch (i & MEM_SIZE_ALIAS) {
+ switch (par->mem_cntl & MEM_SIZE_ALIAS) {
case MEM_SIZE_512K:
info->fix.smem_len = 0x80000;
break;
if (vram) {
info->fix.smem_len = vram * 1024;
- i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
+ par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
if (info->fix.smem_len <= 0x80000)
- i |= MEM_SIZE_512K;
+ par->mem_cntl |= MEM_SIZE_512K;
else if (info->fix.smem_len <= 0x100000)
- i |= MEM_SIZE_1M;
+ par->mem_cntl |= MEM_SIZE_1M;
else if (info->fix.smem_len <= 0x200000)
- i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
+ par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
else if (info->fix.smem_len <= 0x400000)
- i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
+ par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
else if (info->fix.smem_len <= 0x600000)
- i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
+ par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
else
- i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
- aty_st_le32(MEM_CNTL, i, par);
+ par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
+ aty_st_le32(MEM_CNTL, par->mem_cntl, par);
}
/*
info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
par->pll_limits.mclk, par->pll_limits.xclk);
-#if defined(DEBUG) && defined(CONFIG_ATY_CT)
+#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
if (M64_HAS(INTEGRATED)) {
int i;
printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
#endif
if(par->pll_ops->init_pll)
par->pll_ops->init_pll(info, &par->pll);
+ if (par->pll_ops->resume_pll)
+ par->pll_ops->resume_pll(info, &par->pll);
/*
- * Last page of 8 MB (4 MB on ISA) aperture is MMIO
- * FIXME: we should use the auxiliary aperture instead so we can access
- * the full 8 MB of video RAM on 8 MB boards
+ * Last page of 8 MB (4 MB on ISA) aperture is MMIO,
+ * unless the auxiliary register aperture is used.
*/
if (!par->aux_start &&
#endif
info->fbops = &atyfb_ops;
- info->pseudo_palette = pseudo_palette;
+ info->pseudo_palette = par->pseudo_palette;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT |
| (USE_F32KHZ | TRISTATE_MEM_EN), par);
} else
#endif
- if (M64_HAS(MOBIL_BUS)) {
+ if (M64_HAS(MOBIL_BUS) && backlight) {
#ifdef CONFIG_FB_ATY_BACKLIGHT
aty_bl_init (par);
#endif
has_var = 1;
} else {
if (default_vmode == VMODE_CHOOSE) {
+ int sense;
if (M64_HAS(G3_PB_1024x768))
/* G3 PowerBook with 1024x768 LCD */
default_vmode = VMODE_1024_768_60;
goto aty_init_exit;
}
-#ifdef __sparc__
- atyfb_save_palette(par, 0);
-#endif
-
#ifdef CONFIG_FB_ATY_CT
if (!noaccel && M64_HAS(INTEGRATED))
aty_init_cursor(info);
fb_list = info;
PRINTKI("fb%d: %s frame buffer device on %s\n",
- info->node, info->fix.id, name);
+ info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
return 0;
aty_init_exit:
return -1;
}
+static void aty_resume_chip(struct fb_info *info)
+{
+ struct atyfb_par *par = info->par;
+
+ aty_st_le32(MEM_CNTL, par->mem_cntl, par);
+
+ if (par->pll_ops->resume_pll)
+ par->pll_ops->resume_pll(info, &par->pll);
+
+ if (par->aux_start)
+ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
+}
+
#ifdef CONFIG_ATARI
static int __devinit store_video_par(char *video_str, unsigned char m64_num)
{
if (par->lock_blank || par->asleep)
return 0;
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank > FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_POWERDOWN;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+#ifdef CONFIG_FB_ATY_BACKLIGHT
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank > FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
#endif
gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
+ gen_cntl &= ~0x400004c;
switch (blank) {
- case FB_BLANK_UNBLANK:
- gen_cntl &= ~0x400004c;
+ case FB_BLANK_UNBLANK:
break;
case FB_BLANK_NORMAL:
gen_cntl |= 0x4000040;
}
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_UNBLANK;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+#ifdef CONFIG_FB_ATY_BACKLIGHT
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
const struct atyfb_par *par)
{
-#ifdef CONFIG_ATARI
- out_8(&par->aty_cmap_regs->windex, regno);
- out_8(&par->aty_cmap_regs->lut, red);
- out_8(&par->aty_cmap_regs->lut, green);
- out_8(&par->aty_cmap_regs->lut, blue);
-#else
- writeb(regno, &par->aty_cmap_regs->windex);
- writeb(red, &par->aty_cmap_regs->lut);
- writeb(green, &par->aty_cmap_regs->lut);
- writeb(blue, &par->aty_cmap_regs->lut);
-#endif
+ aty_st_8(DAC_W_INDEX, regno, par);
+ aty_st_8(DAC_DATA, red, par);
+ aty_st_8(DAC_DATA, green, par);
+ aty_st_8(DAC_DATA, blue, par);
}
/*
#ifdef __sparc__
-extern void (*prom_palette) (int);
-
static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
struct fb_info *info, unsigned long addr)
{
- extern int con_is_present(void);
-
struct atyfb_par *par = info->par;
- struct pcidev_cookie *pcp;
+ struct device_node *dp;
char prop[128];
int node, len, i, j, ret;
u32 mem, chip_id;
- /* Do not attach when we have a serial console. */
- if (!con_is_present())
- return -ENXIO;
-
/*
* Map memory-mapped registers.
*/
/* nothing */ ;
j = i + 4;
- par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
+ par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC);
if (!par->mmap_map) {
PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
return -ENOMEM;
}
- memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
struct resource *rp = &pdev->resource[i];
node = 0;
}
- pcp = pdev->sysdata;
- if (node == pcp->prom_node->node) {
+ dp = pci_device_to_OF_node(pdev);
+ if (node == dp->node) {
struct fb_var_screeninfo *var = &default_var;
unsigned int N, P, Q, M, T, R;
u32 v_total, h_total;
#ifdef __i386__
#ifdef CONFIG_FB_ATY_GENERIC_LCD
-static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
+static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
{
u32 driv_inf_tab, sig;
u16 lcd_ofs;
atyfb_setup_generic_fail:
iounmap(par->ati_regbase);
par->ati_regbase = NULL;
+ if (info->screen_base) {
+ iounmap(info->screen_base);
+ info->screen_base = NULL;
+ }
return ret;
}
pci_set_drvdata(pdev, info);
/* Init chip & register framebuffer */
- if (aty_init(info, "PCI"))
+ if (aty_init(info))
goto err_release_io;
#ifdef __sparc__
- if (!prom_palette)
- prom_palette = atyfb_palette;
-
/*
* Add /dev/fb mmap values.
*/
#ifdef CONFIG_ATARI
-static int __devinit atyfb_atari_probe(void)
+static int __init atyfb_atari_probe(void)
{
struct atyfb_par *par;
struct fb_info *info;
int m64_num;
u32 clock_r;
+ int num_found = 0;
for (m64_num = 0; m64_num < mach64_count; m64_num++) {
if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
break;
}
- if (aty_init(info, "ISA bus")) {
+ /* Fake pci_id for correct_chipset() */
+ switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
+ case 0x00d7:
+ par->pci_id = PCI_CHIP_MACH64GX;
+ break;
+ case 0x0057:
+ par->pci_id = PCI_CHIP_MACH64CX;
+ break;
+ default:
+ break;
+ }
+
+ if (correct_chipset(par) || aty_init(info)) {
+ iounmap(info->screen_base);
+ iounmap(par->ati_regbase);
framebuffer_release(info);
- /* This is insufficient! kernel_map has added two large chunks!! */
- return -ENXIO;
+ } else {
+ num_found++;
}
}
+
+ return num_found ? 0 : -ENXIO;
}
#endif /* CONFIG_ATARI */
+#ifdef CONFIG_PCI
+
static void __devexit atyfb_remove(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
aty_set_crtc(par, &saved_crtc);
par->pll_ops->set_pll(info, &saved_pll);
+ unregister_framebuffer(info);
+
#ifdef CONFIG_FB_ATY_BACKLIGHT
if (M64_HAS(MOBIL_BUS))
- aty_bl_exit(par);
+ aty_bl_exit(info->bl_dev);
#endif
- unregister_framebuffer(info);
-
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0);
framebuffer_release(info);
}
-#ifdef CONFIG_PCI
static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
{
#endif /* CONFIG_PCI */
#ifndef MODULE
-static int __devinit atyfb_setup(char *options)
+static int __init atyfb_setup(char *options)
{
char *this_opt;
xclk = simple_strtoul(this_opt+5, NULL, 0);
else if (!strncmp(this_opt, "comp_sync:", 10))
comp_sync = simple_strtoul(this_opt+10, NULL, 0);
+ else if (!strncmp(this_opt, "backlight:", 10))
+ backlight = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_PPC
else if (!strncmp(this_opt, "vmode:", 6)) {
unsigned int vmode =
}
#endif /* MODULE */
-static int __devinit atyfb_init(void)
+static int __init atyfb_init(void)
{
+ int err1 = 1, err2 = 1;
#ifndef MODULE
char *option = NULL;
#endif
#ifdef CONFIG_PCI
- pci_register_driver(&atyfb_driver);
+ err1 = pci_register_driver(&atyfb_driver);
#endif
#ifdef CONFIG_ATARI
- atyfb_atari_probe();
+ err2 = atyfb_atari_probe();
#endif
- return 0;
+
+ return (err1 && err2) ? -ENODEV : 0;
}
static void __exit atyfb_exit(void)