1 /* $NetBSD: newport.c,v 1.14 2009/03/04 01:23:28 macallan Exp $ */
4 * Copyright (c) 2003 Ilpo Ruotsalainen
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.14 2009/03/04 01:23:28 macallan Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/malloc.h>
40 #include <machine/sysconf.h>
42 #include <dev/wscons/wsconsio.h>
43 #include <dev/wscons/wsdisplayvar.h>
44 #include <dev/wsfont/wsfont.h>
45 #include <dev/rasops/rasops.h>
46 #include <dev/wscons/wsdisplay_vconsvar.h>
48 #include <sgimips/gio/giovar.h>
49 #include <sgimips/gio/newportvar.h>
50 #include <sgimips/gio/newportreg.h>
52 struct newport_softc
{
55 struct newport_devconfig
*sc_dc
;
59 struct newport_devconfig
{
62 bus_space_tag_t dc_st
;
63 bus_space_handle_t dc_sh
;
75 struct wsscreen_descr
*dc_screen
;
76 struct wsdisplay_font
*dc_fontdata
;
78 struct vcons_data dc_vd
;
81 static int newport_match(device_t
, struct cfdata
*, void *);
82 static void newport_attach(device_t
, device_t
, void *);
84 CFATTACH_DECL_NEW(newport
, sizeof(struct newport_softc
),
85 newport_match
, newport_attach
, NULL
, NULL
);
88 static void newport_cursor(void *, int, int, int);
89 static void newport_cursor_dummy(void *, int, int, int);
90 static int newport_mapchar(void *, int, unsigned int *);
91 static void newport_putchar(void *, int, int, u_int
, long);
92 static void newport_copycols(void *, int, int, int, int);
93 static void newport_erasecols(void *, int, int, int, long);
94 static void newport_copyrows(void *, int, int, int);
95 static void newport_eraserows(void *, int, int, long);
96 static int newport_allocattr(void *, int, int, int, long *);
98 static void newport_init_screen(void *, struct vcons_screen
*, int, long *);
101 static int newport_ioctl(void *, void *, u_long
, void *, int,
103 static paddr_t
newport_mmap(void *, void *, off_t
, int);
105 static struct wsdisplay_accessops newport_accessops
= {
106 .ioctl
= newport_ioctl
,
107 .mmap
= newport_mmap
,
110 static struct wsdisplay_emulops newport_textops
= {
111 .cursor
= newport_cursor_dummy
,
112 .mapchar
= newport_mapchar
,
113 .putchar
= newport_putchar
,
114 .copycols
= newport_copycols
,
115 .erasecols
= newport_erasecols
,
116 .copyrows
= newport_copyrows
,
117 .eraserows
= newport_eraserows
,
118 .allocattr
= newport_allocattr
121 static struct wsscreen_descr newport_screen
= {
125 .textops
= &newport_textops
,
128 .capabilities
= WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_REVERSE
131 static const struct wsscreen_descr
*_newport_screenlist
[] = {
135 static const struct wsscreen_list newport_screenlist
= {
136 sizeof(_newport_screenlist
) / sizeof(struct wsscreen_descr
*),
140 static struct vcons_screen newport_console_screen
;
141 static struct newport_devconfig newport_console_dc
;
142 static int newport_is_console
= 0;
144 #define NEWPORT_ATTR_ENCODE(fg,bg) (((fg) << 8) | (bg))
145 #define NEWPORT_ATTR_BG(a) ((a) & 0xff)
146 #define NEWPORT_ATTR_FG(a) (((a) >> 8) & 0xff)
148 extern const u_char rasops_cmap
[768];
150 /**** Low-level hardware register groveling functions ****/
152 rex3_write(struct newport_devconfig
*dc
, bus_size_t rexreg
, uint32_t val
)
154 bus_space_write_4(dc
->dc_st
, dc
->dc_sh
, NEWPORT_REX3_OFFSET
+ rexreg
,
159 rex3_write_go(struct newport_devconfig
*dc
, bus_size_t rexreg
, uint32_t val
)
161 rex3_write(dc
, rexreg
+ REX3_REG_GO
, val
);
165 rex3_read(struct newport_devconfig
*dc
, bus_size_t rexreg
)
167 return bus_space_read_4(dc
->dc_st
, dc
->dc_sh
, NEWPORT_REX3_OFFSET
+
172 rex3_wait_gfifo(struct newport_devconfig
*dc
)
174 while (rex3_read(dc
, REX3_REG_STATUS
) & REX3_STATUS_GFXBUSY
)
179 vc2_write_ireg(struct newport_devconfig
*dc
, uint8_t ireg
, uint16_t val
)
181 rex3_write(dc
, REX3_REG_DCBMODE
,
183 REX3_DCBMODE_ENCRSINC
|
184 (NEWPORT_DCBADDR_VC2
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
185 (VC2_DCBCRS_INDEX
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
186 REX3_DCBMODE_ENASYNCACK
|
187 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
189 rex3_write(dc
, REX3_REG_DCBDATA0
, (ireg
<< 24) | (val
<< 8));
193 vc2_read_ireg(struct newport_devconfig
*dc
, uint8_t ireg
)
195 rex3_write(dc
, REX3_REG_DCBMODE
,
197 REX3_DCBMODE_ENCRSINC
|
198 (NEWPORT_DCBADDR_VC2
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
199 (VC2_DCBCRS_INDEX
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
200 REX3_DCBMODE_ENASYNCACK
|
201 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
203 rex3_write(dc
, REX3_REG_DCBDATA0
, ireg
<< 24);
205 rex3_write(dc
, REX3_REG_DCBMODE
,
207 REX3_DCBMODE_ENCRSINC
|
208 (NEWPORT_DCBADDR_VC2
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
209 (VC2_DCBCRS_IREG
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
210 REX3_DCBMODE_ENASYNCACK
|
211 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
213 return (uint16_t)(rex3_read(dc
, REX3_REG_DCBDATA0
) >> 16);
217 vc2_read_ram(struct newport_devconfig
*dc
, uint16_t addr
)
219 vc2_write_ireg(dc
, VC2_IREG_RAM_ADDRESS
, addr
);
221 rex3_write(dc
, REX3_REG_DCBMODE
,
223 (NEWPORT_DCBADDR_VC2
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
224 (VC2_DCBCRS_RAM
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
225 REX3_DCBMODE_ENASYNCACK
|
226 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
228 return (uint16_t)(rex3_read(dc
, REX3_REG_DCBDATA0
) >> 16);
233 vc2_write_ram(struct newport_devconfig
*dc
, uint16_t addr
, uint16_t val
)
235 vc2_write_ireg(dc
, VC2_IREG_RAM_ADDRESS
, addr
);
237 rex3_write(dc
, REX3_REG_DCBMODE
,
239 (NEWPORT_DCBADDR_VC2
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
240 (VC2_DCBCRS_RAM
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
241 REX3_DCBMODE_ENASYNCACK
|
242 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
244 rex3_write(dc
, REX3_REG_DCBDATA0
, val
<< 16);
249 xmap9_read(struct newport_devconfig
*dc
, int crs
)
251 rex3_write(dc
, REX3_REG_DCBMODE
,
253 (NEWPORT_DCBADDR_XMAP_0
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
254 (crs
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
255 (3 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
256 (2 << REX3_DCBMODE_CSHOLD_SHIFT
) |
257 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
258 return rex3_read(dc
, REX3_REG_DCBDATA0
);
262 xmap9_write(struct newport_devconfig
*dc
, int crs
, uint8_t val
)
264 rex3_write(dc
, REX3_REG_DCBMODE
,
266 (NEWPORT_DCBADDR_XMAP_BOTH
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
267 (crs
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
268 (3 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
269 (2 << REX3_DCBMODE_CSHOLD_SHIFT
) |
270 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
272 rex3_write(dc
, REX3_REG_DCBDATA0
, val
<< 24);
276 xmap9_write_mode(struct newport_devconfig
*dc
, uint8_t index
, uint32_t mode
)
278 rex3_write(dc
, REX3_REG_DCBMODE
,
280 (NEWPORT_DCBADDR_XMAP_BOTH
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
281 (XMAP9_DCBCRS_MODE_SETUP
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
282 (3 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
283 (2 << REX3_DCBMODE_CSHOLD_SHIFT
) |
284 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
286 rex3_write(dc
, REX3_REG_DCBDATA0
, (index
<< 24) | mode
);
289 /**** Helper functions ****/
291 newport_fill_rectangle(struct newport_devconfig
*dc
, int x1
, int y1
, int x2
,
292 int y2
, uint8_t color
)
296 rex3_write(dc
, REX3_REG_DRAWMODE0
, REX3_DRAWMODE0_OPCODE_DRAW
|
297 REX3_DRAWMODE0_ADRMODE_BLOCK
| REX3_DRAWMODE0_DOSETUP
|
298 REX3_DRAWMODE0_STOPONX
| REX3_DRAWMODE0_STOPONY
);
299 rex3_write(dc
, REX3_REG_DRAWMODE1
,
300 REX3_DRAWMODE1_PLANES_CI
|
301 REX3_DRAWMODE1_DD_DD8
|
302 REX3_DRAWMODE1_RWPACKED
|
303 REX3_DRAWMODE1_HD_HD8
|
304 REX3_DRAWMODE1_COMPARE_LT
|
305 REX3_DRAWMODE1_COMPARE_EQ
|
306 REX3_DRAWMODE1_COMPARE_GT
|
307 REX3_DRAWMODE1_LO_SRC
);
308 rex3_write(dc
, REX3_REG_WRMASK
, 0xffffffff);
309 rex3_write(dc
, REX3_REG_COLORI
, color
);
310 rex3_write(dc
, REX3_REG_XYSTARTI
, (x1
<< REX3_XYSTARTI_XSHIFT
) | y1
);
312 rex3_write_go(dc
, REX3_REG_XYENDI
, (x2
<< REX3_XYENDI_XSHIFT
) | y2
);
316 newport_bitblt(struct newport_devconfig
*dc
, int xs
, int ys
, int xd
,
317 int yd
, int wi
, int he
, int rop
)
324 /* need to copy bottom up */
332 /* need to copy right to left */
339 rex3_write(dc
, REX3_REG_DRAWMODE0
, REX3_DRAWMODE0_OPCODE_SCR2SCR
|
340 REX3_DRAWMODE0_ADRMODE_BLOCK
| REX3_DRAWMODE0_DOSETUP
|
341 REX3_DRAWMODE0_STOPONX
| REX3_DRAWMODE0_STOPONY
);
342 rex3_write(dc
, REX3_REG_DRAWMODE1
,
343 REX3_DRAWMODE1_PLANES_CI
|
344 REX3_DRAWMODE1_DD_DD8
|
345 REX3_DRAWMODE1_RWPACKED
|
346 REX3_DRAWMODE1_HD_HD8
|
347 REX3_DRAWMODE1_COMPARE_LT
|
348 REX3_DRAWMODE1_COMPARE_EQ
|
349 REX3_DRAWMODE1_COMPARE_GT
|
350 ((rop
<< 28) & REX3_DRAWMODE1_LOGICOP_MASK
));
351 rex3_write(dc
, REX3_REG_XYSTARTI
, (xs
<< REX3_XYSTARTI_XSHIFT
) | ys
);
352 rex3_write(dc
, REX3_REG_XYENDI
, (xe
<< REX3_XYENDI_XSHIFT
) | ye
);
354 tmp
= (yd
- ys
) & 0xffff;
355 tmp
|= (xd
- xs
) << REX3_XYMOVE_XSHIFT
;
357 rex3_write_go(dc
, REX3_REG_XYMOVE
, tmp
);
361 newport_cmap_setrgb(struct newport_devconfig
*dc
, int index
, uint8_t r
,
362 uint8_t g
, uint8_t b
)
364 rex3_write(dc
, REX3_REG_DCBMODE
,
366 REX3_DCBMODE_ENCRSINC
|
367 (NEWPORT_DCBADDR_CMAP_BOTH
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
368 (CMAP_DCBCRS_ADDRESS_LOW
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
369 (1 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
370 (1 << REX3_DCBMODE_CSHOLD_SHIFT
) |
371 (1 << REX3_DCBMODE_CSSETUP_SHIFT
) |
372 REX3_DCBMODE_SWAPENDIAN
);
374 rex3_write(dc
, REX3_REG_DCBDATA0
, index
<< 16);
376 rex3_write(dc
, REX3_REG_DCBMODE
,
378 (NEWPORT_DCBADDR_CMAP_BOTH
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
379 (CMAP_DCBCRS_PALETTE
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
380 (1 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
381 (1 << REX3_DCBMODE_CSHOLD_SHIFT
) |
382 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
384 rex3_write(dc
, REX3_REG_DCBDATA0
, (r
<< 24) + (g
<< 16) + (b
<< 8));
388 newport_get_resolution(struct newport_devconfig
*dc
)
394 vep
= vc2_read_ireg(dc
, VC2_IREG_VIDEO_ENTRY
);
400 /* Iterate over runs in video timing table */
404 linep
= vc2_read_ram(dc
, vep
++);
405 lines
= vc2_read_ram(dc
, vep
++);
411 /* Iterate over state runs in line sequence table */
413 data
= vc2_read_ram(dc
, linep
++);
415 if ((data
& 0x0001) == 0)
416 cols
+= (data
>> 7) & 0xfe;
418 if ((data
& 0x0080) == 0)
419 data
= vc2_read_ram(dc
, linep
++);
420 } while ((data
& 0x8000) == 0);
423 if (cols
> dc
->dc_xres
)
426 dc
->dc_yres
+= lines
;
432 newport_setup_hw(struct newport_devconfig
*dc
)
438 /* Get various revisions */
439 rex3_write(dc
, REX3_REG_DCBMODE
,
441 (NEWPORT_DCBADDR_CMAP_0
<< REX3_DCBMODE_DCBADDR_SHIFT
) |
442 (CMAP_DCBCRS_REVISION
<< REX3_DCBMODE_DCBCRS_SHIFT
) |
443 (1 << REX3_DCBMODE_CSWIDTH_SHIFT
) |
444 (1 << REX3_DCBMODE_CSHOLD_SHIFT
) |
445 (1 << REX3_DCBMODE_CSSETUP_SHIFT
));
447 scratch
= vc2_read_ireg(dc
, VC2_IREG_CONFIG
);
448 dc
->dc_vc2rev
= (scratch
& VC2_IREG_CONFIG_REVISION
) >> 5;
450 scratch
= rex3_read(dc
, REX3_REG_DCBDATA0
);
452 dc
->dc_boardrev
= (scratch
>> 28) & 0x07;
453 dc
->dc_cmaprev
= scratch
& 0x07;
454 dc
->dc_xmaprev
= xmap9_read(dc
, XMAP9_DCBCRS_REVISION
) & 0x07;
455 dc
->dc_depth
= ( (dc
->dc_boardrev
> 1) && (scratch
& 0x80)) ? 8 : 24;
457 /* Setup cursor glyph */
458 curp
= vc2_read_ireg(dc
, VC2_IREG_CURSOR_ENTRY
);
460 /* Setup VC2 to a known state */
461 tmp
= vc2_read_ireg(dc
, VC2_IREG_CONTROL
) & VC2_CONTROL_INTERLACE
;
462 vc2_write_ireg(dc
, VC2_IREG_CONTROL
, tmp
|
463 VC2_CONTROL_DISPLAY_ENABLE
|
464 VC2_CONTROL_VTIMING_ENABLE
|
465 VC2_CONTROL_DID_ENABLE
|
466 VC2_CONTROL_CURSORFUNC_ENABLE
/*|
467 VC2_CONTROL_CURSOR_ENABLE*/);
470 xmap9_write(dc
, XMAP9_DCBCRS_CONFIG
,
471 XMAP9_CONFIG_8BIT_SYSTEM
| XMAP9_CONFIG_RGBMAP_CI
);
473 xmap9_write(dc
, XMAP9_DCBCRS_CURSOR_CMAP
, 0);
475 xmap9_write_mode(dc
, 0,
476 XMAP9_MODE_GAMMA_BYPASS
|
477 XMAP9_MODE_PIXSIZE_8BPP
);
478 xmap9_write(dc
, XMAP9_DCBCRS_MODE_SELECT
, 0);
481 rex3_write(dc
, REX3_REG_XYWIN
, (4096 << 16) | 4096);
482 rex3_write(dc
, REX3_REG_TOPSCAN
, 0x3ff); /* XXX Why? XXX */
485 for (i
= 0; i
< 256; i
++)
486 newport_cmap_setrgb(dc
, i
, rasops_cmap
[i
* 3],
487 rasops_cmap
[i
* 3 + 1], rasops_cmap
[i
* 3 + 2]);
490 /**** Attach routines ****/
492 newport_match(device_t parent
, struct cfdata
*self
, void *aux
)
494 struct gio_attach_args
*ga
= aux
;
496 /* newport doesn't decode all addresses */
497 if (ga
->ga_addr
!= 0x1f000000 && ga
->ga_addr
!= 0x1f400000 &&
498 ga
->ga_addr
!= 0x1f800000 && ga
->ga_addr
!= 0x1fc00000)
501 /* Don't do the destructive probe if we're already attached */
502 if (newport_is_console
&& ga
->ga_addr
== newport_console_dc
.dc_addr
)
505 if (platform
.badaddr(
506 (void *)(ga
->ga_ioh
+ NEWPORT_REX3_OFFSET
+ REX3_REG_XSTARTI
),
509 if (platform
.badaddr(
510 (void *)(ga
->ga_ioh
+ NEWPORT_REX3_OFFSET
+ REX3_REG_XSTART
),
514 /* Ugly, this probe is destructive, blame SGI... */
515 /* XXX Should be bus_space_peek/bus_space_poke XXX */
516 bus_space_write_4(ga
->ga_iot
, ga
->ga_ioh
,
517 NEWPORT_REX3_OFFSET
+ REX3_REG_XSTARTI
, 0x12345678);
518 if (bus_space_read_4(ga
->ga_iot
, ga
->ga_ioh
,
519 NEWPORT_REX3_OFFSET
+ REX3_REG_XSTART
)
520 != ((0x12345678 & 0xffff) << 11))
527 newport_attach_common(struct newport_devconfig
*dc
, struct gio_attach_args
*ga
)
529 dc
->dc_addr
= ga
->ga_addr
;
531 dc
->dc_st
= ga
->ga_iot
;
532 dc
->dc_sh
= ga
->ga_ioh
;
536 dc
->dc_font
= wsfont_find(NULL
, 8, 16, 0, WSDISPLAY_FONTORDER_L2R
,
537 WSDISPLAY_FONTORDER_L2R
);
539 panic("newport_attach_common: no suitable fonts");
541 if (wsfont_lock(dc
->dc_font
, &dc
->dc_fontdata
))
542 panic("newport_attach_common: unable to lock font data");
544 newport_setup_hw(dc
);
546 newport_get_resolution(dc
);
548 newport_fill_rectangle(dc
, 0, 0, dc
->dc_xres
, dc
->dc_yres
, 0);
549 dc
->dc_screen
= &newport_screen
;
551 dc
->dc_mode
= WSDISPLAYIO_MODE_EMUL
;
555 newport_attach(device_t parent
, device_t self
, void *aux
)
557 struct gio_attach_args
*ga
= aux
;
558 struct newport_softc
*sc
= device_private(self
);
559 struct wsemuldisplaydev_attach_args wa
;
560 unsigned long defattr
;
563 if (newport_is_console
&& ga
->ga_addr
== newport_console_dc
.dc_addr
) {
565 sc
->sc_dc
= &newport_console_dc
;
568 sc
->sc_dc
= malloc(sizeof(struct newport_devconfig
),
569 M_DEVBUF
, M_WAITOK
| M_ZERO
);
570 if (sc
->sc_dc
== NULL
)
571 panic("newport_attach: out of memory");
573 newport_attach_common(sc
->sc_dc
, ga
);
576 aprint_naive(": Display adapter\n");
578 aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n",
579 sc
->sc_dc
->dc_boardrev
, sc
->sc_dc
->dc_cmaprev
,
580 sc
->sc_dc
->dc_xmaprev
, sc
->sc_dc
->dc_vc2rev
, sc
->sc_dc
->dc_depth
);
581 vcons_init(&sc
->sc_dc
->dc_vd
, sc
->sc_dc
, sc
->sc_dc
->dc_screen
,
583 sc
->sc_dc
->dc_vd
.init_screen
= newport_init_screen
;
584 if (newport_is_console
) {
585 newport_console_screen
.scr_flags
|= VCONS_SCREEN_IS_STATIC
;
586 vcons_init_screen(&sc
->sc_dc
->dc_vd
, &newport_console_screen
,
588 sc
->sc_dc
->dc_screen
->textops
=
589 &newport_console_screen
.scr_ri
.ri_ops
;
590 memcpy(&newport_textops
, &newport_console_screen
.scr_ri
.ri_ops
,
591 sizeof(struct wsdisplay_emulops
));
593 wa
.scrdata
= &newport_screenlist
;
594 wa
.accessops
= &newport_accessops
;
595 wa
.accesscookie
= &sc
->sc_dc
->dc_vd
;
597 config_found(sc
->sc_dev
, &wa
, wsemuldisplaydevprint
);
601 newport_cnattach(struct gio_attach_args
*ga
)
603 struct rasops_info
*ri
= &newport_console_screen
.scr_ri
;
604 long defattr
= NEWPORT_ATTR_ENCODE(WSCOL_WHITE
, WSCOL_BLACK
);
606 if (!newport_match(NULL
, NULL
, ga
)) {
610 newport_attach_common(&newport_console_dc
, ga
);
612 newport_screen
.ncols
= newport_console_dc
.dc_xres
/ 8;
613 newport_screen
.nrows
= newport_console_dc
.dc_yres
/ 16;
615 ri
->ri_hw
= &newport_console_screen
;
616 ri
->ri_depth
= newport_console_dc
.dc_depth
;
617 ri
->ri_width
= newport_console_dc
.dc_xres
;
618 ri
->ri_height
= newport_console_dc
.dc_yres
;
619 ri
->ri_stride
= newport_console_dc
.dc_xres
; /* XXX */
620 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
621 ri
->ri_ops
.copyrows
= newport_copyrows
;
622 ri
->ri_ops
.eraserows
= newport_eraserows
;
623 ri
->ri_ops
.copycols
= newport_copycols
;
624 ri
->ri_ops
.erasecols
= newport_erasecols
;
625 ri
->ri_ops
.cursor
= newport_cursor_dummy
;
626 ri
->ri_ops
.mapchar
= newport_mapchar
;
627 ri
->ri_ops
.putchar
= newport_putchar
;
628 ri
->ri_ops
.allocattr
= newport_allocattr
;
629 ri
->ri_font
= newport_console_dc
.dc_fontdata
;
630 newport_console_screen
.scr_cookie
= &newport_console_dc
;
632 wsdisplay_cnattach(&newport_screen
, ri
, 0, 0, defattr
);
634 newport_is_console
= 1;
640 newport_init_screen(void *cookie
, struct vcons_screen
*scr
,
641 int existing
, long *defattr
)
643 struct newport_devconfig
*dc
= cookie
;
644 struct rasops_info
*ri
= &scr
->scr_ri
;
646 ri
->ri_depth
= dc
->dc_depth
;
647 ri
->ri_width
= dc
->dc_xres
;
648 ri
->ri_height
= dc
->dc_yres
;
649 ri
->ri_stride
= dc
->dc_xres
; /* XXX */
650 ri
->ri_flg
= RI_CENTER
;
652 /*&ri->ri_bits = (char *)sc->sc_fb.fb_pixels;*/
654 rasops_init(ri
, dc
->dc_yres
/ 8, dc
->dc_xres
/ 8);
655 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
657 rasops_reconfig(ri
, dc
->dc_yres
/ ri
->ri_font
->fontheight
,
658 dc
->dc_xres
/ ri
->ri_font
->fontwidth
);
661 ri
->ri_ops
.copyrows
= newport_copyrows
;
662 ri
->ri_ops
.eraserows
= newport_eraserows
;
663 ri
->ri_ops
.copycols
= newport_copycols
;
664 ri
->ri_ops
.erasecols
= newport_erasecols
;
665 ri
->ri_ops
.cursor
= newport_cursor
;
666 ri
->ri_ops
.mapchar
= newport_mapchar
;
667 ri
->ri_ops
.putchar
= newport_putchar
;
668 ri
->ri_ops
.allocattr
= newport_allocattr
;
671 /**** wsdisplay textops ****/
673 newport_cursor_dummy(void *c
, int on
, int row
, int col
)
678 newport_cursor(void *c
, int on
, int row
, int col
)
680 struct rasops_info
*ri
= c
;
681 struct vcons_screen
*scr
= ri
->ri_hw
;
682 struct newport_devconfig
*dc
= scr
->scr_cookie
;
685 wi
= ri
->ri_font
->fontwidth
;
686 he
= ri
->ri_font
->fontheight
;
688 if (ri
->ri_flg
& RI_CURSOR
) {
689 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
690 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
691 newport_bitblt(dc
, x
, y
, x
, y
, wi
, he
, 12);
692 ri
->ri_flg
&= ~RI_CURSOR
;
700 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
701 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
702 newport_bitblt(dc
, x
, y
, x
, y
, wi
, he
, 12);
703 ri
->ri_flg
|= RI_CURSOR
;
708 newport_mapchar(void *c
, int ch
, unsigned int *cp
)
710 struct rasops_info
*ri
= c
;
711 struct vcons_screen
*scr
= ri
->ri_hw
;
712 struct newport_devconfig
*dc
= scr
->scr_cookie
;
714 if (dc
->dc_fontdata
->encoding
!= WSDISPLAY_FONTENC_ISO
) {
715 ch
= wsfont_map_unichar(dc
->dc_fontdata
, ch
);
721 if (ch
< dc
->dc_fontdata
->firstchar
||
722 ch
>= dc
->dc_fontdata
->firstchar
+ dc
->dc_fontdata
->numchars
)
734 newport_putchar(void *c
, int row
, int col
, u_int ch
, long attr
)
736 struct rasops_info
*ri
= c
;
737 struct vcons_screen
*scr
= ri
->ri_hw
;
738 struct newport_devconfig
*dc
= scr
->scr_cookie
;
739 struct wsdisplay_font
*font
= ri
->ri_font
;
740 uint8_t *bitmap
= (u_int8_t
*)font
->data
+ (ch
- font
->firstchar
) *
741 font
->fontheight
* font
->stride
;
744 int x
= col
* font
->fontwidth
+ ri
->ri_xorigin
;
745 int y
= row
* font
->fontheight
+ ri
->ri_yorigin
;
749 rex3_write(dc
, REX3_REG_DRAWMODE0
, REX3_DRAWMODE0_OPCODE_DRAW
|
750 REX3_DRAWMODE0_ADRMODE_BLOCK
| REX3_DRAWMODE0_STOPONX
|
751 REX3_DRAWMODE0_ENZPATTERN
| REX3_DRAWMODE0_ZPOPAQUE
);
753 rex3_write(dc
, REX3_REG_DRAWMODE1
,
754 REX3_DRAWMODE1_PLANES_CI
|
755 REX3_DRAWMODE1_DD_DD8
|
756 REX3_DRAWMODE1_RWPACKED
|
757 REX3_DRAWMODE1_HD_HD8
|
758 REX3_DRAWMODE1_COMPARE_LT
|
759 REX3_DRAWMODE1_COMPARE_EQ
|
760 REX3_DRAWMODE1_COMPARE_GT
|
761 REX3_DRAWMODE1_LO_SRC
);
763 rex3_write(dc
, REX3_REG_XYSTARTI
, (x
<< REX3_XYSTARTI_XSHIFT
) | y
);
764 rex3_write(dc
, REX3_REG_XYENDI
,
765 (x
+ font
->fontwidth
- 1) << REX3_XYENDI_XSHIFT
);
767 rex3_write(dc
, REX3_REG_COLORI
, NEWPORT_ATTR_FG(attr
));
768 rex3_write(dc
, REX3_REG_COLORBACK
, NEWPORT_ATTR_BG(attr
));
770 rex3_write(dc
, REX3_REG_WRMASK
, 0xffffffff);
772 for (i
= 0; i
< font
->fontheight
; i
++) {
773 /* XXX Works only with font->fontwidth == 8 XXX */
774 pattern
= *bitmap
<< 24;
776 rex3_write_go(dc
, REX3_REG_ZPATTERN
, pattern
);
778 bitmap
+= font
->stride
;
783 newport_copycols(void *c
, int row
, int srccol
, int dstcol
, int ncols
)
785 struct rasops_info
*ri
= c
;
786 struct vcons_screen
*scr
= ri
->ri_hw
;
787 struct newport_devconfig
*dc
= scr
->scr_cookie
;
788 int32_t xs
, xd
, y
, width
, height
;
790 xs
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* srccol
;
791 xd
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* dstcol
;
792 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
793 width
= ri
->ri_font
->fontwidth
* ncols
;
794 height
= ri
->ri_font
->fontheight
;
795 newport_bitblt(dc
, xs
, y
, xd
, y
, width
, height
, 3);
799 newport_erasecols(void *c
, int row
, int startcol
, int ncols
,
802 struct rasops_info
*ri
= c
;
803 struct vcons_screen
*scr
= ri
->ri_hw
;
804 struct newport_devconfig
*dc
= scr
->scr_cookie
;
805 struct wsdisplay_font
*font
= dc
->dc_fontdata
;
807 newport_fill_rectangle(dc
,
808 startcol
* font
->fontwidth
, /* x1 */
809 row
* font
->fontheight
, /* y1 */
810 (startcol
+ ncols
) * font
->fontwidth
- 1, /* x2 */
811 (row
+ 1) * font
->fontheight
- 1, /* y2 */
812 NEWPORT_ATTR_BG(attr
));
816 newport_copyrows(void *c
, int srcrow
, int dstrow
, int nrows
)
818 struct rasops_info
*ri
= c
;
819 struct vcons_screen
*scr
= ri
->ri_hw
;
820 struct newport_devconfig
*dc
= scr
->scr_cookie
;
821 int32_t x
, ys
, yd
, width
, height
;
824 ys
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* srcrow
;
825 yd
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* dstrow
;
826 width
= ri
->ri_emuwidth
;
827 height
= ri
->ri_font
->fontheight
* nrows
;
829 newport_bitblt(dc
, x
, ys
, x
, yd
, width
, height
, 3);
833 newport_eraserows(void *c
, int startrow
, int nrows
, long attr
)
835 struct rasops_info
*ri
= c
;
836 struct vcons_screen
*scr
= ri
->ri_hw
;
837 struct newport_devconfig
*dc
= scr
->scr_cookie
;
838 struct wsdisplay_font
*font
= dc
->dc_fontdata
;
840 newport_fill_rectangle(dc
,
842 startrow
* font
->fontheight
, /* y1 */
843 dc
->dc_xres
, /* x2 */
844 (startrow
+ nrows
) * font
->fontheight
- 1, /* y2 */
845 NEWPORT_ATTR_BG(attr
));
849 newport_allocattr(void *c
, int fg
, int bg
, int flags
, long *attr
)
851 if (flags
& WSATTR_BLINK
)
854 if ((flags
& WSATTR_WSCOLORS
) == 0) {
859 if (flags
& WSATTR_HILIT
)
862 if (flags
& WSATTR_REVERSE
) {
868 *attr
= NEWPORT_ATTR_ENCODE(fg
, bg
);
873 /**** wsdisplay accessops ****/
876 newport_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
879 struct vcons_data
*vd
;
880 struct newport_devconfig
*dc
;
881 struct vcons_screen
*ms
;
884 vd
= (struct vcons_data
*)v
;
885 dc
= (struct newport_devconfig
*)vd
->cookie
;
886 ms
= (struct vcons_screen
*)vd
->active
;
888 #define FBINFO (*(struct wsdisplay_fbinfo*)data)
891 case WSDISPLAYIO_GINFO
:
892 FBINFO
.width
= dc
->dc_xres
;
893 FBINFO
.height
= dc
->dc_yres
;
894 FBINFO
.depth
= dc
->dc_depth
;
895 FBINFO
.cmsize
= 1 << FBINFO
.depth
;
897 case WSDISPLAYIO_GTYPE
:
898 *(u_int
*)data
= WSDISPLAY_TYPE_NEWPORT
;
900 case WSDISPLAYIO_SMODE
:
901 nmode
= *(int *)data
;
902 if (nmode
!= dc
->dc_mode
) {
904 if (nmode
== WSDISPLAYIO_MODE_EMUL
) {
906 newport_setup_hw(dc
);
907 vcons_redraw_screen(vd
->active
);
916 newport_mmap(void *v
, void *vs
, off_t offset
, int prot
)
918 struct vcons_data
*vd
;
919 struct newport_devconfig
*dc
;
921 vd
= (struct vcons_data
*)v
;
922 dc
= (struct newport_devconfig
*)vd
->cookie
;
924 if ( offset
>= 0xfffff)
927 return mips_btop(dc
->dc_addr
+ offset
);