📄 radeonfb.c
字号:
{ u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; radeon_engine_flush (rinfo); clock_cntl_index = INREG(CLOCK_CNTL_INDEX); mclk_cntl = INPLL(MCLK_CNTL); OUTPLL(MCLK_CNTL, (mclk_cntl | FORCEON_MCLKA | FORCEON_MCLKB | FORCEON_YCLKA | FORCEON_YCLKB | FORCEON_MC | FORCEON_AIC)); rbbm_soft_reset = INREG(RBBM_SOFT_RESET); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset | SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE | SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB | SOFT_RESET_HDP); INREG(RBBM_SOFT_RESET); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32) ~(SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE | SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB | SOFT_RESET_HDP)); INREG(RBBM_SOFT_RESET); OUTPLL(MCLK_CNTL, mclk_cntl); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); return;}#define radeon_engine_reset() _radeon_engine_reset(rinfo)static __inline__ u8 radeon_get_post_div_bitval(int post_div){ switch (post_div) { case 1: return 0x00; case 2: return 0x01; case 3: return 0x04; case 4: return 0x02; case 6: return 0x06; case 8: return 0x03; case 12: return 0x07; default: return 0x02; }}static __inline__ int round_div(int num, int den){ return (num + (den / 2)) / den;}static __inline__ int min_bits_req(int val){ int bits_req = 0; if (val == 0) bits_req = 1; while (val) { val >>= 1; bits_req++; } return (bits_req);}static __inline__ int _max(int val1, int val2){ if (val1 >= val2) return val1; else return val2;} /* * globals */ static char fontname[40] __initdata;static char *mode_option __initdata;static char noaccel __initdata = 0;static int panel_yres __initdata = 0;static char force_dfp __initdata = 0;static struct radeonfb_info *board_list = NULL;#ifdef FBCON_HAS_CFB8static struct display_switch fbcon_radeon8;#endif/* * prototypes */static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info);static int radeonfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info);static int radeonfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info);static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con, struct fb_info *info);static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, int con, struct fb_info *info);static int radeonfb_switch (int con, struct fb_info *info);static int radeonfb_updatevar (int con, struct fb_info *info);static void radeonfb_blank (int blank, struct fb_info *info);static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info);static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info);static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);static void radeon_save_state (struct radeonfb_info *rinfo, struct radeon_regs *save);static void radeon_engine_init (struct radeonfb_info *rinfo);static void radeon_load_video_mode (struct radeonfb_info *rinfo, struct fb_var_screeninfo *mode);static void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode);static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);static int radeon_init_disp_var (struct radeonfb_info *rinfo);static int radeonfb_pci_register (struct pci_dev *pdev, const struct pci_device_id *ent);static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);static char *radeon_find_rom(struct radeonfb_info *rinfo);static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);static void radeon_get_moninfo (struct radeonfb_info *rinfo);static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);static void radeon_get_EDID(struct radeonfb_info *rinfo);static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);static void radeon_update_default_var(struct radeonfb_info *rinfo);#ifdef CONFIG_ALL_PPCstatic int radeon_read_OF (struct radeonfb_info *rinfo);static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);#ifdef CONFIG_PMAC_PBOOKint radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);static struct pmu_sleep_notifier radeon_sleep_notifier = { radeon_sleep_notify, SLEEP_LEVEL_VIDEO,};static int radeon_set_backlight_enable(int on, int level, void *data);static int radeon_set_backlight_level(int level, void *data);static struct backlight_controller radeon_backlight_controller = { radeon_set_backlight_enable, radeon_set_backlight_level};#endif /* CONFIG_PMAC_PBOOK */#endif /* CONFIG_ALL_PPC */static struct fb_ops radeon_fb_ops = { fb_get_fix: radeonfb_get_fix, fb_get_var: radeonfb_get_var, fb_set_var: radeonfb_set_var, fb_get_cmap: radeonfb_get_cmap, fb_set_cmap: radeonfb_set_cmap, fb_pan_display: radeonfb_pan_display, fb_ioctl: radeonfb_ioctl,};static struct pci_driver radeonfb_driver = { name: "radeonfb", id_table: radeonfb_pci_table, probe: radeonfb_pci_register, remove: __devexit_p(radeonfb_pci_unregister),};int __init radeonfb_init (void){ return pci_module_init (&radeonfb_driver);}void __exit radeonfb_exit (void){ pci_unregister_driver (&radeonfb_driver);}int __init radeonfb_setup (char *options){ char *this_opt; if (!options || !*options) return 0; while ((this_opt = strsep (&options, ",")) != NULL) { if (!*this_opt) continue; if (!strncmp (this_opt, "font:", 5)) { char *p; int i; p = this_opt + 5; for (i=0; i<sizeof (fontname) - 1; i++) if (!*p || *p == ' ' || *p == ',') break; memcpy(fontname, this_opt + 5, i); } else if (!strncmp(this_opt, "noaccel", 7)) { noaccel = 1; } else if (!strncmp(this_opt, "dfp", 3)) { force_dfp = 1; } else if (!strncmp(this_opt, "panel_yres:", 11)) { panel_yres = simple_strtoul((this_opt+11), NULL, 0); } else mode_option = this_opt; } return 0;}#ifdef MODULEmodule_init(radeonfb_init);module_exit(radeonfb_exit);#endifMODULE_AUTHOR("Ani Joshi");MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");MODULE_LICENSE("GPL");static int radeonfb_pci_register (struct pci_dev *pdev, const struct pci_device_id *ent){ struct radeonfb_info *rinfo; u32 tmp; int i, j; RTRACE("radeonfb_pci_register BEGIN\n"); rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL); if (!rinfo) { printk ("radeonfb: could not allocate memory\n"); return -ENODEV; } memset (rinfo, 0, sizeof (struct radeonfb_info)); rinfo->pdev = pdev; /* enable device */ { int err; if ((err = pci_enable_device(pdev))) { printk("radeonfb: cannot enable device\n"); kfree (rinfo); return -ENODEV; } } /* set base addrs */ rinfo->fb_base_phys = pci_resource_start (pdev, 0); rinfo->mmio_base_phys = pci_resource_start (pdev, 2); /* request the mem regions */ if (!request_mem_region (rinfo->fb_base_phys, pci_resource_len(pdev, 0), "radeonfb")) { printk ("radeonfb: cannot reserve FB region\n"); kfree (rinfo); return -ENODEV; } if (!request_mem_region (rinfo->mmio_base_phys, pci_resource_len(pdev, 2), "radeonfb")) { printk ("radeonfb: cannot reserve MMIO region\n"); release_mem_region (rinfo->fb_base_phys, pci_resource_len(pdev, 0)); kfree (rinfo); return -ENODEV; } /* map the regions */ rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE); if (!rinfo->mmio_base) { printk ("radeonfb: cannot map MMIO\n"); release_mem_region (rinfo->mmio_base_phys, pci_resource_len(pdev, 2)); release_mem_region (rinfo->fb_base_phys, pci_resource_len(pdev, 0)); kfree (rinfo); return -ENODEV; } rinfo->chipset = pdev->device; /* chipset */ switch (pdev->device) { case PCI_DEVICE_ID_RADEON_QD: strcpy(rinfo->name, "Radeon QD "); break; case PCI_DEVICE_ID_RADEON_QE: strcpy(rinfo->name, "Radeon QE "); break; case PCI_DEVICE_ID_RADEON_QF: strcpy(rinfo->name, "Radeon QF "); break; case PCI_DEVICE_ID_RADEON_QG: strcpy(rinfo->name, "Radeon QG "); break; case PCI_DEVICE_ID_RADEON_QY: strcpy(rinfo->name, "Radeon QY VE "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_QZ: strcpy(rinfo->name, "Radeon QZ VE "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_QW: strcpy(rinfo->name, "Radeon 7500 QW "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_QL: strcpy(rinfo->name, "Radeon 8500 QL "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_LW: strcpy(rinfo->name, "Radeon M7 LW "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_LY: strcpy(rinfo->name, "Radeon M6 LY "); rinfo->hasCRTC2 = 1; break; case PCI_DEVICE_ID_RADEON_LZ: strcpy(rinfo->name, "Radeon M6 LZ "); rinfo->hasCRTC2 = 1; break; default: return -ENODEV; } /* framebuffer size */ tmp = INREG(CONFIG_MEMSIZE); /* mem size is bits [28:0], mask off the rest */ rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; /* ram type */ tmp = INREG(MEM_SDRAM_MODE_REG); switch ((MEM_CFG_TYPE & tmp) >> 30) { case 0: /* SDR SGRAM (2:1) */ strcpy(rinfo->ram_type, "SDR SGRAM"); rinfo->ram.ml = 4; rinfo->ram.mb = 4; rinfo->ram.trcd = 1; rinfo->ram.trp = 2; rinfo->ram.twr = 1; rinfo->ram.cl = 2; rinfo->ram.loop_latency = 16; rinfo->ram.rloop = 16; break; case 1: /* DDR SGRAM */ strcpy(rinfo->ram_type, "DDR SGRAM"); rinfo->ram.ml = 4; rinfo->ram.mb = 4; rinfo->ram.trcd = 3; rinfo->ram.trp = 3; rinfo->ram.twr = 2; rinfo->ram.cl = 3; rinfo->ram.tr2w = 1; rinfo->ram.loop_latency = 16; rinfo->ram.rloop = 16; break; default: /* 64-bit SDR SGRAM */ strcpy(rinfo->ram_type, "SDR SGRAM 64"); rinfo->ram.ml = 4; rinfo->ram.mb = 8; rinfo->ram.trcd = 3; rinfo->ram.trp = 3; rinfo->ram.twr = 1; rinfo->ram.cl = 3; rinfo->ram.tr2w = 1; rinfo->ram.loop_latency = 17; rinfo->ram.rloop = 17; break; } rinfo->bios_seg = radeon_find_rom(rinfo); radeon_get_pllinfo(rinfo, rinfo->bios_seg); RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));#if !defined(__powerpc__) radeon_get_moninfo(rinfo);#else switch (pdev->device) { case PCI_DEVICE_ID_RADEON_LW: case PCI_DEVICE_ID_RADEON_LY: case PCI_DEVICE_ID_RADEON_LZ: rinfo->dviDisp_type = MT_LCD; break; default: radeon_get_moninfo(rinfo); break; }#endif radeon_get_EDID(rinfo); if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) || (rinfo->crtDisp_type == MT_DFP)) { if (!radeon_get_dfpinfo(rinfo)) { iounmap ((void*)rinfo->mmio_base); release_mem_region (rinfo->mmio_base_phys, pci_resource_len(pdev, 2)); release_mem_region (rinfo->fb_base_phys, pci_resource_len(pdev, 0)); kfree (rinfo); return -ENODEV; } } rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys, rinfo->video_ram); if (!rinfo->fb_base) { printk ("radeonfb: cannot map FB\n"); iounmap ((void*)rinfo->mmio_base); release_mem_region (rinfo->mmio_base_phys, pci_resource_len(pdev, 2)); release_mem_region (rinfo->fb_base_phys, pci_resource_len(pdev, 0)); kfree (rinfo); return -ENODEV; } /* XXX turn off accel for now, blts aren't working right */ noaccel = 1; /* currcon not yet configured, will be set by first switch */ rinfo->currcon = -1; /* set all the vital stuff */ radeon_set_fbinfo (rinfo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -