⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aty128fb.c

📁 linux下的VIDEO接口驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        case 0 ... 8:            var->bits_per_pixel = 8;            break;        case 9 ... 16:            var->bits_per_pixel = 16;            break;        case 17 ... 24:            var->bits_per_pixel = 24;            break;        case 25 ... 32:            var->bits_per_pixel = 32;            break;        default:            return -EINVAL;    }    if ((err = aty128_decode_var(var, &par, info)))	return err;    aty128_encode_var(var, &par, info);    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)	return 0;    oldxres = display->var.xres;    oldyres = display->var.yres;    oldvxres = display->var.xres_virtual;    oldvyres = display->var.yres_virtual;    oldbpp = display->var.bits_per_pixel;    oldgreen = display->var.green.length;    oldaccel = display->var.accel_flags;    display->var = *var;    if (oldxres != var->xres || oldyres != var->yres ||	oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||	oldgreen != var->green.length || oldbpp != var->bits_per_pixel ||	oldaccel != var->accel_flags) {	struct fb_fix_screeninfo fix;	aty128_encode_fix(&fix, &par, info);        display->screen_base = info->frame_buffer;	display->visual = fix.visual;	display->type = fix.type;	display->type_aux = fix.type_aux;	display->ypanstep = fix.ypanstep;	display->ywrapstep = fix.ywrapstep;	display->line_length = fix.line_length;	display->can_soft_blank = 1;	display->inverse = 0;	accel = var->accel_flags & FB_ACCELF_TEXT;        aty128_set_dispsw(display, info, par.crtc.bpp, accel);	if (accel)	    display->scrollmode = SCROLL_YNOMOVE;	else	    display->scrollmode = SCROLL_YREDRAW;	if (info->fb_info.changevar)	    (*info->fb_info.changevar)(con);    }    if (!info->fb_info.display_fg || info->fb_info.display_fg->vc_num == con)	aty128_set_par(&par, info);    if (oldbpp != var->bits_per_pixel || oldgreen != var->green.length) {	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))	    return err;	do_install_cmap(con, &info->fb_info);    }     return 0;}static voidaty128_set_dispsw(struct display *disp,			struct fb_info_aty128 *info, int bpp, int accel){    switch (bpp) {#ifdef FBCON_HAS_CFB8    case 8:	disp->dispsw = accel ? &fbcon_aty128_8 : &fbcon_cfb8;	break;#endif#ifdef FBCON_HAS_CFB16    case 16:	disp->dispsw = accel ? &fbcon_aty128_16 : &fbcon_cfb16;	disp->dispsw_data = info->fbcon_cmap.cfb16;	break;#endif#ifdef FBCON_HAS_CFB24    case 24:	disp->dispsw = accel ? &fbcon_aty128_24 : &fbcon_cfb24;	disp->dispsw_data = info->fbcon_cmap.cfb24;	break;#endif#ifdef FBCON_HAS_CFB32    case 32:	disp->dispsw = accel ? &fbcon_aty128_32 : &fbcon_cfb32;	disp->dispsw_data = info->fbcon_cmap.cfb32;	break;#endif    default:	disp->dispsw = &fbcon_dummy;    }}static voidaty128_encode_fix(struct fb_fix_screeninfo *fix,			struct aty128fb_par *par,			const struct fb_info_aty128 *info){    memset(fix, 0, sizeof(struct fb_fix_screeninfo));        strcpy(fix->id, aty128fb_name);    fix->smem_start = (unsigned long)info->frame_buffer_phys;    fix->mmio_start = (unsigned long)info->regbase_phys;    fix->smem_len = info->vram_size;    fix->mmio_len = 0x1fff;    fix->type        = FB_TYPE_PACKED_PIXELS;    fix->type_aux    = 0;    fix->line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;    fix->visual      = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR                                          : FB_VISUAL_DIRECTCOLOR;    fix->ywrapstep = 0;    fix->xpanstep  = 8;    fix->ypanstep  = 1;    fix->accel = FB_ACCEL_ATI_RAGE128;    return;}    /*     *  Get the Fixed Part of the Display     */static intaty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb){    const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;    struct aty128fb_par par;    if (con == -1)	par = info->default_par;    else	aty128_decode_var(&fb_display[con].var, &par, info);     aty128_encode_fix(fix, &par, info);    return 0;            }    /*     *  Pan or Wrap the Display     */static intaty128fb_pan_display(struct fb_var_screeninfo *var, int con,			   struct fb_info *fb){    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;    struct aty128fb_par *par = &info->current_par;    u32 xoffset, yoffset;    u32 offset;    u32 xres, yres;    xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;    yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;    xoffset = (var->xoffset +7) & ~7;    yoffset = var->yoffset;    if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)        return -EINVAL;    par->crtc.xoffset = xoffset;    par->crtc.yoffset = yoffset;    offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;    if (par->crtc.bpp == 24)        offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */    aty_st_le32(CRTC_OFFSET, offset);    return 0;}    /*     *  Get the Colormap     */static intaty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			struct fb_info *info){    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;    struct display *disp = (con < 0) ? info->disp : (fb_display + con);    if (con == fb->currcon) /* current console? */        return fb_get_cmap(cmap, kspc, aty128_getcolreg, info);    else if (disp->cmap.len) /* non default colormap? */        fb_copy_cmap(&disp->cmap, cmap, kspc ? 0 : 2);    else        fb_copy_cmap(fb_default_cmap((disp->var.bits_per_pixel==8) ? 256 : 32),                     cmap, kspc ? 0 : 2);    return 0;}    /*     *  Set the Colormap     */static intaty128fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			struct fb_info *info){    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;    struct display *disp = (con < 0) ? info->disp : (fb_display + con);    unsigned int cmap_len = (disp->var.bits_per_pixel==8) ? 256 : 32;    if (disp->cmap.len != cmap_len) {        int err = fb_alloc_cmap(&disp->cmap, cmap_len, 0);    	if (!disp->cmap.len) {      /* no colormap allocated? */        	int size = (disp->var.bits_per_pixel <= 8) ? 256 : 32;		if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))		    return err;	}        if (err) return err;    }    if (con == fb->currcon) /* current console? */	return fb_set_cmap(cmap, kspc, aty128_setcolreg, info);    else	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);    return 0;                }    /*     *  Helper function to store a single palette register     */static __inline__ voidaty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,	      struct fb_info_aty128 *info){    /* Note: For now, on M3, we set palette on both heads, which may     * be useless. Can someone with a M3 check this ?     *      * This code would still be useful if using the second CRTC to      * do mirroring     */    if (info->chip_gen == rage_M3) {#if 0        aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);        aty_st_8(PALETTE_INDEX, regno);        aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);#endif        aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);    }    aty_st_8(PALETTE_INDEX, regno);    aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);}static intaty128fb_rasterimg(struct fb_info *info, int start){    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;    if (fb->blitter_may_be_busy)        wait_for_idle(fb);    return 0;}int __initaty128fb_setup(char *options){    char *this_opt;    if (!options || !*options)	return 0;    while ((this_opt = strsep(&options, ",")) != 0) {	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);	    fontname[i] = 0;	} else if (!strncmp(this_opt, "noaccel", 7)) {	    noaccel = 1;#ifdef CONFIG_PMAC_PBOOK        } else if (!strncmp(this_opt, "lcd:", 4)) {            default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);        } else if (!strncmp(this_opt, "crt:", 4)) {            default_crt_on = simple_strtoul(this_opt+4, NULL, 0);#endif        }#ifdef CONFIG_MTRR        else if(!strncmp(this_opt, "nomtrr", 6)) {            mtrr = 0;        }#endif#ifdef CONFIG_PPC        /* vmode and cmode depreciated */	else if (!strncmp(this_opt, "vmode:", 6)) {            unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);            if (vmode > 0 && vmode <= VMODE_MAX)                default_vmode = vmode;        } else if (!strncmp(this_opt, "cmode:", 6)) {            unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);            switch (cmode) {	    case 0:	    case 8:		default_cmode = CMODE_8;		break;	    case 15:	    case 16:		default_cmode = CMODE_16;		break;	    case 24:	    case 32:		default_cmode = CMODE_32;		break;            }        }#endif /* CONFIG_PPC */        else            mode_option = this_opt;    }    return 0;}    /*     *  Initialisation     */static int __initaty128_init(struct fb_info_aty128 *info, const char *name){    struct fb_var_screeninfo var;    u32 dac;    int j, k;    u8 chip_rev;    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];    char *video_card = "Rage128";    if (!info->vram_size)	/* may have already been probed */	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;    /* Get the chip revision */    chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;    /* put a name with the face */    while (aci->name && info->pdev->device != aci->device) { aci++; }    video_card = (char *)aci->name;    info->chip_gen = aci->chip_gen;    printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);    if (info->vram_size % (1024 * 1024) == 0)	printk("%dM %s\n", info->vram_size / (1024*1024), info->mem->name);    else	printk("%dk %s\n", info->vram_size / 1024, info->mem->name);    /* fill in info */    strcpy(info->fb_info.modename, aty128fb_name);    info->fb_info.node  = -1;    info->fb_info.fbops = &aty128fb_ops;    info->fb_info.disp  = &info->disp;    strcpy(info->fb_info.fontname, fontname);    info->fb_info.changevar  = NULL;    info->fb_info.switch_con = &aty128fbcon_switch;    info->fb_info.updatevar  = NULL;    info->fb_info.blank = &aty128fbcon_blank;    info->fb_info.flags = FBINFO_FLAG_DEFAULT;#ifdef CONFIG_PMAC_PBOOK    info->lcd_on = default_lcd_on;    info->crt_on = default_crt_on;#endif        var = default_var;#ifdef CONFIG_PPC    if (_machine == _MACH_Pmac) {        if (mode_option) {            if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))                var = default_var;        } else {            if (default_vmode <= 0 || default_vmode > VMODE_MAX)                default_vmode = VMODE_1024_768_60;	    /* iMacs need that resolution	     * PowerMac2,1 first r128 iMacs	     * PowerMac2,2 summer 2000 iMacs	     * PowerMac4,1 january 2001 iMacs "flower power"	     */	    if (machine_is_compatible("PowerMac2,1") ||		machine_is_compatible("PowerMac2,2") ||		machine_is_compatible("PowerMac4,1"))		default_vmode = VMODE_1024_768_75;	    /* iBook SE */	    if (machine_is_compatible("PowerBook2,2"))		default_vmode = VMODE_800_600_60; 	    /* PowerBook Firewire (Pismo), iBook Dual USB */	    if (machine_is_compatible("PowerBook3,1") ||	    	machine_is_compatible("PowerBook4,1"))		default_vmode = VMODE_1024_768_60;	    /* PowerBook Titanium */	    if (machine_is_compatible("PowerBook3,2"))		default_vmode = VMODE_1152_768_60;            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#endif /* CONFIG_PPC */    {        if (fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0,                          &defaultmode, 8) == 0)            var = default_var;    }    if (noaccel)        var.accel_flags &= ~FB_ACCELF_TEXT;    else        var.accel_flags |= FB_ACCELF_TEXT;    if (aty128_decode_var(&var, &info->default_par, info)) {	printk(KERN_ERR "aty128fb: Cannot set default mode.\n");	return 0;    }    /* load up the palette with default colors */    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];    }    /* setup the DAC the way we like it */    dac = aty_ld_le32(DAC_CNTL);    dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);    dac |= DAC_MASK;    if (info->chip_gen == rage_M3)    	dac |= DAC_PALETTE2_SNOOP_EN;    aty_st_le32(DAC_CNTL, dac);    /* turn off bus mastering, just in case */    aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);    aty128fb_set_var(&var, -1, &info->fb_info);    aty128_init_engine(&info->default_par, info);    board_list = aty128_board_list_add(board_list, info);    if (register_framebuffer(&info->fb_info) < 0)	return 0;#ifdef CONFIG_PMAC_BACKLIGHT    /* Could be extended to Rage128Pro LVDS output too */    if (info->chip_gen == rage_M3)    	register_backlight_controller(&aty128_backlight_controller, info, "ati");#endif /* CONFIG_PMAC_BACKLIGHT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -