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

📄 atyfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                                ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |                                (h_sync_pol<<21);        crtc->v_tot_disp = v_total | (v_disp<<16);        crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);#ifdef CONFIG_FB_ATY_GENERIC_LCD        /* No hardware stretching please! */        crtc->h_stretching = 0;        crtc->v_stretching = 0;    } else {        /* This is horror! When we simulate, say 640x480 on an 800x600           lcd monitor, the CRTC should be programmed 800x600 values for           the non visible part, but 640x480 for the visible part.           This code has been tested on a laptop with it's 800x600 lcd           monitor and a conventional monitor both switched on.           Tested modes: 640x400, 720x400, 800x600, 320x200-doublescan,                         800x600-interlaced         */        lcd_htotal = h_disp + info->lcd_hblank_width;        lcd_hsync_start = h_disp + info->lcd_right;        lcd_vtotal = v_disp + info->lcd_vblank_width;        lcd_vsync_start = v_disp + info->lcd_lower;                crtc->h_tot_disp = (lcd_htotal) | (h_disp<<16);        crtc->h_sync_strt_wid = (lcd_hsync_start & 0xff) |                                (info->lcd_hsync_delay<<8) |                                ((lcd_hsync_start & 0x100)<<4) |                                (info->lcd_hsync_width<<16);        crtc->v_tot_disp = lcd_vtotal | (v_disp<<16);        crtc->v_sync_strt_wid = lcd_vsync_start |                                (info->lcd_vsync_width<<16);        /* To simulate the requested video mode, we use the hardware stretcher,           which zooms the image to the dimensions of the LCD screen. It has           two modes; replication and blending. Replication duplicates some           pixels, blending interpolates between pixels. We use blending.           The formula for blending is:              h_stretching=(source_with/dest_width)*4096              v_stretching=(source_lines/dest_lines)*1024         */        if (xres != info->lcd_width)            crtc->h_stretching = (xres*4096)/info->lcd_width;        else            crtc->h_stretching = 0;        if (ryres != info->lcd_height)            crtc->v_stretching = (ryres*1024)/info->lcd_height;        else            crtc->v_stretching = 0;        /* The prefered mode for the lcd is not interlaced, so disable it if           it was enabled. For doublescan there is no problem, because we can           compensate for it in the hardware stretching (we stretch half as much)         */        crtc->gen_cntl&=~CRTC_INTERLACE_EN;    };    crtc->monitors_enabled = *monitors_enabled;#endif    if (M64_HAS(MAGIC_FIFO)) {        /* Not VTB/GTB */        /* FIXME: magic FIFO values */        crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;    }    crtc->dp_pix_width = dp_pix_width;    crtc->dp_chain_mask = dp_chain_mask;    return 0;}static int aty_crtc_to_var(const struct crtc *crtc,                           struct fb_var_screeninfo *var){    u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;    u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;    u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;    u32 pix_width;    u32 double_scan, interlace;                /* input */    h_total = crtc->h_tot_disp & 0x1ff;    h_disp = (crtc->h_tot_disp>>16) & 0xff;    h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |                  ((crtc->h_sync_strt_wid>>4) & 0x100);    h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;    h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;    h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;    v_total = crtc->v_tot_disp & 0x7ff;    v_disp = (crtc->v_tot_disp>>16) & 0x7ff;    v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;    v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;    v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;    c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;    pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;    double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;    interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;                    /* convert */    xres = (h_disp+1)*8;    yres = v_disp+1;    left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;    right = (h_sync_strt-h_disp)*8+h_sync_dly;    hslen = h_sync_wid*8;    upper = v_total-v_sync_strt-v_sync_wid;    lower = v_sync_strt-v_disp;    vslen = v_sync_wid;    sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |           (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |           (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);    switch (pix_width) {#if 0        case CRTC_PIX_WIDTH_4BPP:            bpp = 4;            var->red.offset = 0;            var->red.length = 8;            var->green.offset = 0;            var->green.length = 8;            var->blue.offset = 0;            var->blue.length = 8;            var->transp.offset = 0;            var->transp.length = 0;            break;#endif        case CRTC_PIX_WIDTH_8BPP:            bpp = 8;            var->red.offset = 0;            var->red.length = 8;            var->green.offset = 0;            var->green.length = 8;            var->blue.offset = 0;            var->blue.length = 8;            var->transp.offset = 0;            var->transp.length = 0;            break;        case CRTC_PIX_WIDTH_15BPP:      /* RGB 555 */            bpp = 16;            var->red.offset = 10;            var->red.length = 5;            var->green.offset = 5;            var->green.length = 5;            var->blue.offset = 0;            var->blue.length = 5;            var->transp.offset = 0;            var->transp.length = 0;            break;#if 0        case CRTC_PIX_WIDTH_16BPP:      /* RGB 565 */            bpp = 16;            var->red.offset = 11;            var->red.length = 5;            var->green.offset = 5;            var->green.length = 6;            var->blue.offset = 0;            var->blue.length = 5;            var->transp.offset = 0;            var->transp.length = 0;            break;#endif        case CRTC_PIX_WIDTH_24BPP:      /* RGB 888 */            bpp = 24;            var->red.offset = 16;            var->red.length = 8;            var->green.offset = 8;            var->green.length = 8;            var->blue.offset = 0;            var->blue.length = 8;            var->transp.offset = 0;            var->transp.length = 0;            break;        case CRTC_PIX_WIDTH_32BPP:      /* ARGB 8888 */            bpp = 32;            var->red.offset = 16;            var->red.length = 8;            var->green.offset = 8;            var->green.length = 8;            var->blue.offset = 0;            var->blue.length = 8;            var->transp.offset = 24;            var->transp.length = 8;            break;        default:            FAIL("Invalid pixel width");    }    /* output */    var->xres = xres;    var->yres = yres;    var->xres_virtual = crtc->vxres;    var->yres_virtual = crtc->vyres;    var->bits_per_pixel = bpp;    var->xoffset = crtc->xoffset;    var->yoffset = crtc->yoffset;    var->left_margin = left;    var->right_margin = right;    var->upper_margin = upper;    var->lower_margin = lower;    var->hsync_len = hslen;    var->vsync_len = vslen;    var->sync = sync;    var->vmode = FB_VMODE_NONINTERLACED;    /* In double scan mode, the vertical parameters are doubled, so we need to       half them to get the right values.       In interlaced mode the values are already correct, so no correction is       necessary.       Code has been tested in 1024x768, 43 Hz interlaced and 640x480, 60 Hz       doublesscan.    */    if (interlace)        var->vmode = FB_VMODE_INTERLACED;    if (double_scan) {        var->vmode = FB_VMODE_DOUBLE;        var->yres>>=1;        var->upper_margin>>=1;        var->lower_margin>>=1;        var->vsync_len>>=1;    };                                        return 0;}/* ------------------------------------------------------------------------- */static void atyfb_set_par(const struct atyfb_par *par,                          struct fb_info_aty *info){    u32 i;    int accelmode;    u8 tmp;    accelmode = par->accel_flags;  /* hack */    info->current_par = *par;    if (info->blitter_may_be_busy)        wait_for_idle(info);    tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);    aty_set_crtc(info, &par->crtc);#if 0    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);                                        /* better call aty_StrobeClock ?? */    aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);#endif    aty_st_8(CLOCK_CNTL, 0, info);    aty_st_8(CLOCK_CNTL, CLOCK_STROBE | CLOCK_DIV, info);    info->dac_ops->set_dac(info, &par->pll, par->crtc.bpp, accelmode);    info->pll_ops->set_pll(info, &par->pll);    if (!M64_HAS(INTEGRATED)) {        /* Don't forget MEM_CNTL */        i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;        switch (par->crtc.bpp) {            case 8:                i |= 0x02000000;                break;            case 16:                i |= 0x03000000;                break;            case 32:                i |= 0x06000000;                break;        }        aty_st_le32(MEM_CNTL, i, info);    } else {        i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;        if (!M64_HAS(MAGIC_POSTDIV))            i |= info->mem_refresh_rate << 20;        switch (par->crtc.bpp) {            case 8:            case 24:                i |= 0x00000000;                break;            case 16:                i |= 0x04000000;                break;            case 32:                i |= 0x08000000;                break;        }        if (M64_HAS(CT_BUS)) {            aty_st_le32(DAC_CNTL, 0x87010184, info);            aty_st_le32(BUS_CNTL, 0x680000f9, info);        } else if (M64_HAS(VT_BUS)) {            aty_st_le32(DAC_CNTL, 0x87010184, info);            aty_st_le32(BUS_CNTL, 0x680000f9, info);        }  else if (M64_HAS(MOBIL_BUS)) {            aty_st_le32(DAC_CNTL, 0x80010102, info);            aty_st_le32(BUS_CNTL, 0x7b33a040, info);        } else {            /* GT */            aty_st_le32(DAC_CNTL, 0x86010102, info);            aty_st_le32(BUS_CNTL, 0x7b23a040, info);            aty_st_le32(EXT_MEM_CNTL,                        aty_ld_le32(EXT_MEM_CNTL, info) | 0x5000001, info);        }        aty_st_le32(MEM_CNTL, i, info);    }    aty_st_8(DAC_MASK, 0xff, info);    /* Initialize the graphics engine */    if (par->accel_flags & FB_ACCELF_TEXT)        aty_init_engine(par, info);#ifdef CONFIG_FB_COMPAT_XPMAC    if (!console_fb_info || console_fb_info == &info->fb_info) {        struct fb_var_screeninfo var;        int vmode, cmode;        display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;        display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;        display_info.depth = par->crtc.bpp;        display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;        atyfb_encode_var(&var, par, info);        if (mac_var_to_vmode(&var, &vmode, &cmode))            display_info.mode = 0;        else            display_info.mode = vmode;        strcpy(display_info.name, atyfb_name);        display_info.fb_address = info->frame_buffer_phys;        display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;        display_info.cmap_data_address = info->ati_regbase_phys+0xc1;        display_info.disp_reg_address = info->ati_regbase_phys;    }#endif /* CONFIG_FB_COMPAT_XPMAC */#ifdef CONFIG_BOOTX_TEXT    btext_update_display(info->frame_buffer_phys,                         (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8,                         ((par->crtc.v_tot_disp>>16) & 0x7ff)+1,                         par->crtc.bpp,                         par->crtc.vxres*par->crtc.bpp/8);#endif /* CONFIG_BOOTX_TEXT */}static int atyfb_decode_var(const struct fb_var_screeninfo *var,                            struct atyfb_par *par,                            const struct fb_info_aty *info,                            u32 monitors_enabled){    int err;    u32 pixclock,xres;    err = aty_var_to_crtc(info, var, &par->crtc, &monitors_enabled);    if (err == 0) {        /* Alert! aty_var_to_crtc can modify monitors_enabled which is           important for the pixclock decision */        pixclock = var->pixclock;        xres = 0;#ifdef CONFIG_FB_ATY_GENERIC_LCD        if ((info->lcd_table != 0) && ((monitors_enabled & LCD_ON) != 0)) {            pixclock = info->lcd_pixclock;            xres = var->xres;        };#endif        if (pixclock == 0) {            FAIL("Invalid pixclock");        } else            err = info->pll_ops->var_to_pll(info, pixclock, par->crtc.bpp, xres,	                                    &par->pll);    };    if (err != 0)        return err;    if (var->accel_flags & FB_ACCELF_TEXT)        par->accel_flags = FB_ACCELF_TEXT;

⌨️ 快捷键说明

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