0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/string.h>
0013 #include <linux/fb.h>
0014 #include <linux/vt_kern.h>
0015 #include <linux/console.h>
0016 #include <asm/types.h>
0017 #include "fbcon.h"
0018
0019 static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
0020 int sx, int dy, int dx, int height, int width)
0021 {
0022 struct fb_tilearea area;
0023
0024 area.sx = sx;
0025 area.sy = sy;
0026 area.dx = dx;
0027 area.dy = dy;
0028 area.height = height;
0029 area.width = width;
0030
0031 info->tileops->fb_tilecopy(info, &area);
0032 }
0033
0034 static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
0035 int sx, int height, int width)
0036 {
0037 struct fb_tilerect rect;
0038 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
0039 int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
0040
0041 rect.index = vc->vc_video_erase_char &
0042 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
0043 rect.fg = attr_fgcol_ec(fgshift, vc, info);
0044 rect.bg = attr_bgcol_ec(bgshift, vc, info);
0045 rect.sx = sx;
0046 rect.sy = sy;
0047 rect.width = width;
0048 rect.height = height;
0049 rect.rop = ROP_COPY;
0050
0051 info->tileops->fb_tilefill(info, &rect);
0052 }
0053
0054 static void tile_putcs(struct vc_data *vc, struct fb_info *info,
0055 const unsigned short *s, int count, int yy, int xx,
0056 int fg, int bg)
0057 {
0058 struct fb_tileblit blit;
0059 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
0060 int size = sizeof(u32) * count, i;
0061
0062 blit.sx = xx;
0063 blit.sy = yy;
0064 blit.width = count;
0065 blit.height = 1;
0066 blit.fg = fg;
0067 blit.bg = bg;
0068 blit.length = count;
0069 blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
0070 for (i = 0; i < count; i++)
0071 blit.indices[i] = (u32)(scr_readw(s++) & charmask);
0072
0073 info->tileops->fb_tileblit(info, &blit);
0074 }
0075
0076 static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
0077 int color, int bottom_only)
0078 {
0079 return;
0080 }
0081
0082 static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
0083 int fg, int bg)
0084 {
0085 struct fb_tilecursor cursor;
0086 int use_sw = vc->vc_cursor_type & CUR_SW;
0087
0088 cursor.sx = vc->state.x;
0089 cursor.sy = vc->state.y;
0090 cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
0091 cursor.fg = fg;
0092 cursor.bg = bg;
0093
0094 switch (vc->vc_cursor_type & 0x0f) {
0095 case CUR_NONE:
0096 cursor.shape = FB_TILE_CURSOR_NONE;
0097 break;
0098 case CUR_UNDERLINE:
0099 cursor.shape = FB_TILE_CURSOR_UNDERLINE;
0100 break;
0101 case CUR_LOWER_THIRD:
0102 cursor.shape = FB_TILE_CURSOR_LOWER_THIRD;
0103 break;
0104 case CUR_LOWER_HALF:
0105 cursor.shape = FB_TILE_CURSOR_LOWER_HALF;
0106 break;
0107 case CUR_TWO_THIRDS:
0108 cursor.shape = FB_TILE_CURSOR_TWO_THIRDS;
0109 break;
0110 case CUR_BLOCK:
0111 default:
0112 cursor.shape = FB_TILE_CURSOR_BLOCK;
0113 break;
0114 }
0115
0116 info->tileops->fb_tilecursor(info, &cursor);
0117 }
0118
0119 static int tile_update_start(struct fb_info *info)
0120 {
0121 struct fbcon_ops *ops = info->fbcon_par;
0122 int err;
0123
0124 err = fb_pan_display(info, &ops->var);
0125 ops->var.xoffset = info->var.xoffset;
0126 ops->var.yoffset = info->var.yoffset;
0127 ops->var.vmode = info->var.vmode;
0128 return err;
0129 }
0130
0131 void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
0132 {
0133 struct fb_tilemap map;
0134 struct fbcon_ops *ops = info->fbcon_par;
0135
0136 ops->bmove = tile_bmove;
0137 ops->clear = tile_clear;
0138 ops->putcs = tile_putcs;
0139 ops->clear_margins = tile_clear_margins;
0140 ops->cursor = tile_cursor;
0141 ops->update_start = tile_update_start;
0142
0143 if (ops->p) {
0144 map.width = vc->vc_font.width;
0145 map.height = vc->vc_font.height;
0146 map.depth = 1;
0147 map.length = vc->vc_font.charcount;
0148 map.data = ops->p->fontdata;
0149 info->tileops->fb_settile(info, &map);
0150 }
0151 }