extractedLnx/linux-2.6.38/drivers/video/aty/atyfb_base.c_aty_init.c
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;
int ret;
init_waitqueue_head(&par->vblank.wait);
spin_lock_init(&par->int_lock);
#ifdef CONFIG_FB_ATY_GX
if (!M64_HAS(INTEGRATED)) {
u32 stat0;
u8 dac_type, dac_subtype, clk_type;
stat0 = aty_ld_le32(CNFG_STAT0, par);
par->bus_type = (stat0 >> 0) & 0x07;
par->ram_type = (stat0 >> 3) & 0x07;
ramname = aty_gx_ram[par->ram_type];
/* FIXME: clockchip/RAMDAC probing? */
dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
#ifdef CONFIG_ATARI
clk_type = CLK_ATI18818_1;
dac_type = (stat0 >> 9) & 0x07;
if (dac_type == 0x07)
dac_subtype = DAC_ATT20C408;
else
dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
#else
dac_type = DAC_IBMRGB514;
dac_subtype = DAC_IBMRGB514;
clk_type = CLK_IBMRGB514;
#endif
switch (dac_subtype) {
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;
break;
case DAC_ATT20C408:
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;
break;
}
switch (clk_type) {
#ifdef CONFIG_ATARI
case CLK_ATI18818_1:
par->pll_ops = &aty_pll_ati18818_1;
break;
#else
case CLK_IBMRGB514:
par->pll_ops = &aty_pll_ibm514;
break;
#endif
#if 0 /* dead code */
case CLK_STG1703:
par->pll_ops = &aty_pll_stg1703;
break;
case CLK_CH8398:
par->pll_ops = &aty_pll_ch8398;
break;
case CLK_ATT20C408:
par->pll_ops = &aty_pll_att20c408;
break;
#endif
default:
PRINTKI("aty_init: CLK type not implemented yet!");
par->pll_ops = &aty_pll_unsupported;
break;
}
}
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
if (M64_HAS(INTEGRATED)) {
par->dac_ops = &aty_dac_ct;
par->pll_ops = &aty_pll_ct;
par->bus_type = PCI;
par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
if (M64_HAS(XL_MEM))
ramname = aty_xl_ram[par->ram_type];
else
ramname = aty_ct_ram[par->ram_type];
/* 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 (of_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";
#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 */
/* save previous video mode */
aty_get_crtc(par, &par->saved_crtc);
if (par->pll_ops->get_pll)
par->pll_ops->get_pll(info, &par->saved_pll);
par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
gtb_memsize = M64_HAS(GTB_DSP);
if (gtb_memsize)
/* 0xF used instead of MEM_SIZE_ALIAS */
switch (par->mem_cntl & 0xF) {
case MEM_SIZE_512K:
info->fix.smem_len = 0x80000;
break;
case MEM_SIZE_1M:
info->fix.smem_len = 0x100000;
break;
case MEM_SIZE_2M_GTB:
info->fix.smem_len = 0x200000;
break;
case MEM_SIZE_4M_GTB:
info->fix.smem_len = 0x400000;
break;
case MEM_SIZE_6M_GTB:
info->fix.smem_len = 0x600000;
break;
case MEM_SIZE_8M_GTB:
info->fix.smem_len = 0x800000;
break;
default:
info->fix.smem_len = 0x80000;
} else
switch (par->mem_cntl & MEM_SIZE_ALIAS) {
case MEM_SIZE_512K:
info->fix.smem_len = 0x80000;
break;
case MEM_SIZE_1M:
info->fix.smem_len = 0x100000;
break;
case MEM_SIZE_2M:
info->fix.smem_len = 0x200000;
break;
case MEM_SIZE_4M:
info->fix.smem_len = 0x400000;
break;
case MEM_SIZE_6M:
info->fix.smem_len = 0x600000;
break;
case MEM_SIZE_8M:
info->fix.smem_len = 0x800000;
break;
default:
info->fix.smem_len = 0x80000;
}
if (M64_HAS(MAGIC_VRAM_SIZE)) {
if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
info->fix.smem_len += 0x400000;
}
if (vram) {
info->fix.smem_len = vram * 1024;
par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
if (info->fix.smem_len <= 0x80000)
par->mem_cntl |= MEM_SIZE_512K;
else if (info->fix.smem_len <= 0x100000)
par->mem_cntl |= MEM_SIZE_1M;
else if (info->fix.smem_len <= 0x200000)
par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
else if (info->fix.smem_len <= 0x400000)
par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
else if (info->fix.smem_len <= 0x600000)
par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
else
par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
aty_st_le32(MEM_CNTL, par->mem_cntl, par);
}
/*
* Reg Block 0 (CT-compatible block) is at mmio_start
* Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
*/
if (M64_HAS(GX)) {
info->fix.mmio_len = 0x400;
info->fix.accel = FB_ACCEL_ATI_MACH64GX;
} else if (M64_HAS(CT)) {
info->fix.mmio_len = 0x400;
info->fix.accel = FB_ACCEL_ATI_MACH64CT;
} else if (M64_HAS(VT)) {
info->fix.mmio_start -= 0x400;
info->fix.mmio_len = 0x800;
info->fix.accel = FB_ACCEL_ATI_MACH64VT;
} else {/* GT */
info->fix.mmio_start -= 0x400;
info->fix.mmio_len = 0x800;
info->fix.accel = FB_ACCEL_ATI_MACH64GT;
}
PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20),
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_FB_ATY_CT)
if (M64_HAS(INTEGRATED)) {
int i;
printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL "
"EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG "
"DSP_ON_OFF CLOCK_CNTL\n"
"debug atyfb: %08x %08x %08x "
"%08x %08x %08x "
"%08x %08x\n"
"debug atyfb: PLL",
aty_ld_le32(BUS_CNTL, par),
aty_ld_le32(DAC_CNTL, par),
aty_ld_le32(MEM_CNTL, par),
aty_ld_le32(EXT_MEM_CNTL, par),
aty_ld_le32(CRTC_GEN_CNTL, par),
aty_ld_le32(DSP_CONFIG, par),
aty_ld_le32(DSP_ON_OFF, par),
aty_ld_le32(CLOCK_CNTL, par));
for (i = 0; i < 40; i++)
printk(" %02x", aty_ld_pll_ct(i, par));
printk("\n");
}
#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,
* unless the auxiliary register aperture is used.
*/
if (!par->aux_start &&
(info->fix.smem_len == 0x800000 ||
(par->bus_type == ISA && info->fix.smem_len == 0x400000)))
info->fix.smem_len -= GUI_RESERVE;
/*
* Disable register access through the linear aperture
* if the auxiliary aperture is used so we can access
* the full 8 MB of video RAM on 8 MB boards.
*/
if (par->aux_start)
aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
BUS_APER_REG_DIS, par);
#ifdef CONFIG_MTRR
par->mtrr_aper = -1;
par->mtrr_reg = -1;
if (!nomtrr) {
/* Cover the whole resource. */
par->mtrr_aper = mtrr_add(par->res_start, par->res_size,
MTRR_TYPE_WRCOMB, 1);
if (par->mtrr_aper >= 0 && !par->aux_start) {
/* Make a hole for mmio. */
par->mtrr_reg = mtrr_add(par->res_start + 0x800000 -
GUI_RESERVE, GUI_RESERVE,
MTRR_TYPE_UNCACHABLE, 1);
if (par->mtrr_reg < 0) {
mtrr_del(par->mtrr_aper, 0, 0);
par->mtrr_aper = -1;
}
}
}
#endif
info->fbops = &atyfb_ops;
info->pseudo_palette = par->pseudo_palette;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_COPYAREA |
FBINFO_HWACCEL_YPAN;
#ifdef CONFIG_PMAC_BACKLIGHT
if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
/*
* these bits let the 101 powerbook
* wake up from sleep -- paulus
*/
aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) |
USE_F32KHZ | TRISTATE_MEM_EN, par);
} else
#endif
if (M64_HAS(MOBIL_BUS) && backlight) {
#ifdef CONFIG_FB_ATY_BACKLIGHT
aty_bl_init(par);
#endif
}
memset(&var, 0, sizeof(var));
#ifdef CONFIG_PPC
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))
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;
else if (of_machine_is_compatible("iMac"))
default_vmode = VMODE_1024_768_75;
else if (of_machine_is_compatible("PowerBook2,1"))
/* iBook with 800x600 LCD */
default_vmode = VMODE_800_600_60;
else
default_vmode = VMODE_640_480_67;
sense = read_aty_sense(par);
PRINTKI("monitor sense=%x, mode %d\n",
sense, mac_map_monitor_sense(sense));
}
if (default_vmode <= 0 || default_vmode > VMODE_MAX)
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))
has_var = 1;
}
}
#endif /* !CONFIG_PPC */
#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
if (!atyfb_get_timings_from_lcd(par, &var))
has_var = 1;
#endif
if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
has_var = 1;
if (!has_var)
var = default_var;
if (noaccel)
var.accel_flags &= ~FB_ACCELF_TEXT;
else
var.accel_flags |= FB_ACCELF_TEXT;
if (comp_sync != -1) {
if (!comp_sync)
var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
else
var.sync |= FB_SYNC_COMP_HIGH_ACT;
}
if (var.yres == var.yres_virtual) {
u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
if (var.yres_virtual < var.yres)
var.yres_virtual = var.yres;
}
ret = atyfb_check_var(&var, info);
if (ret) {
PRINTKE("can't set default video mode\n");
goto aty_init_exit;
}
#ifdef CONFIG_FB_ATY_CT
if (!noaccel && M64_HAS(INTEGRATED))
aty_init_cursor(info);
#endif /* CONFIG_FB_ATY_CT */
info->var = var;
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret < 0)
goto aty_init_exit;
ret = register_framebuffer(info);
if (ret < 0) {
fb_dealloc_cmap(&info->cmap);
goto aty_init_exit;
}
fb_list = info;
PRINTKI("fb%d: %s frame buffer device on %s\n",
info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
return 0;
aty_init_exit:
/* restore video mode */
aty_set_crtc(par, &par->saved_crtc);
par->pll_ops->set_pll(info, &par->saved_pll);
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0);
par->mtrr_reg = -1;
}
if (par->mtrr_aper >= 0) {
mtrr_del(par->mtrr_aper, 0, 0);
par->mtrr_aper = -1;
}
#endif
return ret;
}
Generated by GNU enscript 1.6.4.