1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org) 7 * 8 * This will eventually go into the qemu firmware. 9 */ 10#include <linux/init.h> 11#include <linux/screen_info.h> 12#include <linux/tty.h> 13#include <asm/io.h> 14#include <video/vga.h> 15 16/* 17 * This will eventually be done by the firmware; right now Linux assumes to 18 * run on the uninitialized hardware. 19 */ 20#undef LOAD_VGA_FONT 21 22static unsigned char sr[8] __initdata = { /* Sequencer */ 23 0x03, 0x00, 0x03, 0x04, 0x02, 0x00, 0x00, 0x00 24}; 25 26static unsigned char gr[16] __initdata= { /* Graphics Controller */ 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 28 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 29}; 30 31static unsigned char ar[21] __initdata= { /* Attribute Controller */ 32 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 33 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 34 0x0c, 0x01, 0x07, 0x13, 0x00 35}; 36 37static unsigned char cr[32] __initdata= { /* CRT Controller */ 38 0x91, 0x4f, 0x4f, 0x95, 0x57, 0x4f, 0xc0, 0x1f, 39 0x00, 0x4f, 0x0d, 0x0e, 0x02, 0x30, 0x09, 0xb0, 40 0x90, 0x83, 0x8f, 0x28, 0x1f, 0x8f, 0xc1, 0xa3, 41 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 42}; 43 44static struct rgb { 45 unsigned char r; 46 unsigned char g; 47 unsigned char b; 48} palette[16] __initdata= { 49 [ 0] = {0x00, 0x00, 0x00}, 50 [ 1] = {0x00, 0x00, 0x2a}, 51 [ 2] = {0x00, 0x2a, 0x00}, 52 [ 3] = {0x00, 0x2a, 0x2a}, 53 [ 4] = {0x2a, 0x00, 0x00}, 54 [ 5] = {0x2a, 0x00, 0x2a}, 55 [ 6] = {0x2a, 0x15, 0x00}, 56 [ 7] = {0x2a, 0x2a, 0x2a}, 57 [ 8] = {0x15, 0x15, 0x15}, 58 [ 9] = {0x15, 0x15, 0x3f}, 59 [10] = {0x15, 0x3f, 0x15}, 60 [11] = {0x15, 0x3f, 0x3f}, 61 [12] = {0x3f, 0x15, 0x15}, 62 [13] = {0x3f, 0x15, 0x3f}, 63 [14] = {0x3f, 0x3f, 0x15}, 64 [15] = {0x3f, 0x3f, 0x3f} 65 66}; 67 68void __init qvga_init_ibm(void) 69{ 70 int i; 71 72 for (i = 0; i < 8; i++) { /* Sequencer registers */ 73 outb(i, 0x3c4); 74 outb(sr[i], 0x3c5); 75 } 76 77 for (i = 0; i < 16; i++) { /* Graphics Controller registers */ 78 outb(i, 0x3ce); 79 outb(gr[i], 0x3cf); 80 } 81 82 for (i = 0; i < 21; i++) { /* Attribute Controller registers */ 83 outb(i, 0x3c0); 84 outb(ar[i], 0x3c1); 85 } 86 outb(0x20, 0x3c0); /* enable bit in *index* register */ 87 88 for (i = 0; i < 32; i++) { /* CRT Controller registers */ 89 outb(i, 0x3d4); 90 outb(cr[i], 0x3d5); 91 } 92 93 for (i = 0; i < 16; i++) { /* palette */ 94 outb(i, 0x3c8); 95 outb(palette[i].r, 0x3c9); 96 outb(palette[i].g, 0x3c9); 97 outb(palette[i].b, 0x3c9); 98 } 99 100 for (i = 0; i < 0x20000; i += 2) 101 *(volatile unsigned short *) (0xb00a0000 + i) = 0xaaaa; 102} 103 104#ifdef LOAD_VGA_FONT 105#include "/home/ralf/src/qemu/qemu-mips/vgafont.h" 106 107static void __init 108qvga_load_font(unsigned char *def, unsigned int c) 109{ 110 volatile void *w = (volatile void *) 0xb00a0000; 111 112 vga_wseq(NULL, 0, 1); 113 vga_wseq(NULL, 2, 4); 114 vga_wseq(NULL, 4, 7); 115 vga_wseq(NULL, 0, 3); 116 vga_wgfx(NULL, 4, 2); 117 vga_wgfx(NULL, 5, 0); 118 vga_wgfx(NULL, 6, 0); 119 120 memcpy(w, def, c); 121 122 vga_wseq(NULL, 0, 1); 123 vga_wseq(NULL, 2, 3); 124 vga_wseq(NULL, 4, 3); 125 vga_wseq(NULL, 0, 3); 126 vga_wgfx(NULL, 4, 0); 127 vga_wgfx(NULL, 5, 0x10); 128 vga_wgfx(NULL, 6, 0xe); 129} 130#endif 131 132void __init qvga_init(void) 133{ 134 struct screen_info *si = &screen_info; 135 unsigned int h; 136 int i; 137 138#ifdef LOAD_VGA_FONT 139 qvga_load_font(vgafont16, 4096); 140#endif 141 142 vga_wgfx(NULL, 5, 0x10); /* Set odd/even mode */ 143 vga_wgfx(NULL, 6, 0x0c); /* map to offset 0xb8000, text mode */ 144 vga_wseq(NULL, 2, 3); /* Planes 0 & 1 */ 145 vga_wseq(NULL, 3, 4); /* Font offset */ 146 outb(1, VGA_MIS_W); /* set msr to MSR_COLOR_EMULATION */ 147 vga_wcrt(NULL, 1, 79); /* 80 columns */ 148 vga_wcrt(NULL, 9, 15); /* 16 pixels per character */ 149 vga_wcrt(NULL, 0x0c, 0); /* start address high 8 bit */ 150 vga_wcrt(NULL, 0x0d, 0); /* start address low 8 bit */ 151 vga_wcrt(NULL, 0x13, 0x28); /* line offset */ 152 vga_wcrt(NULL, 0x07, 0x1f); /* line compare bit 8 */ 153 vga_wcrt(NULL, 0x09, 0x4f); /* line compare bit 9 */ 154 vga_wcrt(NULL, 0x18, 0xff); /* line compare low 8 bit */ 155 156 h = (25 * 16); 157 vga_wcrt(NULL, 0x12, h); 158 159 outb(7, 0x3d4); 160 outb((inb(0x3d5) & ~0x42) | ((h >> 7) & 2) | ((h >> 3) & 0x40), 0x3d5); 161 162 for (i = 0; i < 21; i++) /* Attribute Controller */ 163 vga_wattr(NULL, i, ar[i]); 164 outb(0x20, 0x3c0); /* Set bit 5 in Attribute Controller */ 165 /* index ... VGA is so stupid I want */ 166 /* to cry all day ... */ 167 outb(0, VGA_PEL_IW); 168 for (i = 0; i < 16; i++) { /* palette */ 169 outb(palette[i].r, VGA_PEL_D); 170 outb(palette[i].g, VGA_PEL_D); 171 outb(palette[i].b, VGA_PEL_D); 172 } 173 174 si->orig_x = 0; /* Cursor x position */ 175 si->orig_y = 0; /* Cursor y position */ 176 si->orig_video_cols = 80; /* Columns */ 177 si->orig_video_lines = 25; /* Lines */ 178 si->orig_video_isVGA = VIDEO_TYPE_VGAC; /* Card type */ 179 si->orig_video_points = 16; 180 181} 182