0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/kernel.h>
0015 #include <linux/string.h>
0016 #include <linux/fb.h>
0017 #include <linux/svga.h>
0018 #include <asm/types.h>
0019 #include <asm/io.h>
0020
0021
0022
0023 void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
0024 {
0025 u8 regval, bitval, bitnum;
0026
0027 while (regset->regnum != VGA_REGSET_END_VAL) {
0028 regval = vga_rcrt(regbase, regset->regnum);
0029 bitnum = regset->lowbit;
0030 while (bitnum <= regset->highbit) {
0031 bitval = 1 << bitnum;
0032 regval = regval & ~bitval;
0033 if (value & 1) regval = regval | bitval;
0034 bitnum ++;
0035 value = value >> 1;
0036 }
0037 vga_wcrt(regbase, regset->regnum, regval);
0038 regset ++;
0039 }
0040 }
0041
0042
0043 void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
0044 {
0045 u8 regval, bitval, bitnum;
0046
0047 while (regset->regnum != VGA_REGSET_END_VAL) {
0048 regval = vga_rseq(regbase, regset->regnum);
0049 bitnum = regset->lowbit;
0050 while (bitnum <= regset->highbit) {
0051 bitval = 1 << bitnum;
0052 regval = regval & ~bitval;
0053 if (value & 1) regval = regval | bitval;
0054 bitnum ++;
0055 value = value >> 1;
0056 }
0057 vga_wseq(regbase, regset->regnum, regval);
0058 regset ++;
0059 }
0060 }
0061
0062 static unsigned int svga_regset_size(const struct vga_regset *regset)
0063 {
0064 u8 count = 0;
0065
0066 while (regset->regnum != VGA_REGSET_END_VAL) {
0067 count += regset->highbit - regset->lowbit + 1;
0068 regset ++;
0069 }
0070 return 1 << count;
0071 }
0072
0073
0074
0075
0076
0077
0078 void svga_set_default_gfx_regs(void __iomem *regbase)
0079 {
0080
0081 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
0082 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
0083 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
0084 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
0085 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
0086 vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
0087
0088
0089 vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
0090
0091 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
0092 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
0093 }
0094
0095
0096 void svga_set_default_atc_regs(void __iomem *regbase)
0097 {
0098 u8 count;
0099
0100 vga_r(regbase, 0x3DA);
0101 vga_w(regbase, VGA_ATT_W, 0x00);
0102
0103
0104 for (count = 0; count <= 0xF; count ++)
0105 svga_wattr(regbase, count, count);
0106
0107 svga_wattr(regbase, VGA_ATC_MODE, 0x01);
0108
0109 svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
0110 svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
0111 svga_wattr(regbase, VGA_ATC_PEL, 0x00);
0112 svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
0113
0114 vga_r(regbase, 0x3DA);
0115 vga_w(regbase, VGA_ATT_W, 0x20);
0116 }
0117
0118
0119 void svga_set_default_seq_regs(void __iomem *regbase)
0120 {
0121
0122 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
0123 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
0124 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
0125
0126 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
0127 }
0128
0129
0130 void svga_set_default_crt_regs(void __iomem *regbase)
0131 {
0132
0133 svga_wcrt_mask(regbase, 0x03, 0x80, 0x80);
0134 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
0135 svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
0136 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
0137 vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
0138 }
0139
0140 void svga_set_textmode_vga_regs(void __iomem *regbase)
0141 {
0142
0143 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
0144 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
0145
0146 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f);
0147 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
0148 svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
0149
0150 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
0151 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
0152 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
0153 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
0154
0155 vga_wgfx(regbase, VGA_GFX_MODE, 0x10);
0156 vga_wgfx(regbase, VGA_GFX_MISC, 0x0E);
0157 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
0158
0159 vga_r(regbase, 0x3DA);
0160 vga_w(regbase, VGA_ATT_W, 0x00);
0161
0162 svga_wattr(regbase, 0x10, 0x0C);
0163 svga_wattr(regbase, 0x13, 0x08);
0164
0165 vga_r(regbase, 0x3DA);
0166 vga_w(regbase, VGA_ATT_W, 0x20);
0167 }
0168
0169 #if 0
0170 void svga_dump_var(struct fb_var_screeninfo *var, int node)
0171 {
0172 pr_debug("fb%d: var.vmode : 0x%X\n", node, var->vmode);
0173 pr_debug("fb%d: var.xres : %d\n", node, var->xres);
0174 pr_debug("fb%d: var.yres : %d\n", node, var->yres);
0175 pr_debug("fb%d: var.bits_per_pixel: %d\n", node, var->bits_per_pixel);
0176 pr_debug("fb%d: var.xres_virtual : %d\n", node, var->xres_virtual);
0177 pr_debug("fb%d: var.yres_virtual : %d\n", node, var->yres_virtual);
0178 pr_debug("fb%d: var.left_margin : %d\n", node, var->left_margin);
0179 pr_debug("fb%d: var.right_margin : %d\n", node, var->right_margin);
0180 pr_debug("fb%d: var.upper_margin : %d\n", node, var->upper_margin);
0181 pr_debug("fb%d: var.lower_margin : %d\n", node, var->lower_margin);
0182 pr_debug("fb%d: var.hsync_len : %d\n", node, var->hsync_len);
0183 pr_debug("fb%d: var.vsync_len : %d\n", node, var->vsync_len);
0184 pr_debug("fb%d: var.sync : 0x%X\n", node, var->sync);
0185 pr_debug("fb%d: var.pixclock : %d\n\n", node, var->pixclock);
0186 }
0187 #endif
0188
0189
0190
0191
0192
0193 void svga_settile(struct fb_info *info, struct fb_tilemap *map)
0194 {
0195 const u8 *font = map->data;
0196 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
0197 int i, c;
0198
0199 if ((map->width != 8) || (map->height != 16) ||
0200 (map->depth != 1) || (map->length != 256)) {
0201 fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n",
0202 map->width, map->height, map->depth, map->length);
0203 return;
0204 }
0205
0206 fb += 2;
0207 for (c = 0; c < map->length; c++) {
0208 for (i = 0; i < map->height; i++) {
0209 fb_writeb(font[i], fb + i * 4);
0210
0211 }
0212 fb += 128;
0213 font += map->height;
0214 }
0215 }
0216
0217
0218 void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
0219 {
0220 int dx, dy;
0221
0222 int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
0223 int rowstride = colstride * (info->var.xres_virtual / 8);
0224 u16 __iomem *fb = (u16 __iomem *) info->screen_base;
0225 u16 __iomem *src, *dst;
0226
0227 if ((area->sy > area->dy) ||
0228 ((area->sy == area->dy) && (area->sx > area->dx))) {
0229 src = fb + area->sx * colstride + area->sy * rowstride;
0230 dst = fb + area->dx * colstride + area->dy * rowstride;
0231 } else {
0232 src = fb + (area->sx + area->width - 1) * colstride
0233 + (area->sy + area->height - 1) * rowstride;
0234 dst = fb + (area->dx + area->width - 1) * colstride
0235 + (area->dy + area->height - 1) * rowstride;
0236
0237 colstride = -colstride;
0238 rowstride = -rowstride;
0239 }
0240
0241 for (dy = 0; dy < area->height; dy++) {
0242 u16 __iomem *src2 = src;
0243 u16 __iomem *dst2 = dst;
0244 for (dx = 0; dx < area->width; dx++) {
0245 fb_writew(fb_readw(src2), dst2);
0246
0247 src2 += colstride;
0248 dst2 += colstride;
0249 }
0250 src += rowstride;
0251 dst += rowstride;
0252 }
0253 }
0254
0255
0256 void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect)
0257 {
0258 int dx, dy;
0259 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
0260 int rowstride = colstride * (info->var.xres_virtual / 8);
0261 int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
0262 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
0263 fb += rect->sx * colstride + rect->sy * rowstride;
0264
0265 for (dy = 0; dy < rect->height; dy++) {
0266 u8 __iomem *fb2 = fb;
0267 for (dx = 0; dx < rect->width; dx++) {
0268 fb_writeb(rect->index, fb2);
0269 fb_writeb(attr, fb2 + 1);
0270 fb2 += colstride;
0271 }
0272 fb += rowstride;
0273 }
0274 }
0275
0276
0277 void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
0278 {
0279 int dx, dy, i;
0280 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
0281 int rowstride = colstride * (info->var.xres_virtual / 8);
0282 int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
0283 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
0284 fb += blit->sx * colstride + blit->sy * rowstride;
0285
0286 i=0;
0287 for (dy=0; dy < blit->height; dy ++) {
0288 u8 __iomem *fb2 = fb;
0289 for (dx = 0; dx < blit->width; dx ++) {
0290 fb_writeb(blit->indices[i], fb2);
0291 fb_writeb(attr, fb2 + 1);
0292 fb2 += colstride;
0293 i ++;
0294 if (i == blit->length) return;
0295 }
0296 fb += rowstride;
0297 }
0298
0299 }
0300
0301
0302 void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
0303 {
0304 u8 cs = 0x0d;
0305 u8 ce = 0x0e;
0306 u16 pos = cursor->sx + (info->var.xoffset / 8)
0307 + (cursor->sy + (info->var.yoffset / 16))
0308 * (info->var.xres_virtual / 8);
0309
0310 if (! cursor -> mode)
0311 return;
0312
0313 svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20);
0314
0315 if (cursor -> shape == FB_TILE_CURSOR_NONE)
0316 return;
0317
0318 switch (cursor -> shape) {
0319 case FB_TILE_CURSOR_UNDERLINE:
0320 cs = 0x0d;
0321 break;
0322 case FB_TILE_CURSOR_LOWER_THIRD:
0323 cs = 0x09;
0324 break;
0325 case FB_TILE_CURSOR_LOWER_HALF:
0326 cs = 0x07;
0327 break;
0328 case FB_TILE_CURSOR_TWO_THIRDS:
0329 cs = 0x05;
0330 break;
0331 case FB_TILE_CURSOR_BLOCK:
0332 cs = 0x01;
0333 break;
0334 }
0335
0336
0337 vga_wcrt(regbase, 0x0E, pos >> 8);
0338 vga_wcrt(regbase, 0x0F, pos & 0xFF);
0339
0340 vga_wcrt(regbase, 0x0B, ce);
0341 vga_wcrt(regbase, 0x0A, cs);
0342 }
0343
0344 int svga_get_tilemax(struct fb_info *info)
0345 {
0346 return 256;
0347 }
0348
0349
0350
0351 void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
0352 struct fb_var_screeninfo *var)
0353 {
0354 if (var->bits_per_pixel == 0) {
0355
0356 caps->x = 1 << (8 - 1);
0357 caps->y = 1 << (16 - 1);
0358 caps->len = 256;
0359 } else {
0360 caps->x = (var->bits_per_pixel == 4) ? 1 << (8 - 1) : ~(u32)0;
0361 caps->y = ~(u32)0;
0362 caps->len = ~(u32)0;
0363 }
0364 }
0365 EXPORT_SYMBOL(svga_get_caps);
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376 static inline u32 abs_diff(u32 a, u32 b)
0377 {
0378 return (a > b) ? (a - b) : (b - a);
0379 }
0380
0381 int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node)
0382 {
0383 u16 am, an, ar;
0384 u32 f_vco, f_current, delta_current, delta_best;
0385
0386 pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int) f_wanted);
0387
0388 ar = pll->r_max;
0389 f_vco = f_wanted << ar;
0390
0391
0392 if ((f_vco >> ar) != f_wanted)
0393 return -EINVAL;
0394
0395
0396
0397
0398 while ((ar > pll->r_min) && (f_vco > pll->f_vco_max)) {
0399 ar--;
0400 f_vco = f_vco >> 1;
0401 }
0402
0403
0404 if ((f_vco < pll->f_vco_min) || (f_vco > pll->f_vco_max))
0405 return -EINVAL;
0406
0407 delta_best = 0xFFFFFFFF;
0408 *m = 0;
0409 *n = 0;
0410 *r = ar;
0411
0412 am = pll->m_min;
0413 an = pll->n_min;
0414
0415 while ((am <= pll->m_max) && (an <= pll->n_max)) {
0416 f_current = (pll->f_base * am) / an;
0417 delta_current = abs_diff (f_current, f_vco);
0418
0419 if (delta_current < delta_best) {
0420 delta_best = delta_current;
0421 *m = am;
0422 *n = an;
0423 }
0424
0425 if (f_current <= f_vco) {
0426 am ++;
0427 } else {
0428 an ++;
0429 }
0430 }
0431
0432 f_current = (pll->f_base * *m) / *n;
0433 pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int) (f_current >> ar), (int) f_current);
0434 pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int) *m, (unsigned int) *n, (unsigned int) *r);
0435 return 0;
0436 }
0437
0438
0439
0440
0441
0442
0443 int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node)
0444 {
0445 u32 value;
0446
0447 var->xres = (var->xres+7)&~7;
0448 var->left_margin = (var->left_margin+7)&~7;
0449 var->right_margin = (var->right_margin+7)&~7;
0450 var->hsync_len = (var->hsync_len+7)&~7;
0451
0452
0453 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
0454 if (((value / 8) - 5) >= svga_regset_size (tm->h_total_regs))
0455 return -EINVAL;
0456
0457
0458 value = var->xres;
0459 if (((value / 8) - 1) >= svga_regset_size (tm->h_display_regs))
0460 return -EINVAL;
0461 if (((value / 8) - 1) >= svga_regset_size (tm->h_blank_start_regs))
0462 return -EINVAL;
0463
0464
0465 value = var->xres + var->right_margin;
0466 if (((value / 8) - 1) >= svga_regset_size (tm->h_sync_start_regs))
0467 return -EINVAL;
0468
0469
0470 value = var->left_margin + var->right_margin + var->hsync_len;
0471 if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_blank_end_regs)))
0472 return -EINVAL;
0473
0474
0475 value = var->hsync_len;
0476 if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_sync_end_regs)))
0477 return -EINVAL;
0478
0479
0480 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
0481 if ((value - 1) >= svga_regset_size(tm->v_total_regs))
0482 return -EINVAL;
0483
0484
0485 value = var->yres;
0486 if ((value - 1) >= svga_regset_size(tm->v_display_regs))
0487 return -EINVAL;
0488 if ((value - 1) >= svga_regset_size(tm->v_blank_start_regs))
0489 return -EINVAL;
0490
0491
0492 value = var->yres + var->lower_margin;
0493 if ((value - 1) >= svga_regset_size(tm->v_sync_start_regs))
0494 return -EINVAL;
0495
0496
0497 value = var->upper_margin + var->lower_margin + var->vsync_len;
0498 if ((value == 0) || (value >= svga_regset_size (tm->v_blank_end_regs)))
0499 return -EINVAL;
0500
0501
0502 value = var->vsync_len;
0503 if ((value == 0) || (value >= svga_regset_size (tm->v_sync_end_regs)))
0504 return -EINVAL;
0505
0506 return 0;
0507 }
0508
0509
0510 void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
0511 struct fb_var_screeninfo *var,
0512 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
0513 {
0514 u8 regval;
0515 u32 value;
0516
0517 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
0518 value = (value * hmul) / hdiv;
0519 pr_debug("fb%d: horizontal total : %d\n", node, value);
0520 svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
0521
0522 value = var->xres;
0523 value = (value * hmul) / hdiv;
0524 pr_debug("fb%d: horizontal display : %d\n", node, value);
0525 svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
0526
0527 value = var->xres;
0528 value = (value * hmul) / hdiv;
0529 pr_debug("fb%d: horizontal blank start: %d\n", node, value);
0530 svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
0531
0532 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
0533 value = (value * hmul) / hdiv;
0534 pr_debug("fb%d: horizontal blank end : %d\n", node, value);
0535 svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
0536
0537 value = var->xres + var->right_margin;
0538 value = (value * hmul) / hdiv;
0539 pr_debug("fb%d: horizontal sync start : %d\n", node, value);
0540 svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
0541
0542 value = var->xres + var->right_margin + var->hsync_len;
0543 value = (value * hmul) / hdiv;
0544 pr_debug("fb%d: horizontal sync end : %d\n", node, value);
0545 svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
0546
0547 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
0548 value = (value * vmul) / vdiv;
0549 pr_debug("fb%d: vertical total : %d\n", node, value);
0550 svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
0551
0552 value = var->yres;
0553 value = (value * vmul) / vdiv;
0554 pr_debug("fb%d: vertical display : %d\n", node, value);
0555 svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
0556
0557 value = var->yres;
0558 value = (value * vmul) / vdiv;
0559 pr_debug("fb%d: vertical blank start : %d\n", node, value);
0560 svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
0561
0562 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
0563 value = (value * vmul) / vdiv;
0564 pr_debug("fb%d: vertical blank end : %d\n", node, value);
0565 svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
0566
0567 value = var->yres + var->lower_margin;
0568 value = (value * vmul) / vdiv;
0569 pr_debug("fb%d: vertical sync start : %d\n", node, value);
0570 svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
0571
0572 value = var->yres + var->lower_margin + var->vsync_len;
0573 value = (value * vmul) / vdiv;
0574 pr_debug("fb%d: vertical sync end : %d\n", node, value);
0575 svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
0576
0577
0578
0579 regval = vga_r(regbase, VGA_MIS_R);
0580 if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
0581 pr_debug("fb%d: positive horizontal sync\n", node);
0582 regval = regval & ~0x80;
0583 } else {
0584 pr_debug("fb%d: negative horizontal sync\n", node);
0585 regval = regval | 0x80;
0586 }
0587 if (var->sync & FB_SYNC_VERT_HIGH_ACT) {
0588 pr_debug("fb%d: positive vertical sync\n", node);
0589 regval = regval & ~0x40;
0590 } else {
0591 pr_debug("fb%d: negative vertical sync\n\n", node);
0592 regval = regval | 0x40;
0593 }
0594 vga_w(regbase, VGA_MIS_W, regval);
0595 }
0596
0597
0598
0599
0600
0601 static inline int match_format(const struct svga_fb_format *frm,
0602 struct fb_var_screeninfo *var)
0603 {
0604 int i = 0;
0605 int stored = -EINVAL;
0606
0607 while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
0608 {
0609 if ((var->bits_per_pixel == frm->bits_per_pixel) &&
0610 (var->red.length <= frm->red.length) &&
0611 (var->green.length <= frm->green.length) &&
0612 (var->blue.length <= frm->blue.length) &&
0613 (var->transp.length <= frm->transp.length) &&
0614 (var->nonstd == frm->nonstd))
0615 return i;
0616 if (var->bits_per_pixel == frm->bits_per_pixel)
0617 stored = i;
0618 i++;
0619 frm++;
0620 }
0621 return stored;
0622 }
0623
0624 int svga_match_format(const struct svga_fb_format *frm,
0625 struct fb_var_screeninfo *var,
0626 struct fb_fix_screeninfo *fix)
0627 {
0628 int i = match_format(frm, var);
0629
0630 if (i >= 0) {
0631 var->bits_per_pixel = frm[i].bits_per_pixel;
0632 var->red = frm[i].red;
0633 var->green = frm[i].green;
0634 var->blue = frm[i].blue;
0635 var->transp = frm[i].transp;
0636 var->nonstd = frm[i].nonstd;
0637 if (fix != NULL) {
0638 fix->type = frm[i].type;
0639 fix->type_aux = frm[i].type_aux;
0640 fix->visual = frm[i].visual;
0641 fix->xpanstep = frm[i].xpanstep;
0642 }
0643 }
0644
0645 return i;
0646 }
0647
0648
0649 EXPORT_SYMBOL(svga_wcrt_multi);
0650 EXPORT_SYMBOL(svga_wseq_multi);
0651
0652 EXPORT_SYMBOL(svga_set_default_gfx_regs);
0653 EXPORT_SYMBOL(svga_set_default_atc_regs);
0654 EXPORT_SYMBOL(svga_set_default_seq_regs);
0655 EXPORT_SYMBOL(svga_set_default_crt_regs);
0656 EXPORT_SYMBOL(svga_set_textmode_vga_regs);
0657
0658 EXPORT_SYMBOL(svga_settile);
0659 EXPORT_SYMBOL(svga_tilecopy);
0660 EXPORT_SYMBOL(svga_tilefill);
0661 EXPORT_SYMBOL(svga_tileblit);
0662 EXPORT_SYMBOL(svga_tilecursor);
0663 EXPORT_SYMBOL(svga_get_tilemax);
0664
0665 EXPORT_SYMBOL(svga_compute_pll);
0666 EXPORT_SYMBOL(svga_check_timings);
0667 EXPORT_SYMBOL(svga_set_timings);
0668 EXPORT_SYMBOL(svga_match_format);
0669
0670 MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>");
0671 MODULE_DESCRIPTION("Common utility functions for VGA-based graphics cards");
0672 MODULE_LICENSE("GPL");