119757fc8STomi Valkeinen /*
219757fc8STomi Valkeinen * Common utility functions for VGA-based graphics cards.
319757fc8STomi Valkeinen *
419757fc8STomi Valkeinen * Copyright (c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>
519757fc8STomi Valkeinen *
619757fc8STomi Valkeinen * This file is subject to the terms and conditions of the GNU General Public
719757fc8STomi Valkeinen * License. See the file COPYING in the main directory of this archive for
819757fc8STomi Valkeinen * more details.
919757fc8STomi Valkeinen *
1019757fc8STomi Valkeinen * Some parts are based on David Boucher's viafb (http://davesdomain.org.uk/viafb/)
1119757fc8STomi Valkeinen */
1219757fc8STomi Valkeinen
1319757fc8STomi Valkeinen #include <linux/module.h>
1419757fc8STomi Valkeinen #include <linux/kernel.h>
1519757fc8STomi Valkeinen #include <linux/string.h>
1619757fc8STomi Valkeinen #include <linux/fb.h>
17*46f12960SAndy Shevchenko #include <linux/math.h>
1819757fc8STomi Valkeinen #include <linux/svga.h>
1919757fc8STomi Valkeinen #include <asm/types.h>
2019757fc8STomi Valkeinen #include <asm/io.h>
2119757fc8STomi Valkeinen
2219757fc8STomi Valkeinen
2319757fc8STomi Valkeinen /* Write a CRT register value spread across multiple registers */
svga_wcrt_multi(void __iomem * regbase,const struct vga_regset * regset,u32 value)2419757fc8STomi Valkeinen void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
2519757fc8STomi Valkeinen {
2619757fc8STomi Valkeinen u8 regval, bitval, bitnum;
2719757fc8STomi Valkeinen
2819757fc8STomi Valkeinen while (regset->regnum != VGA_REGSET_END_VAL) {
2919757fc8STomi Valkeinen regval = vga_rcrt(regbase, regset->regnum);
3019757fc8STomi Valkeinen bitnum = regset->lowbit;
3119757fc8STomi Valkeinen while (bitnum <= regset->highbit) {
3219757fc8STomi Valkeinen bitval = 1 << bitnum;
3319757fc8STomi Valkeinen regval = regval & ~bitval;
3419757fc8STomi Valkeinen if (value & 1) regval = regval | bitval;
3519757fc8STomi Valkeinen bitnum ++;
3619757fc8STomi Valkeinen value = value >> 1;
3719757fc8STomi Valkeinen }
3819757fc8STomi Valkeinen vga_wcrt(regbase, regset->regnum, regval);
3919757fc8STomi Valkeinen regset ++;
4019757fc8STomi Valkeinen }
4119757fc8STomi Valkeinen }
4219757fc8STomi Valkeinen
4319757fc8STomi Valkeinen /* Write a sequencer register value spread across multiple registers */
svga_wseq_multi(void __iomem * regbase,const struct vga_regset * regset,u32 value)4419757fc8STomi Valkeinen void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
4519757fc8STomi Valkeinen {
4619757fc8STomi Valkeinen u8 regval, bitval, bitnum;
4719757fc8STomi Valkeinen
4819757fc8STomi Valkeinen while (regset->regnum != VGA_REGSET_END_VAL) {
4919757fc8STomi Valkeinen regval = vga_rseq(regbase, regset->regnum);
5019757fc8STomi Valkeinen bitnum = regset->lowbit;
5119757fc8STomi Valkeinen while (bitnum <= regset->highbit) {
5219757fc8STomi Valkeinen bitval = 1 << bitnum;
5319757fc8STomi Valkeinen regval = regval & ~bitval;
5419757fc8STomi Valkeinen if (value & 1) regval = regval | bitval;
5519757fc8STomi Valkeinen bitnum ++;
5619757fc8STomi Valkeinen value = value >> 1;
5719757fc8STomi Valkeinen }
5819757fc8STomi Valkeinen vga_wseq(regbase, regset->regnum, regval);
5919757fc8STomi Valkeinen regset ++;
6019757fc8STomi Valkeinen }
6119757fc8STomi Valkeinen }
6219757fc8STomi Valkeinen
svga_regset_size(const struct vga_regset * regset)6319757fc8STomi Valkeinen static unsigned int svga_regset_size(const struct vga_regset *regset)
6419757fc8STomi Valkeinen {
6519757fc8STomi Valkeinen u8 count = 0;
6619757fc8STomi Valkeinen
6719757fc8STomi Valkeinen while (regset->regnum != VGA_REGSET_END_VAL) {
6819757fc8STomi Valkeinen count += regset->highbit - regset->lowbit + 1;
6919757fc8STomi Valkeinen regset ++;
7019757fc8STomi Valkeinen }
7119757fc8STomi Valkeinen return 1 << count;
7219757fc8STomi Valkeinen }
7319757fc8STomi Valkeinen
7419757fc8STomi Valkeinen
7519757fc8STomi Valkeinen /* ------------------------------------------------------------------------- */
7619757fc8STomi Valkeinen
7719757fc8STomi Valkeinen
7819757fc8STomi Valkeinen /* Set graphics controller registers to sane values */
svga_set_default_gfx_regs(void __iomem * regbase)7919757fc8STomi Valkeinen void svga_set_default_gfx_regs(void __iomem *regbase)
8019757fc8STomi Valkeinen {
8119757fc8STomi Valkeinen /* All standard GFX registers (GR00 - GR08) */
8219757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
8319757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
8419757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
8519757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
8619757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
8719757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
8819757fc8STomi Valkeinen /* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
8919757fc8STomi Valkeinen /* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
9019757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
9119757fc8STomi Valkeinen /* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
9219757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
9319757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
9419757fc8STomi Valkeinen }
9519757fc8STomi Valkeinen
9619757fc8STomi Valkeinen /* Set attribute controller registers to sane values */
svga_set_default_atc_regs(void __iomem * regbase)9719757fc8STomi Valkeinen void svga_set_default_atc_regs(void __iomem *regbase)
9819757fc8STomi Valkeinen {
9919757fc8STomi Valkeinen u8 count;
10019757fc8STomi Valkeinen
10119757fc8STomi Valkeinen vga_r(regbase, 0x3DA);
10219757fc8STomi Valkeinen vga_w(regbase, VGA_ATT_W, 0x00);
10319757fc8STomi Valkeinen
10419757fc8STomi Valkeinen /* All standard ATC registers (AR00 - AR14) */
10519757fc8STomi Valkeinen for (count = 0; count <= 0xF; count ++)
10619757fc8STomi Valkeinen svga_wattr(regbase, count, count);
10719757fc8STomi Valkeinen
10819757fc8STomi Valkeinen svga_wattr(regbase, VGA_ATC_MODE, 0x01);
10919757fc8STomi Valkeinen /* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
11019757fc8STomi Valkeinen svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
11119757fc8STomi Valkeinen svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
11219757fc8STomi Valkeinen svga_wattr(regbase, VGA_ATC_PEL, 0x00);
11319757fc8STomi Valkeinen svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
11419757fc8STomi Valkeinen
11519757fc8STomi Valkeinen vga_r(regbase, 0x3DA);
11619757fc8STomi Valkeinen vga_w(regbase, VGA_ATT_W, 0x20);
11719757fc8STomi Valkeinen }
11819757fc8STomi Valkeinen
11919757fc8STomi Valkeinen /* Set sequencer registers to sane values */
svga_set_default_seq_regs(void __iomem * regbase)12019757fc8STomi Valkeinen void svga_set_default_seq_regs(void __iomem *regbase)
12119757fc8STomi Valkeinen {
12219757fc8STomi Valkeinen /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
12319757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
12419757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
12519757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
12619757fc8STomi Valkeinen /* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
12719757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
12819757fc8STomi Valkeinen }
12919757fc8STomi Valkeinen
13019757fc8STomi Valkeinen /* Set CRTC registers to sane values */
svga_set_default_crt_regs(void __iomem * regbase)13119757fc8STomi Valkeinen void svga_set_default_crt_regs(void __iomem *regbase)
13219757fc8STomi Valkeinen {
13319757fc8STomi Valkeinen /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
13419757fc8STomi Valkeinen svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
13519757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
13619757fc8STomi Valkeinen svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
13719757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
13819757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
13919757fc8STomi Valkeinen }
14019757fc8STomi Valkeinen
svga_set_textmode_vga_regs(void __iomem * regbase)14119757fc8STomi Valkeinen void svga_set_textmode_vga_regs(void __iomem *regbase)
14219757fc8STomi Valkeinen {
14319757fc8STomi Valkeinen /* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
14419757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
14519757fc8STomi Valkeinen vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
14619757fc8STomi Valkeinen
14719757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
14819757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
14919757fc8STomi Valkeinen svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
15019757fc8STomi Valkeinen
15119757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
15219757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
15319757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
15419757fc8STomi Valkeinen vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
15519757fc8STomi Valkeinen
15619757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
15719757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
15819757fc8STomi Valkeinen vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
15919757fc8STomi Valkeinen
16019757fc8STomi Valkeinen vga_r(regbase, 0x3DA);
16119757fc8STomi Valkeinen vga_w(regbase, VGA_ATT_W, 0x00);
16219757fc8STomi Valkeinen
16319757fc8STomi Valkeinen svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
16419757fc8STomi Valkeinen svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
16519757fc8STomi Valkeinen
16619757fc8STomi Valkeinen vga_r(regbase, 0x3DA);
16719757fc8STomi Valkeinen vga_w(regbase, VGA_ATT_W, 0x20);
16819757fc8STomi Valkeinen }
16919757fc8STomi Valkeinen
17019757fc8STomi Valkeinen #if 0
17119757fc8STomi Valkeinen void svga_dump_var(struct fb_var_screeninfo *var, int node)
17219757fc8STomi Valkeinen {
17319757fc8STomi Valkeinen pr_debug("fb%d: var.vmode : 0x%X\n", node, var->vmode);
17419757fc8STomi Valkeinen pr_debug("fb%d: var.xres : %d\n", node, var->xres);
17519757fc8STomi Valkeinen pr_debug("fb%d: var.yres : %d\n", node, var->yres);
17619757fc8STomi Valkeinen pr_debug("fb%d: var.bits_per_pixel: %d\n", node, var->bits_per_pixel);
17719757fc8STomi Valkeinen pr_debug("fb%d: var.xres_virtual : %d\n", node, var->xres_virtual);
17819757fc8STomi Valkeinen pr_debug("fb%d: var.yres_virtual : %d\n", node, var->yres_virtual);
17919757fc8STomi Valkeinen pr_debug("fb%d: var.left_margin : %d\n", node, var->left_margin);
18019757fc8STomi Valkeinen pr_debug("fb%d: var.right_margin : %d\n", node, var->right_margin);
18119757fc8STomi Valkeinen pr_debug("fb%d: var.upper_margin : %d\n", node, var->upper_margin);
18219757fc8STomi Valkeinen pr_debug("fb%d: var.lower_margin : %d\n", node, var->lower_margin);
18319757fc8STomi Valkeinen pr_debug("fb%d: var.hsync_len : %d\n", node, var->hsync_len);
18419757fc8STomi Valkeinen pr_debug("fb%d: var.vsync_len : %d\n", node, var->vsync_len);
18519757fc8STomi Valkeinen pr_debug("fb%d: var.sync : 0x%X\n", node, var->sync);
18619757fc8STomi Valkeinen pr_debug("fb%d: var.pixclock : %d\n\n", node, var->pixclock);
18719757fc8STomi Valkeinen }
18819757fc8STomi Valkeinen #endif /* 0 */
18919757fc8STomi Valkeinen
19019757fc8STomi Valkeinen
19119757fc8STomi Valkeinen /* ------------------------------------------------------------------------- */
19219757fc8STomi Valkeinen
19319757fc8STomi Valkeinen
svga_settile(struct fb_info * info,struct fb_tilemap * map)19419757fc8STomi Valkeinen void svga_settile(struct fb_info *info, struct fb_tilemap *map)
19519757fc8STomi Valkeinen {
19619757fc8STomi Valkeinen const u8 *font = map->data;
19719757fc8STomi Valkeinen u8 __iomem *fb = (u8 __iomem *)info->screen_base;
19819757fc8STomi Valkeinen int i, c;
19919757fc8STomi Valkeinen
20019757fc8STomi Valkeinen if ((map->width != 8) || (map->height != 16) ||
20119757fc8STomi Valkeinen (map->depth != 1) || (map->length != 256)) {
20219757fc8STomi Valkeinen fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n",
20319757fc8STomi Valkeinen map->width, map->height, map->depth, map->length);
20419757fc8STomi Valkeinen return;
20519757fc8STomi Valkeinen }
20619757fc8STomi Valkeinen
20719757fc8STomi Valkeinen fb += 2;
20819757fc8STomi Valkeinen for (c = 0; c < map->length; c++) {
20919757fc8STomi Valkeinen for (i = 0; i < map->height; i++) {
21019757fc8STomi Valkeinen fb_writeb(font[i], fb + i * 4);
21119757fc8STomi Valkeinen // fb[i * 4] = font[i];
21219757fc8STomi Valkeinen }
21319757fc8STomi Valkeinen fb += 128;
21419757fc8STomi Valkeinen font += map->height;
21519757fc8STomi Valkeinen }
21619757fc8STomi Valkeinen }
21719757fc8STomi Valkeinen
21819757fc8STomi Valkeinen /* Copy area in text (tileblit) mode */
svga_tilecopy(struct fb_info * info,struct fb_tilearea * area)21919757fc8STomi Valkeinen void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
22019757fc8STomi Valkeinen {
22119757fc8STomi Valkeinen int dx, dy;
22219757fc8STomi Valkeinen /* colstride is halved in this function because u16 are used */
22319757fc8STomi Valkeinen int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
22419757fc8STomi Valkeinen int rowstride = colstride * (info->var.xres_virtual / 8);
22519757fc8STomi Valkeinen u16 __iomem *fb = (u16 __iomem *) info->screen_base;
22619757fc8STomi Valkeinen u16 __iomem *src, *dst;
22719757fc8STomi Valkeinen
22819757fc8STomi Valkeinen if ((area->sy > area->dy) ||
22919757fc8STomi Valkeinen ((area->sy == area->dy) && (area->sx > area->dx))) {
23019757fc8STomi Valkeinen src = fb + area->sx * colstride + area->sy * rowstride;
23119757fc8STomi Valkeinen dst = fb + area->dx * colstride + area->dy * rowstride;
23219757fc8STomi Valkeinen } else {
23319757fc8STomi Valkeinen src = fb + (area->sx + area->width - 1) * colstride
23419757fc8STomi Valkeinen + (area->sy + area->height - 1) * rowstride;
23519757fc8STomi Valkeinen dst = fb + (area->dx + area->width - 1) * colstride
23619757fc8STomi Valkeinen + (area->dy + area->height - 1) * rowstride;
23719757fc8STomi Valkeinen
23819757fc8STomi Valkeinen colstride = -colstride;
23919757fc8STomi Valkeinen rowstride = -rowstride;
24019757fc8STomi Valkeinen }
24119757fc8STomi Valkeinen
24219757fc8STomi Valkeinen for (dy = 0; dy < area->height; dy++) {
24319757fc8STomi Valkeinen u16 __iomem *src2 = src;
24419757fc8STomi Valkeinen u16 __iomem *dst2 = dst;
24519757fc8STomi Valkeinen for (dx = 0; dx < area->width; dx++) {
24619757fc8STomi Valkeinen fb_writew(fb_readw(src2), dst2);
24719757fc8STomi Valkeinen // *dst2 = *src2;
24819757fc8STomi Valkeinen src2 += colstride;
24919757fc8STomi Valkeinen dst2 += colstride;
25019757fc8STomi Valkeinen }
25119757fc8STomi Valkeinen src += rowstride;
25219757fc8STomi Valkeinen dst += rowstride;
25319757fc8STomi Valkeinen }
25419757fc8STomi Valkeinen }
25519757fc8STomi Valkeinen
25619757fc8STomi Valkeinen /* Fill area in text (tileblit) mode */
svga_tilefill(struct fb_info * info,struct fb_tilerect * rect)25719757fc8STomi Valkeinen void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect)
25819757fc8STomi Valkeinen {
25919757fc8STomi Valkeinen int dx, dy;
26019757fc8STomi Valkeinen int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
26119757fc8STomi Valkeinen int rowstride = colstride * (info->var.xres_virtual / 8);
26219757fc8STomi Valkeinen int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
26319757fc8STomi Valkeinen u8 __iomem *fb = (u8 __iomem *)info->screen_base;
26419757fc8STomi Valkeinen fb += rect->sx * colstride + rect->sy * rowstride;
26519757fc8STomi Valkeinen
26619757fc8STomi Valkeinen for (dy = 0; dy < rect->height; dy++) {
26719757fc8STomi Valkeinen u8 __iomem *fb2 = fb;
26819757fc8STomi Valkeinen for (dx = 0; dx < rect->width; dx++) {
26919757fc8STomi Valkeinen fb_writeb(rect->index, fb2);
27019757fc8STomi Valkeinen fb_writeb(attr, fb2 + 1);
27119757fc8STomi Valkeinen fb2 += colstride;
27219757fc8STomi Valkeinen }
27319757fc8STomi Valkeinen fb += rowstride;
27419757fc8STomi Valkeinen }
27519757fc8STomi Valkeinen }
27619757fc8STomi Valkeinen
27719757fc8STomi Valkeinen /* Write text in text (tileblit) mode */
svga_tileblit(struct fb_info * info,struct fb_tileblit * blit)27819757fc8STomi Valkeinen void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
27919757fc8STomi Valkeinen {
28019757fc8STomi Valkeinen int dx, dy, i;
28119757fc8STomi Valkeinen int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
28219757fc8STomi Valkeinen int rowstride = colstride * (info->var.xres_virtual / 8);
28319757fc8STomi Valkeinen int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
28419757fc8STomi Valkeinen u8 __iomem *fb = (u8 __iomem *)info->screen_base;
28519757fc8STomi Valkeinen fb += blit->sx * colstride + blit->sy * rowstride;
28619757fc8STomi Valkeinen
28719757fc8STomi Valkeinen i=0;
28819757fc8STomi Valkeinen for (dy=0; dy < blit->height; dy ++) {
28919757fc8STomi Valkeinen u8 __iomem *fb2 = fb;
29019757fc8STomi Valkeinen for (dx = 0; dx < blit->width; dx ++) {
29119757fc8STomi Valkeinen fb_writeb(blit->indices[i], fb2);
29219757fc8STomi Valkeinen fb_writeb(attr, fb2 + 1);
29319757fc8STomi Valkeinen fb2 += colstride;
29419757fc8STomi Valkeinen i ++;
29519757fc8STomi Valkeinen if (i == blit->length) return;
29619757fc8STomi Valkeinen }
29719757fc8STomi Valkeinen fb += rowstride;
29819757fc8STomi Valkeinen }
29919757fc8STomi Valkeinen
30019757fc8STomi Valkeinen }
30119757fc8STomi Valkeinen
30219757fc8STomi Valkeinen /* Set cursor in text (tileblit) mode */
svga_tilecursor(void __iomem * regbase,struct fb_info * info,struct fb_tilecursor * cursor)30319757fc8STomi Valkeinen void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
30419757fc8STomi Valkeinen {
30519757fc8STomi Valkeinen u8 cs = 0x0d;
30619757fc8STomi Valkeinen u8 ce = 0x0e;
30719757fc8STomi Valkeinen u16 pos = cursor->sx + (info->var.xoffset / 8)
30819757fc8STomi Valkeinen + (cursor->sy + (info->var.yoffset / 16))
30919757fc8STomi Valkeinen * (info->var.xres_virtual / 8);
31019757fc8STomi Valkeinen
31119757fc8STomi Valkeinen if (! cursor -> mode)
31219757fc8STomi Valkeinen return;
31319757fc8STomi Valkeinen
31419757fc8STomi Valkeinen svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
31519757fc8STomi Valkeinen
31619757fc8STomi Valkeinen if (cursor -> shape == FB_TILE_CURSOR_NONE)
31719757fc8STomi Valkeinen return;
31819757fc8STomi Valkeinen
31919757fc8STomi Valkeinen switch (cursor -> shape) {
32019757fc8STomi Valkeinen case FB_TILE_CURSOR_UNDERLINE:
32119757fc8STomi Valkeinen cs = 0x0d;
32219757fc8STomi Valkeinen break;
32319757fc8STomi Valkeinen case FB_TILE_CURSOR_LOWER_THIRD:
32419757fc8STomi Valkeinen cs = 0x09;
32519757fc8STomi Valkeinen break;
32619757fc8STomi Valkeinen case FB_TILE_CURSOR_LOWER_HALF:
32719757fc8STomi Valkeinen cs = 0x07;
32819757fc8STomi Valkeinen break;
32919757fc8STomi Valkeinen case FB_TILE_CURSOR_TWO_THIRDS:
33019757fc8STomi Valkeinen cs = 0x05;
33119757fc8STomi Valkeinen break;
33219757fc8STomi Valkeinen case FB_TILE_CURSOR_BLOCK:
33319757fc8STomi Valkeinen cs = 0x01;
33419757fc8STomi Valkeinen break;
33519757fc8STomi Valkeinen }
33619757fc8STomi Valkeinen
33719757fc8STomi Valkeinen /* set cursor position */
33819757fc8STomi Valkeinen vga_wcrt(regbase, 0x0E, pos >> 8);
33919757fc8STomi Valkeinen vga_wcrt(regbase, 0x0F, pos & 0xFF);
34019757fc8STomi Valkeinen
34119757fc8STomi Valkeinen vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
34219757fc8STomi Valkeinen vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
34319757fc8STomi Valkeinen }
34419757fc8STomi Valkeinen
svga_get_tilemax(struct fb_info * info)34519757fc8STomi Valkeinen int svga_get_tilemax(struct fb_info *info)
34619757fc8STomi Valkeinen {
34719757fc8STomi Valkeinen return 256;
34819757fc8STomi Valkeinen }
34919757fc8STomi Valkeinen
35019757fc8STomi Valkeinen /* Get capabilities of accelerator based on the mode */
35119757fc8STomi Valkeinen
svga_get_caps(struct fb_info * info,struct fb_blit_caps * caps,struct fb_var_screeninfo * var)35219757fc8STomi Valkeinen void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
35319757fc8STomi Valkeinen struct fb_var_screeninfo *var)
35419757fc8STomi Valkeinen {
35519757fc8STomi Valkeinen if (var->bits_per_pixel == 0) {
35619757fc8STomi Valkeinen /* can only support 256 8x16 bitmap */
35719757fc8STomi Valkeinen caps->x = 1 << (8 - 1);
35819757fc8STomi Valkeinen caps->y = 1 << (16 - 1);
35919757fc8STomi Valkeinen caps->len = 256;
36019757fc8STomi Valkeinen } else {
36119757fc8STomi Valkeinen caps->x = (var->bits_per_pixel == 4) ? 1 << (8 - 1) : ~(u32)0;
36219757fc8STomi Valkeinen caps->y = ~(u32)0;
36319757fc8STomi Valkeinen caps->len = ~(u32)0;
36419757fc8STomi Valkeinen }
36519757fc8STomi Valkeinen }
36619757fc8STomi Valkeinen EXPORT_SYMBOL(svga_get_caps);
36719757fc8STomi Valkeinen
36819757fc8STomi Valkeinen /* ------------------------------------------------------------------------- */
36919757fc8STomi Valkeinen
37019757fc8STomi Valkeinen
37119757fc8STomi Valkeinen /*
37219757fc8STomi Valkeinen * Compute PLL settings (M, N, R)
37319757fc8STomi Valkeinen * F_VCO = (F_BASE * M) / N
37419757fc8STomi Valkeinen * F_OUT = F_VCO / (2^R)
37519757fc8STomi Valkeinen */
svga_compute_pll(const struct svga_pll * pll,u32 f_wanted,u16 * m,u16 * n,u16 * r,int node)37619757fc8STomi Valkeinen int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node)
37719757fc8STomi Valkeinen {
37819757fc8STomi Valkeinen u16 am, an, ar;
37919757fc8STomi Valkeinen u32 f_vco, f_current, delta_current, delta_best;
38019757fc8STomi Valkeinen
38119757fc8STomi Valkeinen pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int) f_wanted);
38219757fc8STomi Valkeinen
38319757fc8STomi Valkeinen ar = pll->r_max;
38419757fc8STomi Valkeinen f_vco = f_wanted << ar;
38519757fc8STomi Valkeinen
38619757fc8STomi Valkeinen /* overflow check */
38719757fc8STomi Valkeinen if ((f_vco >> ar) != f_wanted)
38819757fc8STomi Valkeinen return -EINVAL;
38919757fc8STomi Valkeinen
39019757fc8STomi Valkeinen /* It is usually better to have greater VCO clock
39119757fc8STomi Valkeinen because of better frequency stability.
39219757fc8STomi Valkeinen So first try r_max, then r smaller. */
39319757fc8STomi Valkeinen while ((ar > pll->r_min) && (f_vco > pll->f_vco_max)) {
39419757fc8STomi Valkeinen ar--;
39519757fc8STomi Valkeinen f_vco = f_vco >> 1;
39619757fc8STomi Valkeinen }
39719757fc8STomi Valkeinen
39819757fc8STomi Valkeinen /* VCO bounds check */
39919757fc8STomi Valkeinen if ((f_vco < pll->f_vco_min) || (f_vco > pll->f_vco_max))
40019757fc8STomi Valkeinen return -EINVAL;
40119757fc8STomi Valkeinen
40219757fc8STomi Valkeinen delta_best = 0xFFFFFFFF;
40319757fc8STomi Valkeinen *m = 0;
40419757fc8STomi Valkeinen *n = 0;
40519757fc8STomi Valkeinen *r = ar;
40619757fc8STomi Valkeinen
40719757fc8STomi Valkeinen am = pll->m_min;
40819757fc8STomi Valkeinen an = pll->n_min;
40919757fc8STomi Valkeinen
41019757fc8STomi Valkeinen while ((am <= pll->m_max) && (an <= pll->n_max)) {
41119757fc8STomi Valkeinen f_current = (pll->f_base * am) / an;
41219757fc8STomi Valkeinen delta_current = abs_diff (f_current, f_vco);
41319757fc8STomi Valkeinen
41419757fc8STomi Valkeinen if (delta_current < delta_best) {
41519757fc8STomi Valkeinen delta_best = delta_current;
41619757fc8STomi Valkeinen *m = am;
41719757fc8STomi Valkeinen *n = an;
41819757fc8STomi Valkeinen }
41919757fc8STomi Valkeinen
42019757fc8STomi Valkeinen if (f_current <= f_vco) {
42119757fc8STomi Valkeinen am ++;
42219757fc8STomi Valkeinen } else {
42319757fc8STomi Valkeinen an ++;
42419757fc8STomi Valkeinen }
42519757fc8STomi Valkeinen }
42619757fc8STomi Valkeinen
42719757fc8STomi Valkeinen f_current = (pll->f_base * *m) / *n;
42819757fc8STomi Valkeinen pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int) (f_current >> ar), (int) f_current);
42919757fc8STomi Valkeinen pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int) *m, (unsigned int) *n, (unsigned int) *r);
43019757fc8STomi Valkeinen return 0;
43119757fc8STomi Valkeinen }
43219757fc8STomi Valkeinen
43319757fc8STomi Valkeinen
43419757fc8STomi Valkeinen /* ------------------------------------------------------------------------- */
43519757fc8STomi Valkeinen
43619757fc8STomi Valkeinen
43719757fc8STomi Valkeinen /* Check CRT timing values */
svga_check_timings(const struct svga_timing_regs * tm,struct fb_var_screeninfo * var,int node)43819757fc8STomi Valkeinen int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node)
43919757fc8STomi Valkeinen {
44019757fc8STomi Valkeinen u32 value;
44119757fc8STomi Valkeinen
44219757fc8STomi Valkeinen var->xres = (var->xres+7)&~7;
44319757fc8STomi Valkeinen var->left_margin = (var->left_margin+7)&~7;
44419757fc8STomi Valkeinen var->right_margin = (var->right_margin+7)&~7;
44519757fc8STomi Valkeinen var->hsync_len = (var->hsync_len+7)&~7;
44619757fc8STomi Valkeinen
44719757fc8STomi Valkeinen /* Check horizontal total */
44819757fc8STomi Valkeinen value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
44919757fc8STomi Valkeinen if (((value / 8) - 5) >= svga_regset_size (tm->h_total_regs))
45019757fc8STomi Valkeinen return -EINVAL;
45119757fc8STomi Valkeinen
45219757fc8STomi Valkeinen /* Check horizontal display and blank start */
45319757fc8STomi Valkeinen value = var->xres;
45419757fc8STomi Valkeinen if (((value / 8) - 1) >= svga_regset_size (tm->h_display_regs))
45519757fc8STomi Valkeinen return -EINVAL;
45619757fc8STomi Valkeinen if (((value / 8) - 1) >= svga_regset_size (tm->h_blank_start_regs))
45719757fc8STomi Valkeinen return -EINVAL;
45819757fc8STomi Valkeinen
45919757fc8STomi Valkeinen /* Check horizontal sync start */
46019757fc8STomi Valkeinen value = var->xres + var->right_margin;
46119757fc8STomi Valkeinen if (((value / 8) - 1) >= svga_regset_size (tm->h_sync_start_regs))
46219757fc8STomi Valkeinen return -EINVAL;
46319757fc8STomi Valkeinen
46419757fc8STomi Valkeinen /* Check horizontal blank end (or length) */
46519757fc8STomi Valkeinen value = var->left_margin + var->right_margin + var->hsync_len;
46619757fc8STomi Valkeinen if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_blank_end_regs)))
46719757fc8STomi Valkeinen return -EINVAL;
46819757fc8STomi Valkeinen
46919757fc8STomi Valkeinen /* Check horizontal sync end (or length) */
47019757fc8STomi Valkeinen value = var->hsync_len;
47119757fc8STomi Valkeinen if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_sync_end_regs)))
47219757fc8STomi Valkeinen return -EINVAL;
47319757fc8STomi Valkeinen
47419757fc8STomi Valkeinen /* Check vertical total */
47519757fc8STomi Valkeinen value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
47619757fc8STomi Valkeinen if ((value - 1) >= svga_regset_size(tm->v_total_regs))
47719757fc8STomi Valkeinen return -EINVAL;
47819757fc8STomi Valkeinen
47919757fc8STomi Valkeinen /* Check vertical display and blank start */
48019757fc8STomi Valkeinen value = var->yres;
48119757fc8STomi Valkeinen if ((value - 1) >= svga_regset_size(tm->v_display_regs))
48219757fc8STomi Valkeinen return -EINVAL;
48319757fc8STomi Valkeinen if ((value - 1) >= svga_regset_size(tm->v_blank_start_regs))
48419757fc8STomi Valkeinen return -EINVAL;
48519757fc8STomi Valkeinen
48619757fc8STomi Valkeinen /* Check vertical sync start */
48719757fc8STomi Valkeinen value = var->yres + var->lower_margin;
48819757fc8STomi Valkeinen if ((value - 1) >= svga_regset_size(tm->v_sync_start_regs))
48919757fc8STomi Valkeinen return -EINVAL;
49019757fc8STomi Valkeinen
49119757fc8STomi Valkeinen /* Check vertical blank end (or length) */
49219757fc8STomi Valkeinen value = var->upper_margin + var->lower_margin + var->vsync_len;
49319757fc8STomi Valkeinen if ((value == 0) || (value >= svga_regset_size (tm->v_blank_end_regs)))
49419757fc8STomi Valkeinen return -EINVAL;
49519757fc8STomi Valkeinen
49619757fc8STomi Valkeinen /* Check vertical sync end (or length) */
49719757fc8STomi Valkeinen value = var->vsync_len;
49819757fc8STomi Valkeinen if ((value == 0) || (value >= svga_regset_size (tm->v_sync_end_regs)))
49919757fc8STomi Valkeinen return -EINVAL;
50019757fc8STomi Valkeinen
50119757fc8STomi Valkeinen return 0;
50219757fc8STomi Valkeinen }
50319757fc8STomi Valkeinen
50419757fc8STomi Valkeinen /* Set CRT timing registers */
svga_set_timings(void __iomem * regbase,const struct svga_timing_regs * tm,struct fb_var_screeninfo * var,u32 hmul,u32 hdiv,u32 vmul,u32 vdiv,u32 hborder,int node)50519757fc8STomi Valkeinen void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
50619757fc8STomi Valkeinen struct fb_var_screeninfo *var,
50719757fc8STomi Valkeinen u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
50819757fc8STomi Valkeinen {
50919757fc8STomi Valkeinen u8 regval;
51019757fc8STomi Valkeinen u32 value;
51119757fc8STomi Valkeinen
51219757fc8STomi Valkeinen value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
51319757fc8STomi Valkeinen value = (value * hmul) / hdiv;
51419757fc8STomi Valkeinen pr_debug("fb%d: horizontal total : %d\n", node, value);
51519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
51619757fc8STomi Valkeinen
51719757fc8STomi Valkeinen value = var->xres;
51819757fc8STomi Valkeinen value = (value * hmul) / hdiv;
51919757fc8STomi Valkeinen pr_debug("fb%d: horizontal display : %d\n", node, value);
52019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
52119757fc8STomi Valkeinen
52219757fc8STomi Valkeinen value = var->xres;
52319757fc8STomi Valkeinen value = (value * hmul) / hdiv;
52419757fc8STomi Valkeinen pr_debug("fb%d: horizontal blank start: %d\n", node, value);
52519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
52619757fc8STomi Valkeinen
52719757fc8STomi Valkeinen value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
52819757fc8STomi Valkeinen value = (value * hmul) / hdiv;
52919757fc8STomi Valkeinen pr_debug("fb%d: horizontal blank end : %d\n", node, value);
53019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
53119757fc8STomi Valkeinen
53219757fc8STomi Valkeinen value = var->xres + var->right_margin;
53319757fc8STomi Valkeinen value = (value * hmul) / hdiv;
53419757fc8STomi Valkeinen pr_debug("fb%d: horizontal sync start : %d\n", node, value);
53519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
53619757fc8STomi Valkeinen
53719757fc8STomi Valkeinen value = var->xres + var->right_margin + var->hsync_len;
53819757fc8STomi Valkeinen value = (value * hmul) / hdiv;
53919757fc8STomi Valkeinen pr_debug("fb%d: horizontal sync end : %d\n", node, value);
54019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
54119757fc8STomi Valkeinen
54219757fc8STomi Valkeinen value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
54319757fc8STomi Valkeinen value = (value * vmul) / vdiv;
54419757fc8STomi Valkeinen pr_debug("fb%d: vertical total : %d\n", node, value);
54519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
54619757fc8STomi Valkeinen
54719757fc8STomi Valkeinen value = var->yres;
54819757fc8STomi Valkeinen value = (value * vmul) / vdiv;
54919757fc8STomi Valkeinen pr_debug("fb%d: vertical display : %d\n", node, value);
55019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
55119757fc8STomi Valkeinen
55219757fc8STomi Valkeinen value = var->yres;
55319757fc8STomi Valkeinen value = (value * vmul) / vdiv;
55419757fc8STomi Valkeinen pr_debug("fb%d: vertical blank start : %d\n", node, value);
55519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
55619757fc8STomi Valkeinen
55719757fc8STomi Valkeinen value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
55819757fc8STomi Valkeinen value = (value * vmul) / vdiv;
55919757fc8STomi Valkeinen pr_debug("fb%d: vertical blank end : %d\n", node, value);
56019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
56119757fc8STomi Valkeinen
56219757fc8STomi Valkeinen value = var->yres + var->lower_margin;
56319757fc8STomi Valkeinen value = (value * vmul) / vdiv;
56419757fc8STomi Valkeinen pr_debug("fb%d: vertical sync start : %d\n", node, value);
56519757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
56619757fc8STomi Valkeinen
56719757fc8STomi Valkeinen value = var->yres + var->lower_margin + var->vsync_len;
56819757fc8STomi Valkeinen value = (value * vmul) / vdiv;
56919757fc8STomi Valkeinen pr_debug("fb%d: vertical sync end : %d\n", node, value);
57019757fc8STomi Valkeinen svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
57119757fc8STomi Valkeinen
57219757fc8STomi Valkeinen /* Set horizontal and vertical sync pulse polarity in misc register */
57319757fc8STomi Valkeinen
57419757fc8STomi Valkeinen regval = vga_r(regbase, VGA_MIS_R);
57519757fc8STomi Valkeinen if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
57619757fc8STomi Valkeinen pr_debug("fb%d: positive horizontal sync\n", node);
57719757fc8STomi Valkeinen regval = regval & ~0x80;
57819757fc8STomi Valkeinen } else {
57919757fc8STomi Valkeinen pr_debug("fb%d: negative horizontal sync\n", node);
58019757fc8STomi Valkeinen regval = regval | 0x80;
58119757fc8STomi Valkeinen }
58219757fc8STomi Valkeinen if (var->sync & FB_SYNC_VERT_HIGH_ACT) {
58319757fc8STomi Valkeinen pr_debug("fb%d: positive vertical sync\n", node);
58419757fc8STomi Valkeinen regval = regval & ~0x40;
58519757fc8STomi Valkeinen } else {
58619757fc8STomi Valkeinen pr_debug("fb%d: negative vertical sync\n\n", node);
58719757fc8STomi Valkeinen regval = regval | 0x40;
58819757fc8STomi Valkeinen }
58919757fc8STomi Valkeinen vga_w(regbase, VGA_MIS_W, regval);
59019757fc8STomi Valkeinen }
59119757fc8STomi Valkeinen
59219757fc8STomi Valkeinen
59319757fc8STomi Valkeinen /* ------------------------------------------------------------------------- */
59419757fc8STomi Valkeinen
59519757fc8STomi Valkeinen
match_format(const struct svga_fb_format * frm,struct fb_var_screeninfo * var)59619757fc8STomi Valkeinen static inline int match_format(const struct svga_fb_format *frm,
59719757fc8STomi Valkeinen struct fb_var_screeninfo *var)
59819757fc8STomi Valkeinen {
59919757fc8STomi Valkeinen int i = 0;
60019757fc8STomi Valkeinen int stored = -EINVAL;
60119757fc8STomi Valkeinen
60219757fc8STomi Valkeinen while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
60319757fc8STomi Valkeinen {
60419757fc8STomi Valkeinen if ((var->bits_per_pixel == frm->bits_per_pixel) &&
60519757fc8STomi Valkeinen (var->red.length <= frm->red.length) &&
60619757fc8STomi Valkeinen (var->green.length <= frm->green.length) &&
60719757fc8STomi Valkeinen (var->blue.length <= frm->blue.length) &&
60819757fc8STomi Valkeinen (var->transp.length <= frm->transp.length) &&
60919757fc8STomi Valkeinen (var->nonstd == frm->nonstd))
61019757fc8STomi Valkeinen return i;
61119757fc8STomi Valkeinen if (var->bits_per_pixel == frm->bits_per_pixel)
61219757fc8STomi Valkeinen stored = i;
61319757fc8STomi Valkeinen i++;
61419757fc8STomi Valkeinen frm++;
61519757fc8STomi Valkeinen }
61619757fc8STomi Valkeinen return stored;
61719757fc8STomi Valkeinen }
61819757fc8STomi Valkeinen
svga_match_format(const struct svga_fb_format * frm,struct fb_var_screeninfo * var,struct fb_fix_screeninfo * fix)61919757fc8STomi Valkeinen int svga_match_format(const struct svga_fb_format *frm,
62019757fc8STomi Valkeinen struct fb_var_screeninfo *var,
62119757fc8STomi Valkeinen struct fb_fix_screeninfo *fix)
62219757fc8STomi Valkeinen {
62319757fc8STomi Valkeinen int i = match_format(frm, var);
62419757fc8STomi Valkeinen
62519757fc8STomi Valkeinen if (i >= 0) {
62619757fc8STomi Valkeinen var->bits_per_pixel = frm[i].bits_per_pixel;
62719757fc8STomi Valkeinen var->red = frm[i].red;
62819757fc8STomi Valkeinen var->green = frm[i].green;
62919757fc8STomi Valkeinen var->blue = frm[i].blue;
63019757fc8STomi Valkeinen var->transp = frm[i].transp;
63119757fc8STomi Valkeinen var->nonstd = frm[i].nonstd;
63219757fc8STomi Valkeinen if (fix != NULL) {
63319757fc8STomi Valkeinen fix->type = frm[i].type;
63419757fc8STomi Valkeinen fix->type_aux = frm[i].type_aux;
63519757fc8STomi Valkeinen fix->visual = frm[i].visual;
63619757fc8STomi Valkeinen fix->xpanstep = frm[i].xpanstep;
63719757fc8STomi Valkeinen }
63819757fc8STomi Valkeinen }
63919757fc8STomi Valkeinen
64019757fc8STomi Valkeinen return i;
64119757fc8STomi Valkeinen }
64219757fc8STomi Valkeinen
64319757fc8STomi Valkeinen
64419757fc8STomi Valkeinen EXPORT_SYMBOL(svga_wcrt_multi);
64519757fc8STomi Valkeinen EXPORT_SYMBOL(svga_wseq_multi);
64619757fc8STomi Valkeinen
64719757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_default_gfx_regs);
64819757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_default_atc_regs);
64919757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_default_seq_regs);
65019757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_default_crt_regs);
65119757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_textmode_vga_regs);
65219757fc8STomi Valkeinen
65319757fc8STomi Valkeinen EXPORT_SYMBOL(svga_settile);
65419757fc8STomi Valkeinen EXPORT_SYMBOL(svga_tilecopy);
65519757fc8STomi Valkeinen EXPORT_SYMBOL(svga_tilefill);
65619757fc8STomi Valkeinen EXPORT_SYMBOL(svga_tileblit);
65719757fc8STomi Valkeinen EXPORT_SYMBOL(svga_tilecursor);
65819757fc8STomi Valkeinen EXPORT_SYMBOL(svga_get_tilemax);
65919757fc8STomi Valkeinen
66019757fc8STomi Valkeinen EXPORT_SYMBOL(svga_compute_pll);
66119757fc8STomi Valkeinen EXPORT_SYMBOL(svga_check_timings);
66219757fc8STomi Valkeinen EXPORT_SYMBOL(svga_set_timings);
66319757fc8STomi Valkeinen EXPORT_SYMBOL(svga_match_format);
66419757fc8STomi Valkeinen
66519757fc8STomi Valkeinen MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>");
66619757fc8STomi Valkeinen MODULE_DESCRIPTION("Common utility functions for VGA-based graphics cards");
66719757fc8STomi Valkeinen MODULE_LICENSE("GPL");
668