[PATCH] fbcon: fix scrollback with logo issue immediately after boot
[linux-2.6] / drivers / video / console / tileblit.c
1 /*
2  *  linux/drivers/video/console/tileblit.c -- Tile Blitting Operation
3  *
4  *      Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
5  *
6  *  This file is subject to the terms and conditions of the GNU General Public
7  *  License.  See the file COPYING in the main directory of this archive for
8  *  more details.
9  */
10
11 #include <linux/config.h>
12 #include <linux/module.h>
13 #include <linux/string.h>
14 #include <linux/fb.h>
15 #include <linux/vt_kern.h>
16 #include <linux/console.h>
17 #include <asm/types.h>
18 #include "fbcon.h"
19
20 static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
21                        int sx, int dy, int dx, int height, int width)
22 {
23         struct fb_tilearea area;
24
25         area.sx = sx;
26         area.sy = sy;
27         area.dx = dx;
28         area.dy = dy;
29         area.height = height;
30         area.width = width;
31
32         info->tileops->fb_tilecopy(info, &area);
33 }
34
35 static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
36                        int sx, int height, int width)
37 {
38         struct fb_tilerect rect;
39         int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
40         int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
41
42         rect.index = vc->vc_video_erase_char &
43                 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
44         rect.fg = attr_fgcol_ec(fgshift, vc);
45         rect.bg = attr_bgcol_ec(bgshift, vc);
46         rect.sx = sx;
47         rect.sy = sy;
48         rect.width = width;
49         rect.height = height;
50         rect.rop = ROP_COPY;
51
52         info->tileops->fb_tilefill(info, &rect);
53 }
54
55 static void tile_putcs(struct vc_data *vc, struct fb_info *info,
56                        const unsigned short *s, int count, int yy, int xx,
57                        int fg, int bg)
58 {
59         struct fb_tileblit blit;
60         unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
61         int size = sizeof(u32) * count, i;
62
63         blit.sx = xx;
64         blit.sy = yy;
65         blit.width = count;
66         blit.height = 1;
67         blit.fg = fg;
68         blit.bg = bg;
69         blit.length = count;
70         blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
71         for (i = 0; i < count; i++)
72                 blit.indices[i] = (u32)(scr_readw(s++) & charmask);
73
74         info->tileops->fb_tileblit(info, &blit);
75 }
76
77 static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
78                                int bottom_only)
79 {
80         return;
81 }
82
83 static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
84                         int softback_lines, int fg, int bg)
85 {
86         struct fb_tilecursor cursor;
87         int use_sw = (vc->vc_cursor_type & 0x01);
88
89         cursor.sx = vc->vc_x;
90         cursor.sy = vc->vc_y;
91         cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
92         cursor.fg = fg;
93         cursor.bg = bg;
94
95         switch (vc->vc_cursor_type & 0x0f) {
96         case CUR_NONE:
97                 cursor.shape = FB_TILE_CURSOR_NONE;
98                 break;
99         case CUR_UNDERLINE:
100                 cursor.shape = FB_TILE_CURSOR_UNDERLINE;
101                 break;
102         case CUR_LOWER_THIRD:
103                 cursor.shape = FB_TILE_CURSOR_LOWER_THIRD;
104                 break;
105         case CUR_LOWER_HALF:
106                 cursor.shape = FB_TILE_CURSOR_LOWER_HALF;
107                 break;
108         case CUR_TWO_THIRDS:
109                 cursor.shape = FB_TILE_CURSOR_TWO_THIRDS;
110                 break;
111         case CUR_BLOCK:
112         default:
113                 cursor.shape = FB_TILE_CURSOR_BLOCK;
114                 break;
115         }
116
117         info->tileops->fb_tilecursor(info, &cursor);
118 }
119
120 static int tile_update_start(struct fb_info *info)
121 {
122         struct fbcon_ops *ops = info->fbcon_par;
123         int err;
124
125         err = fb_pan_display(info, &ops->var);
126         ops->var.xoffset = info->var.xoffset;
127         ops->var.yoffset = info->var.yoffset;
128         ops->var.vmode = info->var.vmode;
129         return err;
130 }
131
132 void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
133 {
134         struct fb_tilemap map;
135         struct fbcon_ops *ops = info->fbcon_par;
136
137         ops->bmove = tile_bmove;
138         ops->clear = tile_clear;
139         ops->putcs = tile_putcs;
140         ops->clear_margins = tile_clear_margins;
141         ops->cursor = tile_cursor;
142         ops->update_start = tile_update_start;
143
144         if (ops->p) {
145                 map.width = vc->vc_font.width;
146                 map.height = vc->vc_font.height;
147                 map.depth = 1;
148                 map.length = (ops->p->userfont) ?
149                         FNTCHARCNT(ops->p->fontdata) : 256;
150                 map.data = ops->p->fontdata;
151                 info->tileops->fb_settile(info, &map);
152         }
153 }
154
155 EXPORT_SYMBOL(fbcon_set_tileops);
156
157 MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
158 MODULE_DESCRIPTION("Tile Blitting Operation");
159 MODULE_LICENSE("GPL");
160