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/module.h> 12 #include <linux/string.h> 13 #include <linux/fb.h> 14 #include <linux/vt_kern.h> 15 #include <linux/console.h> 16 #include <asm/types.h> 17 #include "fbcon.h" 18 19 static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy, 20 int sx, int dy, int dx, int height, int width) 21 { 22 struct fb_tilearea area; 23 24 area.sx = sx; 25 area.sy = sy; 26 area.dx = dx; 27 area.dy = dy; 28 area.height = height; 29 area.width = width; 30 31 info->tileops->fb_tilecopy(info, &area); 32 } 33 34 static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy, 35 int sx, int height, int width) 36 { 37 struct fb_tilerect rect; 38 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 39 int fgshift = (vc->vc_hi_font_mask) ? 9 : 8; 40 41 rect.index = vc->vc_video_erase_char & 42 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); 43 rect.fg = attr_fgcol_ec(fgshift, vc, info); 44 rect.bg = attr_bgcol_ec(bgshift, vc, info); 45 rect.sx = sx; 46 rect.sy = sy; 47 rect.width = width; 48 rect.height = height; 49 rect.rop = ROP_COPY; 50 51 info->tileops->fb_tilefill(info, &rect); 52 } 53 54 static void tile_putcs(struct vc_data *vc, struct fb_info *info, 55 const unsigned short *s, int count, int yy, int xx, 56 int fg, int bg) 57 { 58 struct fb_tileblit blit; 59 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 60 int size = sizeof(u32) * count, i; 61 62 blit.sx = xx; 63 blit.sy = yy; 64 blit.width = count; 65 blit.height = 1; 66 blit.fg = fg; 67 blit.bg = bg; 68 blit.length = count; 69 blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size); 70 for (i = 0; i < count; i++) 71 blit.indices[i] = (u32)(scr_readw(s++) & charmask); 72 73 info->tileops->fb_tileblit(info, &blit); 74 } 75 76 static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, 77 int color, int bottom_only) 78 { 79 return; 80 } 81 82 static void tile_cursor(struct vc_data *vc, struct fb_info *info, bool enable, 83 int fg, int bg) 84 { 85 struct fb_tilecursor cursor; 86 int use_sw = vc->vc_cursor_type & CUR_SW; 87 88 cursor.sx = vc->state.x; 89 cursor.sy = vc->state.y; 90 cursor.mode = enable && !use_sw; 91 cursor.fg = fg; 92 cursor.bg = bg; 93 94 switch (vc->vc_cursor_type & 0x0f) { 95 case CUR_NONE: 96 cursor.shape = FB_TILE_CURSOR_NONE; 97 break; 98 case CUR_UNDERLINE: 99 cursor.shape = FB_TILE_CURSOR_UNDERLINE; 100 break; 101 case CUR_LOWER_THIRD: 102 cursor.shape = FB_TILE_CURSOR_LOWER_THIRD; 103 break; 104 case CUR_LOWER_HALF: 105 cursor.shape = FB_TILE_CURSOR_LOWER_HALF; 106 break; 107 case CUR_TWO_THIRDS: 108 cursor.shape = FB_TILE_CURSOR_TWO_THIRDS; 109 break; 110 case CUR_BLOCK: 111 default: 112 cursor.shape = FB_TILE_CURSOR_BLOCK; 113 break; 114 } 115 116 info->tileops->fb_tilecursor(info, &cursor); 117 } 118 119 static int tile_update_start(struct fb_info *info) 120 { 121 struct fbcon_ops *ops = info->fbcon_par; 122 int err; 123 124 err = fb_pan_display(info, &ops->var); 125 ops->var.xoffset = info->var.xoffset; 126 ops->var.yoffset = info->var.yoffset; 127 ops->var.vmode = info->var.vmode; 128 return err; 129 } 130 131 void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info) 132 { 133 struct fb_tilemap map; 134 struct fbcon_ops *ops = info->fbcon_par; 135 136 ops->bmove = tile_bmove; 137 ops->clear = tile_clear; 138 ops->putcs = tile_putcs; 139 ops->clear_margins = tile_clear_margins; 140 ops->cursor = tile_cursor; 141 ops->update_start = tile_update_start; 142 143 if (ops->p) { 144 map.width = vc->vc_font.width; 145 map.height = vc->vc_font.height; 146 map.depth = 1; 147 map.length = vc->vc_font.charcount; 148 map.data = ops->p->fontdata; 149 info->tileops->fb_settile(info, &map); 150 } 151 } 152