📄 matroxfb_base.c
字号:
dsp = info->disp; } else { dsp = fb_display + con; } if (var->vmode & FB_VMODE_YWRAP) { return -EINVAL; } else { if (var->xoffset+dsp->var.xres > dsp->var.xres_virtual || var->yoffset+dsp->var.yres > dsp->var.yres_virtual) return -EINVAL; } if (con == ACCESS_FBINFO(currcon)) matrox_pan_var(PMINFO var); dsp->var.xoffset = var->xoffset; dsp->var.yoffset = var->yoffset; dsp->var.vmode &= ~FB_VMODE_YWRAP; return 0;}static int matroxfb_updatevar(int con, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) DBG("matroxfb_updatevar"); matrox_pan_var(PMINFO &fb_display[con].var); return 0;#undef minfo}static int matroxfb_get_final_bppShift(CPMINFO int bpp) { int bppshft2; DBG("matroxfb_get_final_bppShift") bppshft2 = bpp; if (!bppshft2) { return 8; } if (isInterleave(MINFO)) bppshft2 >>= 1; if (ACCESS_FBINFO(devflags.video64bits)) bppshft2 >>= 1; return bppshft2;}static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { int over; int rounding; DBG("matroxfb_test_and_set_rounding") switch (bpp) { case 0: return xres; case 4: rounding = 128; break; case 8: rounding = 64; /* doc says 64; 32 is OK for G400 */ break; case 16: rounding = 32; break; case 24: rounding = 64; /* doc says 64; 32 is OK for G400 */ break; default: rounding = 16; /* on G400, 16 really does not work */ if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) rounding = 32; break; } if (isInterleave(MINFO)) { rounding *= 2; } over = xres % rounding; if (over) xres += rounding-over; return xres;}static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { const int* width; int xres_new; DBG("matroxfb_pitch_adjust") if (!bpp) return xres; width = ACCESS_FBINFO(capable.vxres); if (ACCESS_FBINFO(devflags.precise_width)) { while (*width) { if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) { break; } width++; } xres_new = *width; } else { xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); } if (!xres_new) return 0; if (xres != xres_new) { printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new); } return xres_new;}static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) { DBG("matroxfb_get_cmap_len") switch (var->bits_per_pixel) {#ifdef FBCON_HAS_VGATEXT case 0: return 16; /* pseudocolor... 16 entries HW palette */#endif#ifdef FBCON_HAS_CFB4 case 4: return 16; /* pseudocolor... 16 entries HW palette */#endif#ifdef FBCON_HAS_CFB8 case 8: return 256; /* pseudocolor... 256 entries HW palette */#endif#ifdef FBCON_HAS_CFB16 case 16: return 16; /* directcolor... 16 entries SW palette */ /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB24 case 24: return 16; /* directcolor... 16 entries SW palette */ /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB32 case 32: return 16; /* directcolor... 16 entries SW palette */ /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif } return 16; /* return something reasonable... or panic()? */}static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) { struct RGBT { unsigned char bpp; struct { unsigned char offset, length; } red, green, blue, transp; signed char visual; }; static const struct RGBT table[]= {#if defined FBCON_HAS_VGATEXT { 0,{ 0,6},{0,6},{0,6},{ 0,0},MX_VISUAL_PSEUDOCOLOR},#endif#if defined FBCON_HAS_CFB4 || defined FBCON_HAS_CFB8 { 8,{ 0,8},{0,8},{0,8},{ 0,0},MX_VISUAL_PSEUDOCOLOR},#endif#if defined FBCON_HAS_CFB16 {15,{10,5},{5,5},{0,5},{15,1},MX_VISUAL_DIRECTCOLOR}, {16,{11,5},{5,6},{0,5},{ 0,0},MX_VISUAL_DIRECTCOLOR},#endif#if defined FBCON_HAS_CFB24 {24,{16,8},{8,8},{0,8},{ 0,0},MX_VISUAL_DIRECTCOLOR},#endif#if defined FBCON_HAS_CFB32 {32,{16,8},{8,8},{0,8},{24,8},MX_VISUAL_DIRECTCOLOR}#endif }; struct RGBT const *rgbt; unsigned int bpp = var->bits_per_pixel; unsigned int vramlen; unsigned int memlen; DBG("matroxfb_decode_var") switch (bpp) {#ifdef FBCON_HAS_VGATEXT case 0: if (!ACCESS_FBINFO(capable.text)) return -EINVAL; break;#endif#ifdef FBCON_HAS_CFB4 case 4: if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL; break;#endif#ifdef FBCON_HAS_CFB8 case 8: break;#endif#ifdef FBCON_HAS_CFB16 case 16: break;#endif#ifdef FBCON_HAS_CFB24 case 24: break;#endif#ifdef FBCON_HAS_CFB32 case 32: break;#endif default: return -EINVAL; } *ydstorg = 0; vramlen = ACCESS_FBINFO(video.len_usable); if (var->yres_virtual < var->yres) var->yres_virtual = var->yres; if (var->xres_virtual < var->xres) var->xres_virtual = var->xres; if (bpp) { var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, bpp); memlen = var->xres_virtual * bpp * var->yres_virtual / 8; if (memlen > vramlen) { var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp); memlen = var->xres_virtual * bpp * var->yres_virtual / 8; } /* There is hardware bug that no line can cross 4MB boundary */ /* give up for CFB24, it is impossible to easy workaround it */ /* for other try to do something */ if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) { if (bpp == 24) { /* sorry */ } else { unsigned int linelen; unsigned int m1 = linelen = var->xres_virtual * bpp / 8; unsigned int m2 = PAGE_SIZE; /* or 128 if you do not need PAGE ALIGNED address */ unsigned int max_yres; while (m1) { int t; while (m2 >= m1) m2 -= m1; t = m1; m1 = m2; m2 = t; } m2 = linelen * PAGE_SIZE / m2; *ydstorg = m2 = 0x400000 % m2; max_yres = (vramlen - m2) / linelen; if (var->yres_virtual > max_yres) var->yres_virtual = max_yres; } } } else { matrox_text_round(PMINFO var, p);#if 0/* we must limit pixclock by mclk... Millennium I: 66 MHz = 15000 Millennium II: 61 MHz = 16300 Millennium G200: 83 MHz = 12000 */ if (var->pixclock < 15000) var->pixclock = 15000; /* limit for "normal" gclk & mclk */#endif } /* YDSTLEN contains only signed 16bit value */ if (var->yres_virtual > 32767) var->yres_virtual = 32767; /* we must round yres/xres down, we already rounded y/xres_virtual up if it was possible. We should return -EINVAL, but I disagree */ if (var->yres_virtual < var->yres) var->yres = var->yres_virtual; if (var->xres_virtual < var->xres) var->xres = var->xres_virtual; if (var->xoffset + var->xres > var->xres_virtual) var->xoffset = var->xres_virtual - var->xres; if (var->yoffset + var->yres > var->yres_virtual) var->yoffset = var->yres_virtual - var->yres; if (bpp == 16 && var->green.length == 5) { bpp--; /* an artifical value - 15 */ } for (rgbt = table; rgbt->bpp < bpp; rgbt++);#define SETCLR(clr)\ var->clr.offset = rgbt->clr.offset;\ var->clr.length = rgbt->clr.length SETCLR(red); SETCLR(green); SETCLR(blue); SETCLR(transp);#undef SETCLR *visual = rgbt->visual; if (bpp > 8) dprintk("matroxfb: truecolor: " "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", var->transp.length, var->red.length, var->green.length, var->blue.length, var->transp.offset, var->red.offset, var->green.offset, var->blue.offset); *video_cmap_len = matroxfb_get_cmap_len(var); dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel, var->xres_virtual, var->yres_virtual); return 0;}static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fb_info){ struct display* p;#ifdef CONFIG_FB_MATROX_MULTIHEAD struct matrox_fb_info* minfo = list_entry(fb_info, struct matrox_fb_info, fbcon);#endif DBG("matroxfb_setcolreg") /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ if (regno >= ACCESS_FBINFO(curr.cmap_len)) return 1; ACCESS_FBINFO(palette[regno].red) = red; ACCESS_FBINFO(palette[regno].green) = green; ACCESS_FBINFO(palette[regno].blue) = blue; ACCESS_FBINFO(palette[regno].transp) = transp; p = ACCESS_FBINFO(currcon_display); if (p->var.grayscale) { /* gray = 0.30*R + 0.59*G + 0.11*B */ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; } red = CNVT_TOHW(red, p->var.red.length); green = CNVT_TOHW(green, p->var.green.length); blue = CNVT_TOHW(blue, p->var.blue.length); transp = CNVT_TOHW(transp, p->var.transp.length); switch (p->var.bits_per_pixel) {#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_VGATEXT)#ifdef FBCON_HAS_VGATEXT case 0:#endif#ifdef FBCON_HAS_CFB4 case 4:#endif#ifdef FBCON_HAS_CFB8 case 8:#endif mga_outb(M_DAC_REG, regno); mga_outb(M_DAC_VAL, red); mga_outb(M_DAC_VAL, green); mga_outb(M_DAC_VAL, blue); break;#endif#ifdef FBCON_HAS_CFB16 case 16: ACCESS_FBINFO(cmap.cfb16[regno]) = (red << p->var.red.offset) | (green << p->var.green.offset) | (blue << p->var.blue.offset) | (transp << p->var.transp.offset); /* for 1:5:5:5 */ break;#endif#ifdef FBCON_HAS_CFB24 case 24: ACCESS_FBINFO(cmap.cfb24[regno]) = (red << p->var.red.offset) | (green << p->var.green.offset) | (blue << p->var.blue.offset); break;#endif#ifdef FBCON_HAS_CFB32 case 32: ACCESS_FBINFO(cmap.cfb32[regno]) = (red << p->var.red.offset) | (green << p->var.green.offset) | (blue << p->var.blue.offset) | (transp << p->var.transp.offset); /* 8:8:8:8 */ break;#endif } return 0;}static inline void my_install_cmap(WPMINFO2){ /* Do not touch this code if you do not understand what it does! */ /* Never try to use do_install_cmap() instead. It is crap. */ struct fb_cmap* cmap = &ACCESS_FBINFO(currcon_display)->cmap; if (cmap->len) fb_set_cmap(cmap, 1, matroxfb_setcolreg, &ACCESS_FBINFO(fbcon)); else fb_set_cmap(fb_default_cmap(ACCESS_FBINFO(curr.cmap_len)), 1, matroxfb_setcolreg, &ACCESS_FBINFO(fbcon));}static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct display* p; DBG("matroxfb_get_fix")#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) if (ACCESS_FBINFO(dead)) { return -ENXIO; } if (con >= 0) p = fb_display + con; else p = ACCESS_FBINFO(fbcon.disp); memset(fix, 0, sizeof(*fix)); strcpy(fix->id,"MATROX"); fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); fix->type = p->type; fix->type_aux = p->type_aux; fix->visual = p->visual; fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */ fix->ypanstep = 1; fix->ywrapstep = 0; fix->line_length = p->line_length; fix->mmio_start = ACCESS_FBINFO(mmio.base); fix->mmio_len = ACCESS_FBINFO(mmio.len); fix->accel = ACCESS_FBINFO(devflags.accelerator); return 0;#undef minfo}static int matroxfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) DBG("matroxfb_get_var") if(con < 0) *var=ACCESS_FBINFO(fbcon.disp)->var; else *var=fb_display[con].var; return 0;#undef minfo}static int matroxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) int err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -