📄 atyfb_base.c
字号:
pll = aty_chips[j].pll; mclk = aty_chips[j].mclk; info->features = aty_chips[j].features; goto found; } printk("atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev); return 0;found: printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, type, rev);#ifdef CONFIG_FB_ATY_GX if (!M64_HAS(INTEGRATED)) { u32 stat0; u8 dac_type, dac_subtype, clk_type; stat0 = aty_ld_le32(CONFIG_STAT0, info); info->bus_type = (stat0 >> 0) & 0x07; info->ram_type = (stat0 >> 3) & 0x07; ramname = aty_gx_ram[info->ram_type]; /* FIXME: clockchip/RAMDAC probing? */ dac_type = (aty_ld_le32(DAC_CNTL, info) >> 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, info) & 0xF0) | dac_type;#else dac_type = DAC_IBMRGB514; dac_subtype = DAC_IBMRGB514; clk_type = CLK_IBMRGB514;#endif switch (dac_subtype) { case DAC_IBMRGB514: info->dac_ops = &aty_dac_ibm514; break; case DAC_ATI68860_B: case DAC_ATI68860_C: info->dac_ops = &aty_dac_ati68860b; break; case DAC_ATT20C408: case DAC_ATT21C498: info->dac_ops = &aty_dac_att21c498; break; default: printk(" atyfb_set_par: DAC type not implemented yet!\n"); info->dac_ops = &aty_dac_unsupported; break; } switch (clk_type) { case CLK_ATI18818_1: info->pll_ops = &aty_pll_ati18818_1; break; case CLK_STG1703: info->pll_ops = &aty_pll_stg1703; break; case CLK_CH8398: info->pll_ops = &aty_pll_ch8398; break; case CLK_ATT20C408: info->pll_ops = &aty_pll_att20c408; break; case CLK_IBMRGB514: info->pll_ops = &aty_pll_ibm514; break; default: printk(" atyfb_set_par: CLK type not implemented yet!"); info->pll_ops = &aty_pll_unsupported; break; } }#endif /* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CT if (M64_HAS(INTEGRATED)) { info->bus_type = PCI; info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07); ramname = aty_ct_ram[info->ram_type]; info->dac_ops = &aty_dac_ct; info->pll_ops = &aty_pll_ct; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ if (mclk == 67 && info->ram_type < SDRAM) mclk = 63; }#endif /* CONFIG_FB_ATY_CT */ info->ref_clk_per = 1000000000000ULL/14318180; xtal = "14.31818"; if (M64_HAS(GTB_DSP) && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) { int diff1, diff2; diff1 = 510*14/pll_ref_div-pll; diff2 = 510*29/pll_ref_div-pll; if (diff1 < 0) diff1 = -diff1; if (diff2 < 0) diff2 = -diff2; if (diff2 < diff1) { info->ref_clk_per = 1000000000000ULL/29498928; xtal = "29.498928"; } } i = aty_ld_le32(MEM_CNTL, info); gtb_memsize = M64_HAS(GTB_DSP); if (gtb_memsize) switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ case MEM_SIZE_512K: info->total_vram = 0x80000; break; case MEM_SIZE_1M: info->total_vram = 0x100000; break; case MEM_SIZE_2M_GTB: info->total_vram = 0x200000; break; case MEM_SIZE_4M_GTB: info->total_vram = 0x400000; break; case MEM_SIZE_6M_GTB: info->total_vram = 0x600000; break; case MEM_SIZE_8M_GTB: info->total_vram = 0x800000; break; default: info->total_vram = 0x80000; } else switch (i & MEM_SIZE_ALIAS) { case MEM_SIZE_512K: info->total_vram = 0x80000; break; case MEM_SIZE_1M: info->total_vram = 0x100000; break; case MEM_SIZE_2M: info->total_vram = 0x200000; break; case MEM_SIZE_4M: info->total_vram = 0x400000; break; case MEM_SIZE_6M: info->total_vram = 0x600000; break; case MEM_SIZE_8M: info->total_vram = 0x800000; break; default: info->total_vram = 0x80000; } if (M64_HAS(MAGIC_VRAM_SIZE)) { if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000) info->total_vram += 0x400000; } if (default_vram) { info->total_vram = default_vram*1024; i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); if (info->total_vram <= 0x80000) i |= MEM_SIZE_512K; else if (info->total_vram <= 0x100000) i |= MEM_SIZE_1M; else if (info->total_vram <= 0x200000) i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; else if (info->total_vram <= 0x400000) i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; else if (info->total_vram <= 0x600000) i |= 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, info); } if (default_pll) pll = default_pll; if (default_mclk) mclk = default_mclk; printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n", info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20), info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk); if (mclk < 44) info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */ else if (mclk < 50) info->mem_refresh_rate = 1; /* 001 = 44 Mhz - 49 Mhz */ else if (mclk < 55) info->mem_refresh_rate = 2; /* 010 = 50 Mhz - 54 Mhz */ else if (mclk < 66) info->mem_refresh_rate = 3; /* 011 = 55 Mhz - 65 Mhz */ else if (mclk < 75) info->mem_refresh_rate = 4; /* 100 = 66 Mhz - 74 Mhz */ else if (mclk < 80) info->mem_refresh_rate = 5; /* 101 = 75 Mhz - 79 Mhz */ else if (mclk < 100) info->mem_refresh_rate = 6; /* 110 = 80 Mhz - 100 Mhz */ else info->mem_refresh_rate = 7; /* 111 = 100 Mhz and above */ info->pll_per = 1000000/pll; info->mclk_per = 1000000/mclk;#ifdef DEBUG if (M64_HAS(INTEGRATED)) { int i; printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL " "DSP_CONFIG DSP_ON_OFF\n" "%08x %08x %08x %08x %08x %08x %08x\n" "PLL", aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info), aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info), aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info), aty_ld_le32(DSP_ON_OFF, info)); for (i = 0; i < 16; i++) printk(" %02x", aty_ld_pll(i, info)); printk("\n"); }#endif /* * 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 */ if (info->total_vram == 0x800000 || (info->bus_type == ISA && info->total_vram == 0x400000)) info->total_vram -= GUI_RESERVE; /* Clear the video memory */ fb_memset((void *)info->frame_buffer, 0, info->total_vram); disp = &info->disp; strcpy(info->fb_info.modename, atyfb_name); info->fb_info.node = -1; info->fb_info.fbops = &atyfb_ops; info->fb_info.disp = disp; strcpy(info->fb_info.fontname, fontname); info->fb_info.changevar = NULL; info->fb_info.switch_con = &atyfbcon_switch; info->fb_info.updatevar = &atyfbcon_updatevar; info->fb_info.blank = &atyfbcon_blank; info->fb_info.flags = FBINFO_FLAG_DEFAULT;#ifdef CONFIG_PMAC_BACKLIGHT if (M64_HAS(G3_PB_1_1) && 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, info) | (USE_F32KHZ | TRISTATE_MEM_EN), info); } if (M64_HAS(MOBIL_BUS)) register_backlight_controller(&aty_backlight_controller, info, "ati");#endif /* CONFIG_PMAC_BACKLIGHT */#ifdef MODULE var = default_var;#else /* !MODULE */ memset(&var, 0, sizeof(var));#ifdef CONFIG_PPC if (_machine == _MACH_Pmac) { /* * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it * applies to all Mac video cards */ if (mode_option) { if (!mac_find_mode(&var, &info->fb_info, mode_option, 8)) var = default_var; } else { if (default_vmode == VMODE_CHOOSE) { if (M64_HAS(G3_PB_1024x768)) /* G3 PowerBook with 1024x768 LCD */ default_vmode = VMODE_1024_768_60; else if (machine_is_compatible("iMac")) default_vmode = VMODE_1024_768_75; else if (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(info); printk(KERN_INFO "atyfb: 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;#ifdef CONFIG_NVRAM if (default_cmode == CMODE_NVRAM) default_cmode = nvram_read_byte(NV_CMODE);#endif if (default_cmode < CMODE_8 || default_cmode > CMODE_32) default_cmode = CMODE_8; if (mac_vmode_to_var(default_vmode, default_cmode, &var)) var = default_var; } } else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8)) var = default_var;#else /* !CONFIG_PPC */#ifdef __sparc__ if (mode_option) { if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8)) var = default_var; } else var = default_var;#else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8)) var = default_var;#endif /* !__sparc__ */#endif /* !CONFIG_PPC */#endif /* !MODULE */ if (noaccel) var.accel_flags &= ~FB_ACCELF_TEXT; else var.accel_flags |= FB_ACCELF_TEXT; if (var.yres == var.yres_virtual) { u32 vram = (info->total_vram - (PAGE_SIZE << 2)); var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual; if (var.yres_virtual < var.yres) var.yres_virtual = var.yres; } if (atyfb_decode_var(&var, &info->default_par, info)) { printk("atyfb: can't set default video mode\n"); return 0; }#ifdef __sparc__ atyfb_save_palette(&info->fb_info, 0);#endif for (j = 0; j < 16; j++) { k = color_table[j]; info->palette[j].red = default_red[k]; info->palette[j].green = default_grn[k]; info->palette[j].blue = default_blu[k]; }#ifdef CONFIG_FB_ATY_CT if (curblink && M64_HAS(INTEGRATED)) { info->cursor = aty_init_cursor(info); if (info->cursor) { info->dispsw.cursor = atyfb_cursor; info->dispsw.set_font = atyfb_set_font; } }#endif /* CONFIG_FB_ATY_CT */ atyfb_set_var(&var, -1, &info->fb_info); if (register_framebuffer(&info->fb_info) < 0) return 0; info->next = fb_list; fb_list = info; printk("fb%d: %s frame buffer device on %s\n", GET_FB_IDX(info->fb_info.node), atyfb_name, name); return 1;}int __init atyfb_init(void){#if defined(CONFIG_PCI) struct pci_dev *pdev = NULL; struct fb_info_aty *info; unsigned long addr, res_start, res_size; int i;#ifdef __sparc__ extern void (*prom_palette) (int); extern int con_is_present(void); struct pcidev_cookie *pcp; char prop[128]; int node, len, j; u32 mem, chip_id; /* Do not attach when we have a serial console. */ if (!con_is_present()) return -ENXIO;#else u16 tmp; int aux_app; unsigned long raddr;#endif while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) { if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { struct resource *rp;#ifndef __sparc__ struct resource *rrp;#endif for (i = sizeof(aty_chips)/sizeof(*aty_chips)-1; i >= 0; i--) if (pdev->device == aty_chips[i].pci_id) break; if (i < 0) continue; info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC); if (!info) { printk("atyfb_init: can't alloc fb_info_aty\n"); return -ENXIO; } memset(info, 0, sizeof(struct fb_info_aty)); rp = &pdev->resource[0]; if (rp->flags & IORESOURCE_IO) rp = &pdev->resource[1]; addr = rp->start; if (!addr) continue; res_start = rp->start; res_size = rp->end-rp->start+1; if (!request_mem_region(res_start, res_size, "atyfb")) continue;#ifdef __sparc__ /* * Map memory-mapped registers. */ info->ati_regbase = addr + 0x7ffc00UL; info->ati_regbase_phys = addr + 0x7ffc00UL; /* * Map in big-endian aperture. */ info->frame_buffer = (unsigned long) addr + 0x800000UL; info->frame_buffer_phys = addr + 0x800000UL; /* * Figure mmap addresses from PCI config space. * Split Framebuffer in big- and little-endian halfs. */ for (i = 0; i < 6 && pdev->resource[i].start; i++) /* nothing */; j = i + 4; info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC); if (!info->mmap_map) { printk("atyfb_init: can't alloc mmap_map\n"); kfree(info); release_mem_region(res_start, res_size); return -ENXIO; } memset(info->mmap_map, 0, j * sizeof(*info->mmap_map)); for (i =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -