📄 radeonfb.c
字号:
radeon_save_state (rinfo, &rinfo->init_state); /* init palette */ for (i=0; i<16; i++) { j = color_table[i]; rinfo->palette[i].red = default_red[j]; rinfo->palette[i].green = default_grn[j]; rinfo->palette[i].blue = default_blu[j]; } pci_set_drvdata(pdev, rinfo); rinfo->next = board_list; board_list = rinfo; /* set all the vital stuff */ radeon_set_fbinfo (rinfo); if (register_framebuffer ((struct fb_info *) rinfo) < 0) { printk ("radeonfb: could not register framebuffer\n"); iounmap ((void*)rinfo->fb_base); 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; }#ifdef CONFIG_MTRR rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys, rinfo->video_ram, MTRR_TYPE_WRCOMB, 1);#endif#ifdef CONFIG_PMAC_BACKLIGHT if (rinfo->dviDisp_type == MT_LCD) register_backlight_controller(&radeon_backlight_controller, rinfo, "ati");#endif printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type, (rinfo->video_ram/(1024*1024))); if (rinfo->hasCRTC2) { printk("radeonfb: DVI port %s monitor connected\n", GET_MON_NAME(rinfo->dviDisp_type)); printk("radeonfb: CRT port %s monitor connected\n", GET_MON_NAME(rinfo->crtDisp_type)); } else { printk("radeonfb: CRT port %s monitor connected\n", GET_MON_NAME(rinfo->crtDisp_type)); }#ifdef CONFIG_PMAC_PBOOK if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) { /* Find PM registers in config space */ rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); /* Enable dynamic PM of chip clocks */ radeon_pm_enable_dynamic_mode(rinfo); /* Register sleep callbacks */ pmu_register_sleep_notifier(&radeon_sleep_notifier); printk("radeonfb: Power Management enabled for Mobility chipsets\n"); }#endif RTRACE("radeonfb_pci_register END\n"); return 0;}static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev){ struct radeonfb_info *rinfo = pci_get_drvdata(pdev); if (!rinfo) return; /* restore original state */ radeon_write_mode (rinfo, &rinfo->init_state); #ifdef CONFIG_MTRR if (rinfo->mtrr_hdl >= 0) mtrr_del(rinfo->mtrr_hdl, 0, 0);#endif unregister_framebuffer ((struct fb_info *) rinfo); iounmap ((void*)rinfo->mmio_base); iounmap ((void*)rinfo->fb_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);}static int radeon_engine_init (struct radeonfb_info *rinfo){ unsigned long temp; /* disable 3D engine */ OUTREG(RB3D_CNTL, 0); radeon_engine_reset (); radeon_fifo_wait (1); if (rinfo->arch != RADEON_R300) OUTREG(RB2D_DSTCACHE_MODE, 0); radeon_fifo_wait (3); /* We re-read MC_FB_LOCATION from card as it can have been * modified by XFree drivers (ouch !) */ rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); radeon_fifo_wait (1);#if defined(__BIG_ENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);#else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);#endif radeon_fifo_wait (1); OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX)); temp = radeon_get_dstbpp(rinfo->depth); rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); radeon_fifo_wait (1); OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | GMC_BRUSH_SOLID_COLOR | GMC_SRC_DATATYPE_COLOR)); radeon_fifo_wait (7); /* clear line drawing regs */ OUTREG(DST_LINE_START, 0); OUTREG(DST_LINE_END, 0); /* set brush color regs */ OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); /* set source color regs */ OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); OUTREG(DP_SRC_BKGD_CLR, 0x00000000); /* default write mask */ OUTREG(DP_WRITE_MSK, 0xffffffff); radeon_engine_idle (); return 0;}static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo){ struct fb_info *info; info = &rinfo->info; strcpy (info->modename, rinfo->name); info->node = -1; info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &radeon_fb_ops; info->display_fg = NULL; strncpy (info->fontname, fontname, sizeof (info->fontname)); info->fontname[sizeof (info->fontname) - 1] = 0; info->changevar = NULL; info->switch_con = radeonfb_switch; info->updatevar = radeonfb_updatevar; info->blank = radeonfb_blank; if (radeon_init_disp (rinfo) < 0) return -1; return 0;}static int __devinit radeon_init_disp (struct radeonfb_info *rinfo){ struct fb_info *info; struct display *disp; info = &rinfo->info; disp = &rinfo->disp; disp->var = radeonfb_default_var; /* We must initialize disp before calling fb_find_mode, as the later * will cause an implicit call to radeonfb_set_var that could crash * if disp is NULL */ info->disp = disp; rinfo->currcon_display = disp;#ifndef MODULE if (mode_option) fb_find_mode (&disp->var, &rinfo->info, mode_option, NULL, 0, NULL, 8); else#endif if (!rinfo->use_default_var) fb_find_mode (&disp->var, &rinfo->info, "640x480-8@60", NULL, 0, NULL, 0); disp->var.accel_flags |= FB_ACCELF_TEXT; /* Do we need that below ? ... */ rinfo->depth = var_to_depth(&disp->var); rinfo->bpp = disp->var.bits_per_pixel; /* Apply that dawn mode ! */ radeon_do_set_var(&disp->var, -1, 0, info); return 0;}static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp){ int accel; accel = disp->var.accel_flags & FB_ACCELF_TEXT; disp->dispsw_data = NULL; disp->screen_base = (char*)rinfo->fb_base; disp->type = FB_TYPE_PACKED_PIXELS; disp->type_aux = 0; disp->ypanstep = 1; disp->ywrapstep = 0; disp->can_soft_blank = 1; disp->inverse = 0; switch (disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: disp->visual = FB_VISUAL_PSEUDOCOLOR; disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8; if (accel) disp->line_length = (disp->var.xres_virtual + 0x3f) & ~0x3f; else disp->line_length = disp->var.xres_virtual; break;#endif /* FBCON_HAS_CFB8 */#ifdef FBCON_HAS_CFB16 case 16: disp->dispsw = accel ? &fbcon_radeon16 : &fbcon_cfb16; disp->dispsw_data = &rinfo->con_cmap.cfb16; disp->visual = FB_VISUAL_DIRECTCOLOR; if (accel) disp->line_length = (disp->var.xres_virtual * 2 + 0x3f) & ~0x3f; else disp->line_length = disp->var.xres_virtual * 2; break;#endif /* FBCON_HAS_CFB16 */#ifdef FBCON_HAS_CFB24 case 24: disp->dispsw = &fbcon_cfb24; disp->dispsw_data = &rinfo->con_cmap.cfb24; disp->visual = FB_VISUAL_DIRECTCOLOR; if (accel) disp->line_length = (disp->var.xres_virtual * 3 + 0x3f) & ~0x3f; else disp->line_length = disp->var.xres_virtual * 3; break;#endif /* FBCON_HAS_CFB24 */#ifdef FBCON_HAS_CFB32 case 32: disp->dispsw = accel ? &fbcon_radeon32 : &fbcon_cfb32; disp->dispsw_data = &rinfo->con_cmap.cfb32; disp->visual = FB_VISUAL_DIRECTCOLOR; if (accel) disp->line_length = (disp->var.xres_virtual * 4 + 0x3f) & ~0x3f; else disp->line_length = disp->var.xres_virtual * 4; break; #endif /* FBCON_HAS_CFB32 */ default: printk ("radeonfb: setting fbcon_dummy renderer\n"); disp->dispsw = &fbcon_dummy; } return;} static void do_install_cmap(int con, struct fb_info *info){ struct radeonfb_info *rinfo = (struct radeonfb_info *) info; if (con != rinfo->currcon) return; if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, 1, radeon_setcolreg, info); else { int size = radeon_get_cmap_len(&fb_display[con].var); fb_set_cmap(fb_default_cmap(size), 1, radeon_setcolreg, info); }}static int radeonfb_do_maximize(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var, struct fb_var_screeninfo *v, int nom, int den){ static struct { int xres, yres; } modes[] = { {1600, 1280}, {1280, 1024}, {1024, 768}, {800, 600}, {640, 480}, {-1, -1} }; int i; /* use highest possible virtual resolution */ if (v->xres_virtual == -1 && v->yres_virtual == -1) { printk("radeonfb: using max available virtual resolution\n"); for (i=0; modes[i].xres != -1; i++) { if (modes[i].xres * nom / den * modes[i].yres < rinfo->video_ram / 2) break; } if (modes[i].xres == -1) { printk("radeonfb: could not find virtual resolution that fits into video memory!\n"); return -EINVAL; } v->xres_virtual = modes[i].xres; v->yres_virtual = modes[i].yres; printk("radeonfb: virtual resolution set to max of %dx%d\n", v->xres_virtual, v->yres_virtual); } else if (v->xres_virtual == -1) { v->xres_virtual = (rinfo->video_ram * den / (nom * v->yres_virtual * 2)) & ~15; } else if (v->yres_virtual == -1) { v->xres_virtual = (v->xres_virtual + 15) & ~15; v->yres_virtual = rinfo->video_ram * den / (nom * v->xres_virtual *2); } else { if (v->xres_virtual * nom / den * v->yres_virtual > rinfo->video_ram) { return -EINVAL; } } if (v->xres_virtual * nom / den >= 8192) { v->xres_virtual = 8192 * den / nom - 16; } if (v->xres_virtual < v->xres) return -EINVAL; if (v->yres_virtual < v->yres) return -EINVAL; return 0;} /* * fb ops */static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct radeonfb_info *rinfo = (struct radeonfb_info *) info; struct display *disp; disp = (con < 0) ? rinfo->info.disp : &fb_display[con]; memset (fix, 0, sizeof (struct fb_fix_screeninfo)); sprintf (fix->id, "ATI Radeon %s", rinfo->name); fix->smem_start = rinfo->fb_base_phys; fix->smem_len = rinfo->video_ram; fix->type = disp->type; fix->type_aux = disp->type_aux; fix->visual = disp->visual; fix->xpanstep = 8; fix->ypanstep = 1; fix->ywrapstep = 0; fix->line_length = disp->line_length; fix->mmio_start = rinfo->mmio_base_phys; fix->mmio_len = RADEON_REGSIZE; if (noaccel) fix->accel = FB_ACCEL_NONE; else fix->accel = FB_ACCEL_ATI_RADEON; return 0;}static int radeonfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct radeonfb_info *rinfo = (struct radeonfb_info *) info; *var = (con < 0) ? rinfo->disp.var : fb_display[con].var; return 0;}static int radeon_do_set_var (struct fb_var_screeninfo *var, int con, int real, struct fb_info *info){ struct radeonfb_info *rinfo = (struct radeonfb_info *) info; struct display *disp; struct fb_var_screeninfo v; int nom, den, accel; unsigned chgvar = 1; disp = (con < 0) ? rinfo->info.disp : &fb_display[con]; accel = (noaccel == 0) && ((var->accel_flags & FB_ACCELF_TEXT) != 0); if (con >= 0) { chgvar = ((disp->var.xres != var->xres) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -