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

📄 atyfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    else        par->accel_flags = 0;#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */    if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))        return -EINVAL;#endif    return 0;}static int atyfb_encode_var(struct fb_var_screeninfo *var,                            const struct atyfb_par *par,                            const struct fb_info_aty *info){    int err;    memset(var, 0, sizeof(struct fb_var_screeninfo));    if ((err = aty_crtc_to_var(&par->crtc, var)))        return err;    var->pixclock = info->pll_ops->pll_to_var(info, &par->pll);    var->height = -1;    var->width = -1;    var->accel_flags = par->accel_flags;    return 0;}static void set_off_pitch(struct atyfb_par *par,                          const struct fb_info_aty *info){    u32 xoffset = par->crtc.xoffset;    u32 yoffset = par->crtc.yoffset;    u32 vxres = par->crtc.vxres;    u32 bpp = par->crtc.bpp;    par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);    aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);}    /*     *  Open/Release the frame buffer device     */static int atyfb_open(struct fb_info *info, int user){#ifdef __sparc__    struct fb_info_aty *fb = (struct fb_info_aty *)info;    if (user) {        fb->open++;        fb->mmaped = 0;        fb->vtconsole = -1;    } else {        fb->consolecnt++;    }#endif    return(0);}struct fb_var_screeninfo default_var = {    /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */    640, 480, 640, 480, 0, 0, 8, 0,    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},    0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,    0, FB_VMODE_NONINTERLACED};static int atyfb_release(struct fb_info *info, int user){#ifdef __sparc__    struct fb_info_aty *fb = (struct fb_info_aty *)info;    if (user) {        fb->open--;        mdelay(1);        wait_for_idle(fb);        if (!fb->open) {                int was_mmaped = fb->mmaped;                fb->mmaped = 0;                if (fb->vtconsole != -1)                        vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;                fb->vtconsole = -1;                if (was_mmaped) {                        struct fb_var_screeninfo var;                        /* Now reset the default display config, we have no                         * idea what the program(s) which mmap'd the chip did                         * to the configuration, nor whether it restored it                         * correctly.                         */                        var = default_var;                        if (noaccel)                                var.accel_flags &= ~FB_ACCELF_TEXT;                        else                                var.accel_flags |= FB_ACCELF_TEXT;                        if (var.yres == var.yres_virtual) {                                u32 vram = (fb->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;                        }                        atyfb_set_var(&var, -1, &fb->fb_info);                }        }    } else {        fb->consolecnt--;    }#endif    return(0);}static int encode_fix(struct fb_fix_screeninfo *fix,                      const struct atyfb_par *par,                      const struct fb_info_aty *info){    memset(fix, 0, sizeof(struct fb_fix_screeninfo));    strcpy(fix->id, atyfb_name);    fix->smem_start = info->frame_buffer_phys;    fix->smem_len = (u32)info->total_vram;    /*     *  Reg Block 0 (CT-compatible block) is at ati_regbase_phys     *  Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400     */    if (M64_HAS(GX)) {        fix->mmio_start = info->ati_regbase_phys;        fix->mmio_len = 0x400;        fix->accel = FB_ACCEL_ATI_MACH64GX;    } else if (M64_HAS(CT)) {        fix->mmio_start = info->ati_regbase_phys;        fix->mmio_len = 0x400;        fix->accel = FB_ACCEL_ATI_MACH64CT;    } else if (M64_HAS(VT)) {        fix->mmio_start = info->ati_regbase_phys-0x400;        fix->mmio_len = 0x800;        fix->accel = FB_ACCEL_ATI_MACH64VT;    } else /* if (M64_HAS(GT)) */ {        fix->mmio_start = info->ati_regbase_phys-0x400;        fix->mmio_len = 0x800;        fix->accel = FB_ACCEL_ATI_MACH64GT;    }    fix->type = FB_TYPE_PACKED_PIXELS;    fix->type_aux = 0;    fix->line_length = par->crtc.vxres*par->crtc.bpp/8;    fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR                                     : FB_VISUAL_DIRECTCOLOR;    fix->ywrapstep = 0;    fix->xpanstep = 8;    fix->ypanstep = 1;    return 0;}    /*     *  Get the Fixed Part of the Display     */static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,                         struct fb_info *fb){    const struct fb_info_aty *info = (struct fb_info_aty *)fb;    struct atyfb_par par;    if (con == -1)        par = info->default_par;    else        /* The monitors_enabled information is not important for           the calculation of the information in par that encode_fix           needs, so we pass a 0. */        atyfb_decode_var(&fb_display[con].var, &par, info, 0);    encode_fix(fix, &par, info);    return 0;}    /*     *  Get the User Defined Part of the Display     */static int atyfb_get_var(struct fb_var_screeninfo *var, int con,                         struct fb_info *fb){    const struct fb_info_aty *info = (struct fb_info_aty *)fb;    if (con == -1)        atyfb_encode_var(var, &info->default_par, info);    else        *var = fb_display[con].var;    return 0;}static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,                             int bpp, int accel){            switch (bpp) {#ifdef FBCON_HAS_CFB8                case 8:                    info->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;                    disp->dispsw = &info->dispsw;                    break;#endif#ifdef FBCON_HAS_CFB16                case 16:                    info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;                    disp->dispsw = &info->dispsw;                    disp->dispsw_data = info->fbcon_cmap.cfb16;                    break;#endif#ifdef FBCON_HAS_CFB24                case 24:                    info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;                    disp->dispsw = &info->dispsw;                    disp->dispsw_data = info->fbcon_cmap.cfb24;                    break;#endif#ifdef FBCON_HAS_CFB32                case 32:                    info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;                    disp->dispsw = &info->dispsw;                    disp->dispsw_data = info->fbcon_cmap.cfb32;                    break;#endif                default:                    disp->dispsw = &fbcon_dummy;            }#ifdef CONFIG_FB_ATY_CT            if (info->cursor) {                info->dispsw.cursor = atyfb_cursor;                info->dispsw.set_font = atyfb_set_font;            }#endif /* CONFIG_FB_ATY_CT */}    /*     * In the display mode set code we need to make desisions depending on     * wether the LCD or CRT monitor is enabled.     * This is going to give problems in the unlikely case that someone     * for example turns on the LCD monitor just after we tested what     * monitors are enabled. Since the consequences are very serious     * (the graphic card crashes and sends the wrong signals to the lcd     *  monitor which gets brighter and brighter; to prevent it from     * damage the computer must be switched off as soon as possible)     * we need to prevent this.     *     * As far as I know there is no way to prevent people switching on the     * LCD monitor while we are programming the video card. So the best way     * to do it, is detect what monitors are enabled before programming the     * video chip. After programming the video chip, we write this information     * back to the video chip, switching the LCD off again if someone enabled     * it. But isn't the card already crashed before we have the chance to     * turn the display back off? I don't think so because the CRTC is disabled     * while we program it.     */#ifdef CONFIG_FB_ATY_GENERIC_LCDstatic u32 atyfb_monitors_enabled(struct fb_info_aty *info) {     if (info->lcd_table != 0) {         return aty_ld_lcd(LCD_GEN_CTRL, info) & 3;     };     return 0;};#else#define atyfb_monitors_enabled(info) 0#endif    /*     *  Set the User Defined Part of the Display     */static int atyfb_set_var(struct fb_var_screeninfo *var, int con,                         struct fb_info *fb){    struct fb_info_aty *info = (struct fb_info_aty *)fb;    struct atyfb_par par;    struct display *display;    int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;    int activate = var->activate;    u32 monitors_enabled;    if (con >= 0)        display = &fb_display[con];    else        display = fb->disp;     /* used during initialization */    monitors_enabled = atyfb_monitors_enabled(info);    /*     * We have to be very carefull with encode_var for LCD_panels. Fbdev     * applications do not know about LCD monitors. We have to make them     * think they are using a CRT. That means that alltough the video     * chip is programmed for the resolution of the LCD monitor (say 800x600),     * the applications expect the mode they asked for, say 640x480     *     * So when a program asks for 640x480, atyfb_decode_var sets the crtc     * registers for 800x600. Then atyfb_encode_var calculates the crtc     * registers back into the var variable, but now the var variable     * will contain wrong values for 800x600! Result: wrong information is     * returned to the program!     *     * To counter this, we call atyfb_decode_var first like if there is no     * lcd monitor switched on. Then we call atyfb_decode_var. Now     * the correct information is returned to the program, but the values     * for the crtc registers are not suited for the LCD monitor. We call     * atyfb_decode_var again to calculate the registers again, this time     * with the right monitors_enabled.     */    if ((err = atyfb_decode_var(var, &par, info, CRT_ON)))        return err;    atyfb_encode_var(var, &par, (struct fb_info_aty *)info);#ifdef CONFIG_FB_ATY_GENERIC_LCD    if ((err = atyfb_decode_var(var, &par, info, monitors_enabled)))        return err;#endif    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {        oldxres = display->var.xres;        oldyres = display->var.yres;        oldvxres = display->var.xres_virtual;        oldvyres = display->var.yres_virtual;        oldbpp = display->var.bits_per_pixel;        oldaccel = display->var.accel_flags;        display->var = *var;        accel = var->accel_flags & FB_ACCELF_TEXT;        if (oldxres != var->xres || oldyres != var->yres ||            oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||            oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {            struct fb_fix_screeninfo fix;            encode_fix(&fix, &par, info);            display->screen_base = (char *)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;            if (accel)                display->scrollmode = (info->bus_type == PCI) ? SCROLL_YNOMOVE : 0;            else                display->scrollmode = SCROLL_YREDRAW;            if (info->fb_info.changevar)                (*info->fb_info.changevar)(con);

⌨️ 快捷键说明

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