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

📄 atyfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        }        if (!info->fb_info.display_fg ||            info->fb_info.display_fg->vc_num == con) {            atyfb_set_par(&par, info);            atyfb_set_dispsw(display, info, par.crtc.bpp, accel);        }        if (oldbpp != var->bits_per_pixel) {            if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))                return err;            do_install_cmap(con, &info->fb_info);        }    }    return 0;}    /*     *  Pan or Wrap the Display     *     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag     */static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,                             struct fb_info *fb){    struct fb_info_aty *info = (struct fb_info_aty *)fb;    u32 xres, yres, xoffset, yoffset;    struct atyfb_par *par = &info->current_par;    xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;    yres = ((par->crtc.v_tot_disp>>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;    set_off_pitch(par, info);    return 0;}    /*     *  Get the Colormap     */static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,                          struct fb_info *info){    if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */        return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);    else if (fb_display[con].cmap.len) /* non default colormap? */        fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);    else {        int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;        fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);    }    return 0;}    /*     *  Set the Colormap     */static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,                          struct fb_info *info){    int err;    struct display *disp;    if (con >= 0)        disp = &fb_display[con];    else        disp = info->disp;    if (!disp->cmap.len) {      /* no colormap allocated? */        int size = disp->var.bits_per_pixel == 16 ? 32 : 256;        if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))            return err;    }    if (!info->display_fg || con == info->display_fg->vc_num)                   /* current console? */        return fb_set_cmap(cmap, kspc, atyfb_setcolreg, info);    else        fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);    return 0;}static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,                       u_long arg, int con, struct fb_info *info2){#if defined(__sparc__)    struct fb_info_aty *info = (struct fb_info_aty *)info2;#endif /* __sparc__ || DEBUG */#ifdef __sparc__    struct fbtype fbtyp;    struct display *disp;    if (con >= 0)        disp = &fb_display[con];    else        disp = info2->disp;#endif    switch (cmd) {#ifdef __sparc__    case FBIOGTYPE:        fbtyp.fb_type = FBTYPE_PCI_GENERIC;        fbtyp.fb_width = info->current_par.crtc.vxres;        fbtyp.fb_height = info->current_par.crtc.vyres;        fbtyp.fb_depth = info->current_par.crtc.bpp;        fbtyp.fb_cmsize = disp->cmap.len;        fbtyp.fb_size = info->total_vram;        if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))                return -EFAULT;        break;#endif /* __sparc__ */    default:        return -EINVAL;    }    return 0;}static int atyfb_rasterimg(struct fb_info *info, int start){    struct fb_info_aty *fb = (struct fb_info_aty *)info;    if (fb->blitter_may_be_busy)        wait_for_idle(fb);    return 0;}#ifdef __sparc__static int atyfb_mmap(struct fb_info *info, struct file *file,                      struct vm_area_struct *vma){        struct fb_info_aty *fb = (struct fb_info_aty *)info;        unsigned int size, page, map_size = 0;        unsigned long map_offset = 0;        unsigned long off;        int i;        if (!fb->mmap_map)                return -ENXIO;        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))                return -EINVAL;        off = vma->vm_pgoff << PAGE_SHIFT;        size = vma->vm_end - vma->vm_start;        /* To stop the swapper from even considering these pages. */        vma->vm_flags |= (VM_SHM | VM_LOCKED);        if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||            ((off == fb->total_vram) && (size == PAGE_SIZE)))                off += 0x8000000000000000UL;        vma->vm_pgoff = off >> PAGE_SHIFT;      /* propagate off changes */        /* Each page, see which map applies */        for (page = 0; page < size; ) {                map_size = 0;                for (i = 0; fb->mmap_map[i].size; i++) {                        unsigned long start = fb->mmap_map[i].voff;                        unsigned long end = start + fb->mmap_map[i].size;                        unsigned long offset = off + page;                        if (start > offset)                                continue;                        if (offset >= end)                                continue;                        map_size = fb->mmap_map[i].size - (offset - start);                        map_offset = fb->mmap_map[i].poff + (offset - start);                        break;                }                if (!map_size) {                        page += PAGE_SIZE;                        continue;                }                if (page + map_size > size)                        map_size = size - page;                pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);                pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;                if (remap_page_range(vma->vm_start + page, map_offset,                                     map_size, vma->vm_page_prot))                        return -EAGAIN;                page += map_size;        }        if (!map_size)                return -EINVAL;        vma->vm_flags |= VM_IO;        if (!fb->mmaped) {                int lastconsole = 0;                if (info->display_fg)                        lastconsole = info->display_fg->vc_num;                fb->mmaped = 1;                if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {                        fb->vtconsole = lastconsole;                        vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;                }        }        return 0;}static struct {        u32     yoffset;        u8      r[2][256];        u8      g[2][256];        u8      b[2][256];} atyfb_save;static void atyfb_save_palette(struct fb_info *fb, int enter){        struct fb_info_aty *info = (struct fb_info_aty *)fb;        int i, tmp;        for (i = 0; i < 256; i++) {                tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;                if (M64_HAS(EXTRA_BRIGHT))                        tmp |= 0x2;                aty_st_8(DAC_CNTL, tmp, info);                aty_st_8(DAC_MASK, 0xff, info);                writeb(i, &info->aty_cmap_regs->rindex);                atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);                atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);                atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);                writeb(i, &info->aty_cmap_regs->windex);                writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);                writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);                writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);        }}static void atyfb_palette(int enter){        struct fb_info_aty *info;        struct atyfb_par *par;        struct display *d;        int i;        for (i = 0; i < MAX_NR_CONSOLES; i++) {                d = &fb_display[i];                if (d->fb_info &&                    d->fb_info->fbops == &atyfb_ops &&                    d->fb_info->display_fg &&                    d->fb_info->display_fg->vc_num == i) {                        atyfb_save_palette(d->fb_info, enter);                        info = (struct fb_info_aty *)d->fb_info;                        par = &info->current_par;                        if (enter) {                                atyfb_save.yoffset = par->crtc.yoffset;                                par->crtc.yoffset = 0;                                set_off_pitch(par, info);                        } else {                                par->crtc.yoffset = atyfb_save.yoffset;                                set_off_pitch(par, info);                        }                        break;                }        }}#endif /* __sparc__ */#ifdef CONFIG_PMAC_PBOOKstatic struct fb_info_aty* first_display = NULL;/* Power management routines. Those are used for PowerBook sleep. * * It appears that Rage LT and Rage LT Pro have different power * management registers. There's is some confusion about which * chipID is a Rage LT or LT pro :( */static int aty_power_mgmt_LT(int sleep, struct fb_info_aty *info){        unsigned int pm;        int timeout;                pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);        pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;        aty_st_le32(POWER_MANAGEMENT_LG, pm, info);        pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                timeout = 200000;        if (sleep) {                /* Sleep */                pm &= ~PWR_MGT_ON;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                udelay(10);                pm &= ~(PWR_BLON | AUTO_PWR_UP);                pm |= SUSPEND_NOW;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                udelay(10);                pm |= PWR_MGT_ON;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                do {                        pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                        udelay(10);                        if ((--timeout) == 0)                                break;                } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);        } else {                /* Wakeup */                pm &= ~PWR_MGT_ON;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                udelay(10);                pm |=  (PWR_BLON | AUTO_PWR_UP);                pm &= ~SUSPEND_NOW;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                udelay(10);                pm |= PWR_MGT_ON;                aty_st_le32(POWER_MANAGEMENT_LG, pm, info);                do {                        pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);                        udelay(10);                        if ((--timeout) == 0)                                break;                } while ((pm & PWR_MGT_STATUS_MASK) != 0);        }        mdelay(500);        return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;}static int aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info){        unsigned int pm;        int timeout;                pm = aty_ld_lcd(POWER_MANAGEMENT, info);        pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;        aty_st_lcd(POWER_MANAGEMENT, pm, info);        pm = aty_ld_lcd(POWER_MANAGEMENT, info);        timeout = 200;        if (sleep) {                /* Sleep */                pm &= ~PWR_MGT_ON;                aty_st_lcd(POWER_MANAGEMENT, pm, info);                pm = aty_ld_lcd(POWER_MANAGEMENT, info);                udelay(10);                pm &= ~(PWR_BLON | AUTO_PWR_UP);                pm |= SUSPEND_NOW

⌨️ 快捷键说明

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