1
2
3
4
5
6
7
8
9
10
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/tty.h>
16#include <linux/kd.h>
17#include <linux/selection.h>
18#include <linux/console.h>
19#include <linux/console_struct.h>
20#include <linux/vt_kern.h>
21#include <linux/mm.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24
25#include <asm/uaccess.h>
26#include <asm/system.h>
27#include <asm/page.h>
28#include <asm/pgtable.h>
29#include <video/newport.h>
30#define INCLUDE_LINUX_LOGO_DATA
31#include <asm/linux_logo.h>
32
33#include <video/font.h>
34
35#define LOGO_W 80
36#define LOGO_H 80
37
38extern struct fbcon_font_desc font_vga_8x16;
39extern unsigned long sgi_gfxaddr;
40
41#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
42
43
44#define REFCOUNT(fd) (((int *)(fd))[-1])
45#define FNTSIZE(fd) (((int *)(fd))[-2])
46#define FNTCHARCNT(fd) (((int *)(fd))[-3])
47#define FONT_EXTRA_WORDS 3
48
49static unsigned char *font_data[MAX_NR_CONSOLES];
50
51static struct newport_regs *npregs;
52
53static int logo_active;
54static int topscan;
55static int xcurs_correction = 29;
56static int newport_xsize;
57static int newport_ysize;
58
59static int newport_set_def_font(int unit, struct console_font_op *op);
60
61#define BMASK(c) (c << 24)
62
63#define RENDER(regs, cp) do { \
64(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
65(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
66(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
67(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
68(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
69(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
70(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
71(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
72} while(0)
73
74#define TESTVAL 0xdeadbeef
75#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
76
77static inline void newport_render_background(int xstart, int ystart,
78 int xend, int yend, int ci)
79{
80 newport_wait();
81 npregs->set.wrmask = 0xffffffff;
82 npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
83 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
84 | NPORT_DMODE0_STOPY);
85 npregs->set.colori = ci;
86 npregs->set.xystarti =
87 (xstart << 16) | ((ystart + topscan) & 0x3ff);
88 npregs->go.xyendi =
89 ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
90}
91
92static inline void newport_init_cmap(void)
93{
94 unsigned short i;
95
96 for (i = 0; i < 16; i++) {
97 newport_bfwait();
98 newport_cmap_setaddr(npregs, color_table[i]);
99 newport_cmap_setrgb(npregs,
100 default_red[i],
101 default_grn[i], default_blu[i]);
102 }
103}
104
105static inline void newport_show_logo(void)
106{
107 unsigned long i;
108
109 for (i = 0; i < LINUX_LOGO_COLORS; i++) {
110 newport_bfwait();
111 newport_cmap_setaddr(npregs, i + 0x20);
112 newport_cmap_setrgb(npregs,
113 linux_logo_red[i],
114 linux_logo_green[i],
115 linux_logo_blue[i]);
116 }
117
118 newport_wait();
119 npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
120 NPORT_DMODE0_CHOST);
121
122 npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);
123 npregs->set.xyendi = ((newport_xsize - 1) << 16);
124 newport_wait();
125
126 for (i = 0; i < LOGO_W * LOGO_H; i++)
127 npregs->go.hostrw0 = linux_logo[i] << 24;
128}
129
130static inline void newport_clear_screen(int xstart, int ystart, int xend,
131 int yend, int ci)
132{
133 if (logo_active)
134 return;
135
136 newport_wait();
137 npregs->set.wrmask = 0xffffffff;
138 npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
139 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
140 | NPORT_DMODE0_STOPY);
141 npregs->set.colori = ci;
142 npregs->set.xystarti = (xstart << 16) | ystart;
143 npregs->go.xyendi = (xend << 16) | yend;
144}
145
146static inline void newport_clear_lines(int ystart, int yend, int ci)
147{
148 ystart = ((ystart << 4) + topscan) & 0x3ff;
149 yend = ((yend << 4) + topscan + 15) & 0x3ff;
150 newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
151}
152
153void newport_reset(void)
154{
155 unsigned short treg;
156 int i;
157
158 newport_wait();
159 treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
160 newport_vc2_set(npregs, VC2_IREG_CONTROL,
161 (treg | VC2_CTRL_EVIDEO));
162
163 treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);
164 newport_vc2_set(npregs, VC2_IREG_RADDR, treg);
165 npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
166 NPORT_DMODE_W2 | VC2_PROTOCOL);
167 for (i = 0; i < 128; i++) {
168 newport_bfwait();
169 if (i == 92 || i == 94)
170 npregs->set.dcbdata0.byshort.s1 = 0xff00;
171 else
172 npregs->set.dcbdata0.byshort.s1 = 0x0000;
173 }
174
175 newport_init_cmap();
176
177
178 npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
179 XM9_CRS_CONFIG | NPORT_DMODE_W1);
180 npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
181 npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |
182 XM9_CRS_CONFIG | NPORT_DMODE_W1);
183 npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
184
185 topscan = 0;
186 npregs->cset.topscan = 0x3ff;
187 npregs->cset.xywin = (4096 << 16) | 4096;
188
189
190 newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
191}
192
193
194
195
196
197void newport_get_screensize(void)
198{
199 int i, cols;
200 unsigned short ventry, treg;
201 unsigned short linetable[128];
202
203 ventry = newport_vc2_get(npregs, VC2_IREG_VENTRY);
204 newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);
205 npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
206 NPORT_DMODE_W2 | VC2_PROTOCOL);
207 for (i = 0; i < 128; i++) {
208 newport_bfwait();
209 linetable[i] = npregs->set.dcbdata0.byshort.s1;
210 }
211
212 newport_xsize = newport_ysize = 0;
213 for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) {
214 cols = 0;
215 newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
216 npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
217 NPORT_DMODE_W2 | VC2_PROTOCOL);
218 do {
219 newport_bfwait();
220 treg = npregs->set.dcbdata0.byshort.s1;
221 if ((treg & 1) == 0)
222 cols += (treg >> 7) & 0xfe;
223 if ((treg & 0x80) == 0) {
224 newport_bfwait();
225 treg = npregs->set.dcbdata0.byshort.s1;
226 }
227 } while ((treg & 0x8000) == 0);
228 if (cols) {
229 if (cols > newport_xsize)
230 newport_xsize = cols;
231 newport_ysize += linetable[i + 1];
232 }
233 }
234 printk("NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
235}
236
237static void newport_get_revisions(void)
238{
239 unsigned int tmp;
240 unsigned int board_rev;
241 unsigned int rex3_rev;
242 unsigned int vc2_rev;
243 unsigned int cmap_rev;
244 unsigned int xmap9_rev;
245 unsigned int bt445_rev;
246 unsigned int bitplanes;
247
248 rex3_rev = npregs->cset.status & NPORT_STAT_VERS;
249
250 npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |
251 NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
252 tmp = npregs->set.dcbdata0.bybytes.b3;
253 cmap_rev = tmp & 7;
254 board_rev = (tmp >> 4) & 7;
255 bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
256
257 npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |
258 NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
259 tmp = npregs->set.dcbdata0.bybytes.b3;
260 if ((tmp & 7) < cmap_rev)
261 cmap_rev = (tmp & 7);
262
263 vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;
264
265 npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
266 XM9_CRS_REVISION | NPORT_DMODE_W1);
267 xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;
268
269 npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
270 BT445_CSR_ADDR_REG | NPORT_DMODE_W1);
271 npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;
272 npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
273 BT445_CSR_REVISION | NPORT_DMODE_W1);
274 bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
275
276#define L(a) (char)('A'+(a))
277 printk
278 ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
279 board_rev, bitplanes, L(rex3_rev), L(vc2_rev), L(xmap9_rev),
280 L(cmap_rev ? (cmap_rev + 1) : 0), L(bt445_rev));
281#undef L
282
283 if (board_rev == 3)
284 xcurs_correction = 21;
285}
286
287
288static const char *newport_startup(void)
289{
290 int i;
291
292 if (!sgi_gfxaddr)
293 return NULL;
294 npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
295 npregs->cset.config = NPORT_CFG_GD0;
296
297 if (newport_wait()) {
298 return NULL;
299 }
300
301 npregs->set.xstarti = TESTVAL;
302 if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
303 return NULL;
304
305 for (i = 0; i < MAX_NR_CONSOLES; i++)
306 font_data[i] = FONT_DATA;
307
308 newport_reset();
309 newport_get_revisions();
310 newport_get_screensize();
311
312 return "SGI Newport";
313}
314
315static void newport_init(struct vc_data *vc, int init)
316{
317 vc->vc_cols = newport_xsize / 8;
318 vc->vc_rows = newport_ysize / 16;
319 vc->vc_can_do_color = 1;
320}
321
322static void newport_deinit(struct vc_data *c)
323{
324 int i;
325
326
327 for (i = 0; i < MAX_NR_CONSOLES; i++)
328 newport_set_def_font(i, NULL);
329}
330
331static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
332 int width)
333{
334 int xend = ((sx + width) << 3) - 1;
335 int ystart = ((sy << 4) + topscan) & 0x3ff;
336 int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
337
338 if (logo_active)
339 return;
340
341 if (ystart < yend) {
342 newport_clear_screen(sx << 3, ystart, xend, yend,
343 (vc->vc_color & 0xf0) >> 4);
344 } else {
345 newport_clear_screen(sx << 3, ystart, xend, 1023,
346 (vc->vc_color & 0xf0) >> 4);
347 newport_clear_screen(sx << 3, 0, xend, yend,
348 (vc->vc_color & 0xf0) >> 4);
349 }
350}
351
352static void newport_putc(struct vc_data *vc, int charattr, int ypos,
353 int xpos)
354{
355 unsigned char *p;
356
357 p = &font_data[vc->vc_num][(charattr & 0xff) << 4];
358 charattr = (charattr >> 8) & 0xff;
359 xpos <<= 3;
360 ypos <<= 4;
361
362 newport_render_background(xpos, ypos, xpos, ypos,
363 (charattr & 0xf0) >> 4);
364
365
366 newport_wait();
367 npregs->set.colori = charattr & 0xf;
368 npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
369 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
370 NPORT_DMODE0_L32);
371
372
373 npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
374 npregs->set.xyendi = ((xpos + 7) << 16);
375 newport_wait();
376
377
378 RENDER(npregs, p);
379}
380
381static void newport_putcs(struct vc_data *vc, const unsigned short *s,
382 int count, int ypos, int xpos)
383{
384 int i;
385 int charattr;
386 unsigned char *p;
387
388 charattr = (scr_readw(s) >> 8) & 0xff;
389
390 xpos <<= 3;
391 ypos <<= 4;
392
393 if (!logo_active)
394
395 newport_render_background(xpos, ypos,
396 xpos + ((count - 1) << 3), ypos,
397 (charattr & 0xf0) >> 4);
398
399 newport_wait();
400
401
402 npregs->set.colori = charattr & 0xf;
403 npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
404 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
405 NPORT_DMODE0_L32);
406
407 for (i = 0; i < count; i++, xpos += 8) {
408 p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
409
410 newport_wait();
411
412
413 npregs->set.xystarti =
414 (xpos << 16) | ((ypos + topscan) & 0x3ff);
415 npregs->set.xyendi = ((xpos + 7) << 16);
416
417
418 RENDER(npregs, p);
419 }
420}
421
422static void newport_cursor(struct vc_data *vc, int mode)
423{
424 unsigned short treg;
425 int xcurs, ycurs;
426
427 switch (mode) {
428 case CM_ERASE:
429 treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
430 newport_vc2_set(npregs, VC2_IREG_CONTROL,
431 (treg & ~(VC2_CTRL_ECDISP)));
432 break;
433
434 case CM_MOVE:
435 case CM_DRAW:
436 treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
437 newport_vc2_set(npregs, VC2_IREG_CONTROL,
438 (treg | VC2_CTRL_ECDISP));
439 xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;
440 ycurs = ((xcurs / vc->vc_cols) << 4) + 31;
441 xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;
442 newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);
443 newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);
444 }
445}
446
447static int newport_switch(struct vc_data *vc)
448{
449 static int logo_drawn = 0;
450
451 topscan = 0;
452 npregs->cset.topscan = 0x3ff;
453
454 if (!logo_drawn) {
455 newport_show_logo();
456 logo_drawn = 1;
457 logo_active = 1;
458 }
459
460 return 1;
461}
462
463static int newport_blank(struct vc_data *c, int blank)
464{
465 unsigned short treg;
466
467 if (blank == 0) {
468
469 treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
470 newport_vc2_set(npregs, VC2_IREG_CONTROL,
471 (treg | VC2_CTRL_EDISP));
472 } else {
473
474 treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
475 newport_vc2_set(npregs, VC2_IREG_CONTROL,
476 (treg & ~(VC2_CTRL_EDISP)));
477 }
478 return 1;
479}
480
481static int newport_set_font(int unit, struct console_font_op *op)
482{
483 int w = op->width;
484 int h = op->height;
485 int size = h * op->charcount;
486 int i;
487 unsigned char *new_data, *data = op->data, *p;
488
489
490
491 if ((w != 8) || (h != 16)
492 || (op->charcount != 256 && op->charcount != 512))
493 return -EINVAL;
494
495 if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
496 GFP_USER))) return -ENOMEM;
497
498 new_data += FONT_EXTRA_WORDS * sizeof(int);
499 FNTSIZE(new_data) = size;
500 FNTCHARCNT(new_data) = op->charcount;
501 REFCOUNT(new_data) = 0;
502
503 p = new_data;
504 for (i = 0; i < op->charcount; i++) {
505 memcpy(p, data, h);
506 data += 32;
507 p += h;
508 }
509
510
511 for (i = 0; i < MAX_NR_CONSOLES; i++) {
512 if (font_data[i] != FONT_DATA
513 && FNTSIZE(font_data[i]) == size
514 && !memcmp(font_data[i], new_data, size)) {
515 kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
516
517 if (i == unit)
518 return 0;
519 new_data = font_data[i];
520 break;
521 }
522 }
523
524 if (font_data[unit] != FONT_DATA) {
525 if (--REFCOUNT(font_data[unit]) == 0)
526 kfree(font_data[unit] -
527 FONT_EXTRA_WORDS * sizeof(int));
528 }
529 REFCOUNT(new_data)++;
530 font_data[unit] = new_data;
531
532 return 0;
533}
534
535static int newport_set_def_font(int unit, struct console_font_op *op)
536{
537 if (font_data[unit] != FONT_DATA) {
538 if (--REFCOUNT(font_data[unit]) == 0)
539 kfree(font_data[unit] -
540 FONT_EXTRA_WORDS * sizeof(int));
541 font_data[unit] = FONT_DATA;
542 }
543
544 return 0;
545}
546
547static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
548{
549 int unit = vc->vc_num;
550
551 switch (op->op) {
552 case KD_FONT_OP_SET:
553 return newport_set_font(unit, op);
554 case KD_FONT_OP_SET_DEFAULT:
555 return newport_set_def_font(unit, op);
556 default:
557 return -ENOSYS;
558 }
559}
560
561static int newport_set_palette(struct vc_data *vc, unsigned char *table)
562{
563 return -EINVAL;
564}
565
566static int newport_scrolldelta(struct vc_data *vc, int lines)
567{
568
569 return 0;
570}
571
572static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
573 int lines)
574{
575 int count, x, y;
576 unsigned short *s, *d;
577 unsigned short chattr;
578
579 logo_active = 0;
580
581 if (t == 0 && b == vc->vc_rows) {
582 if (dir == SM_UP) {
583 topscan = (topscan + (lines << 4)) & 0x3ff;
584 newport_clear_lines(vc->vc_rows - lines,
585 vc->vc_rows - 1,
586 (vc->vc_color & 0xf0) >> 4);
587 } else {
588 topscan = (topscan + (-lines << 4)) & 0x3ff;
589 newport_clear_lines(0, lines - 1,
590 (vc->vc_color & 0xf0) >> 4);
591 }
592 npregs->cset.topscan = (topscan - 1) & 0x3ff;
593 return 0;
594 }
595
596 count = (b - t - lines) * vc->vc_cols;
597 if (dir == SM_UP) {
598 x = 0;
599 y = t;
600 s = (unsigned short *) (vc->vc_origin +
601 vc->vc_size_row * (t + lines));
602 d = (unsigned short *) (vc->vc_origin +
603 vc->vc_size_row * t);
604 while (count--) {
605 chattr = scr_readw(s++);
606 if (chattr != scr_readw(d)) {
607 newport_putc(vc, chattr, y, x);
608 scr_writew(chattr, d);
609 }
610 d++;
611 if (++x == vc->vc_cols) {
612 x = 0;
613 y++;
614 }
615 }
616 d = (unsigned short *) (vc->vc_origin +
617 vc->vc_size_row * (b - lines));
618 x = 0;
619 y = b - lines;
620 for (count = 0; count < (lines * vc->vc_cols); count++) {
621 if (scr_readw(d) != vc->vc_video_erase_char) {
622 newport_putc(vc, vc->vc_video_erase_char,
623 y, x);
624 scr_writew(vc->vc_video_erase_char, d);
625 }
626 d++;
627 if (++x == vc->vc_cols) {
628 x = 0;
629 y++;
630 }
631 }
632 } else {
633 x = vc->vc_cols - 1;
634 y = b - 1;
635 s = (unsigned short *) (vc->vc_origin +
636 vc->vc_size_row * (b - lines) - 2);
637 d = (unsigned short *) (vc->vc_origin +
638 vc->vc_size_row * b - 2);
639 while (count--) {
640 chattr = scr_readw(s--);
641 if (chattr != scr_readw(d)) {
642 newport_putc(vc, chattr, y, x);
643 scr_writew(chattr, d);
644 }
645 d--;
646 if (x-- == 0) {
647 x = vc->vc_cols - 1;
648 y--;
649 }
650 }
651 d = (unsigned short *) (vc->vc_origin +
652 vc->vc_size_row * t);
653 x = 0;
654 y = t;
655 for (count = 0; count < (lines * vc->vc_cols); count++) {
656 if (scr_readw(d) != vc->vc_video_erase_char) {
657 newport_putc(vc, vc->vc_video_erase_char,
658 y, x);
659 scr_writew(vc->vc_video_erase_char, d);
660 }
661 d++;
662 if (++x == vc->vc_cols) {
663 x = 0;
664 y++;
665 }
666 }
667 }
668 return 1;
669}
670
671static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
672 int dx, int h, int w)
673{
674 short xs, ys, xe, ye, xoffs, yoffs, tmp;
675
676 xs = sx << 3;
677 xe = ((sx + w) << 3) - 1;
678
679
680
681
682 ys = ((sy << 4) + topscan) & 0x3ff;
683 ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
684 xoffs = (dx - sx) << 3;
685 yoffs = (dy - sy) << 4;
686 if (xoffs > 0) {
687
688 tmp = xe;
689 xe = xs;
690 xs = tmp;
691 }
692 newport_wait();
693 npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
694 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
695 | NPORT_DMODE0_STOPY);
696 npregs->set.xystarti = (xs << 16) | ys;
697 npregs->set.xyendi = (xe << 16) | ye;
698 npregs->go.xymove = (xoffs << 16) | yoffs;
699}
700
701static int newport_dummy(struct vc_data *c)
702{
703 return 0;
704}
705
706#define DUMMY (void *) newport_dummy
707
708const struct consw newport_con = {
709 con_startup: newport_startup,
710 con_init: newport_init,
711 con_deinit: newport_deinit,
712 con_clear: newport_clear,
713 con_putc: newport_putc,
714 con_putcs: newport_putcs,
715 con_cursor: newport_cursor,
716 con_scroll: newport_scroll,
717 con_bmove: newport_bmove,
718 con_switch: newport_switch,
719 con_blank: newport_blank,
720 con_font_op: newport_font_op,
721 con_set_palette: newport_set_palette,
722 con_scrolldelta: newport_scrolldelta,
723 con_set_origin: DUMMY,
724 con_save_screen: DUMMY
725};
726
727#ifdef MODULE
728static int __init newport_console_init(void)
729{
730 take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
731
732 return 0;
733}
734
735static void __exit newport_console_exit(void)
736{
737 give_up_console(&newport_con);
738}
739
740module_init(newport_console_init);
741module_exit(newport_console_exit);
742#endif
743
744MODULE_LICENSE("GPL");
745