13 #include <linux/kernel.h>
14 #include <linux/errno.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
24 #include <asm/uaccess.h>
26 #include <asm/pgtable.h>
34 #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
37 #define REFCOUNT(fd) (((int *)(fd))[-1])
38 #define FNTSIZE(fd) (((int *)(fd))[-2])
39 #define FNTCHARCNT(fd) (((int *)(fd))[-3])
40 #define FONT_EXTRA_WORDS 3
46 static int logo_active;
48 static int xcurs_correction = 29;
49 static int newport_xsize;
50 static int newport_ysize;
51 static int newport_has_init;
55 #define BMASK(c) (c << 24)
57 #define RENDER(regs, cp) do { \
58 (regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
59 (regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
60 (regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
61 (regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
62 (regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
63 (regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
64 (regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
65 (regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
68 #define TESTVAL 0xdeadbeef
69 #define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
71 static inline void newport_render_background(
int xstart,
int ystart,
72 int xend,
int yend,
int ci)
75 npregs->
set.wrmask = 0xffffffff;
79 npregs->
set.colori = ci;
80 npregs->
set.xystarti =
81 (xstart << 16) | ((ystart + topscan) & 0x3ff);
83 ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
86 static inline void newport_init_cmap(
void)
90 for (i = 0; i < 16; i++) {
91 newport_bfwait(npregs);
93 newport_cmap_setrgb(npregs,
99 static const struct linux_logo *newport_show_logo(
void)
101 #ifdef CONFIG_LOGO_SGI_CLUT224
103 const unsigned char *
clut;
104 const unsigned char *
data;
112 for (i = 0; i < logo->
clutsize; i++) {
113 newport_bfwait(npregs);
114 newport_cmap_setaddr(npregs, i + 0x20);
115 newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
119 newport_wait(npregs);
123 npregs->
set.xystarti = ((newport_xsize - logo->
width) << 16) | (0);
124 npregs->
set.xyendi = ((newport_xsize - 1) << 16);
125 newport_wait(npregs);
128 npregs->
go.hostrw0 = *data++ << 24;
134 static inline void newport_clear_screen(
int xstart,
int ystart,
int xend,
140 newport_wait(npregs);
141 npregs->
set.wrmask = 0xffffffff;
145 npregs->
set.colori = ci;
146 npregs->
set.xystarti = (xstart << 16) | ystart;
147 npregs->
go.xyendi = (xend << 16) | yend;
150 static inline void newport_clear_lines(
int ystart,
int yend,
int ci)
152 ystart = ((ystart << 4) + topscan) & 0x3ff;
153 yend = ((yend << 4) + topscan + 15) & 0x3ff;
154 newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
157 static void newport_reset(
void)
162 newport_wait(npregs);
171 for (i = 0; i < 128; i++) {
172 newport_bfwait(npregs);
173 if (i == 92 || i == 94)
174 npregs->
set.dcbdata0.byshort.s1 = 0xff00;
176 npregs->
set.dcbdata0.byshort.s1 = 0x0000;
190 npregs->
cset.topscan = 0x3ff;
191 npregs->
cset.xywin = (4096 << 16) | 4096;
194 newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
201 static void newport_get_screensize(
void)
204 unsigned short ventry, treg;
205 unsigned short linetable[128];
211 for (i = 0; i < 128; i++) {
212 newport_bfwait(npregs);
213 linetable[
i] = npregs->
set.dcbdata0.byshort.s1;
216 newport_xsize = newport_ysize = 0;
217 for (i = 0; i <
ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) {
223 newport_bfwait(npregs);
224 treg = npregs->
set.dcbdata0.byshort.s1;
226 cols += (treg >> 7) & 0xfe;
227 if ((treg & 0x80) == 0) {
228 newport_bfwait(npregs);
229 treg = npregs->
set.dcbdata0.byshort.s1;
231 }
while ((treg & 0x8000) == 0);
233 if (cols > newport_xsize)
234 newport_xsize =
cols;
235 newport_ysize += linetable[i + 1];
238 printk(
"NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
241 static void newport_get_revisions(
void)
244 unsigned int board_rev;
245 unsigned int rex3_rev;
246 unsigned int vc2_rev;
247 unsigned int cmap_rev;
248 unsigned int xmap9_rev;
249 unsigned int bt445_rev;
250 unsigned int bitplanes;
256 tmp = npregs->
set.dcbdata0.bybytes.b3;
258 board_rev = (tmp >> 4) & 7;
259 bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
263 tmp = npregs->
set.dcbdata0.bybytes.b3;
264 if ((tmp & 7) < cmap_rev)
265 cmap_rev = (tmp & 7);
271 xmap9_rev = npregs->
set.dcbdata0.bybytes.b3 & 7;
278 bt445_rev = (npregs->
set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
280 #define L(a) (char)('A'+(a))
282 (
"NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
283 board_rev, bitplanes,
L(rex3_rev),
L(vc2_rev),
L(xmap9_rev),
284 L(cmap_rev ? (cmap_rev + 1) : 0),
L(bt445_rev));
288 xcurs_correction = 21;
291 static void newport_exit(
void)
297 newport_set_def_font(i,
NULL);
301 static const char *newport_startup(
void)
307 if (newport_wait(npregs))
318 newport_get_revisions();
319 newport_get_screensize();
320 newport_has_init = 1;
322 return "SGI Newport";
330 vc->
vc_cols = newport_xsize / 8;
331 vc->
vc_rows = newport_ysize / 16;
335 static void newport_deinit(
struct vc_data *
c)
339 newport_has_init = 0;
346 int xend = ((sx +
width) << 3) - 1;
347 int ystart = ((sy << 4) + topscan) & 0x3ff;
348 int yend = (((sy +
height) << 4) + topscan - 1) & 0x3ff;
354 newport_clear_screen(sx << 3, ystart, xend, yend,
357 newport_clear_screen(sx << 3, ystart, xend, 1023,
359 newport_clear_screen(sx << 3, 0, xend, yend,
364 static void newport_putc(
struct vc_data *vc,
int charattr,
int ypos,
369 p = &font_data[vc->
vc_num][(charattr & 0xff) << 4];
370 charattr = (charattr >> 8) & 0xff;
374 newport_render_background(xpos, ypos, xpos, ypos,
375 (charattr & 0xf0) >> 4);
378 newport_wait(npregs);
379 npregs->
set.colori = charattr & 0xf;
385 npregs->
set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
386 npregs->
set.xyendi = ((xpos + 7) << 16);
387 newport_wait(npregs);
393 static void newport_putcs(
struct vc_data *vc,
const unsigned short *
s,
394 int count,
int ypos,
int xpos)
407 newport_render_background(xpos, ypos,
408 xpos + ((count - 1) << 3), ypos,
409 (charattr & 0xf0) >> 4);
411 newport_wait(npregs);
414 npregs->
set.colori = charattr & 0xf;
419 for (i = 0; i <
count; i++, xpos += 8) {
422 newport_wait(npregs);
425 npregs->
set.xystarti =
426 (xpos << 16) | ((ypos + topscan) & 0x3ff);
427 npregs->
set.xyendi = ((xpos + 7) << 16);
434 static void newport_cursor(
struct vc_data *vc,
int mode)
452 ycurs = ((xcurs / vc->
vc_cols) << 4) + 31;
453 xcurs = ((xcurs % vc->
vc_cols) << 3) + xcurs_correction;
459 static int newport_switch(
struct vc_data *vc)
461 static int logo_drawn = 0;
464 npregs->
cset.topscan = 0x3ff;
467 if (newport_show_logo()) {
476 static int newport_blank(
struct vc_data *c,
int blank,
int mode_switch)
500 unsigned char *new_data, *data = op->
data, *
p;
504 if ((w != 8) || (h != 16)
526 &&
FNTSIZE(font_data[i]) == size
527 && !
memcmp(font_data[i], new_data, size)) {
532 new_data = font_data[
i];
538 if (--
REFCOUNT(font_data[unit]) == 0)
539 kfree(font_data[unit] -
543 font_data[
unit] = new_data;
548 static int newport_set_def_font(
int unit,
struct console_font *op)
551 if (--
REFCOUNT(font_data[unit]) == 0)
552 kfree(font_data[unit] -
562 return newport_set_def_font(vc->
vc_num, op);
567 return newport_set_font(vc->
vc_num, font);
570 static int newport_set_palette(
struct vc_data *vc,
unsigned char *
table)
575 static int newport_scrolldelta(
struct vc_data *vc,
int lines)
581 static int newport_scroll(
struct vc_data *vc,
int t,
int b,
int dir,
585 unsigned short *
s, *
d;
586 unsigned short chattr;
590 if (t == 0 && b == vc->
vc_rows) {
592 topscan = (topscan + (lines << 4)) & 0x3ff;
593 newport_clear_lines(vc->
vc_rows - lines,
597 topscan = (topscan + (-lines << 4)) & 0x3ff;
598 newport_clear_lines(0, lines - 1,
601 npregs->
cset.topscan = (topscan - 1) & 0x3ff;
605 count = (b - t - lines) * vc->
vc_cols;
616 newport_putc(vc, chattr, y, x);
629 for (count = 0; count < (lines * vc->
vc_cols); count++) {
651 newport_putc(vc, chattr, y, x);
664 for (count = 0; count < (lines * vc->
vc_cols); count++) {
680 static void newport_bmove(
struct vc_data *vc,
int sy,
int sx,
int dy,
681 int dx,
int h,
int w)
686 xe = ((sx +
w) << 3) - 1;
691 ys = ((sy << 4) + topscan) & 0x3ff;
692 ye = (((sy +
h) << 4) - 1 + topscan) & 0x3ff;
693 xoffs = (dx -
sx) << 3;
694 yoffs = (dy - sy) << 4;
701 newport_wait(npregs);
705 npregs->
set.xystarti = (xs << 16) | ys;
706 npregs->
set.xyendi = (xe << 16) | ye;
707 npregs->
go.xymove = (xoffs << 16) | yoffs;
710 static int newport_dummy(
struct vc_data *c)
715 #define DUMMY (void *) newport_dummy
719 .con_startup = newport_startup,
720 .con_init = newport_init,
721 .con_deinit = newport_deinit,
722 .con_clear = newport_clear,
723 .con_putc = newport_putc,
724 .con_putcs = newport_putcs,
725 .con_cursor = newport_cursor,
726 .con_scroll = newport_scroll,
727 .con_bmove = newport_bmove,
728 .con_switch = newport_switch,
729 .con_blank = newport_blank,
730 .con_font_set = newport_font_set,
731 .con_font_default = newport_font_default,
732 .con_set_palette = newport_set_palette,
733 .con_scrolldelta = newport_scrolldelta,
734 .con_set_origin =
DUMMY,
735 .con_save_screen =
DUMMY
741 unsigned long newport_addr;
749 newport_addr = dev->
resource.start + 0xF0000;
759 static void newport_remove(
struct gio_device *dev)
774 .id_table = newport_ids,
775 .probe = newport_probe,
776 .remove = newport_remove,