Home | History | Annotate | Line # | Download | only in gio
newport.c revision 1.5.4.4
      1  1.5.4.4  skrll /*	$NetBSD: newport.c,v 1.5.4.4 2004/09/21 13:21:13 skrll Exp $	*/
      2  1.5.4.2  skrll 
      3  1.5.4.2  skrll /*
      4  1.5.4.2  skrll  * Copyright (c) 2003 Ilpo Ruotsalainen
      5  1.5.4.2  skrll  * All rights reserved.
      6  1.5.4.2  skrll  *
      7  1.5.4.2  skrll  * Redistribution and use in source and binary forms, with or without
      8  1.5.4.2  skrll  * modification, are permitted provided that the following conditions
      9  1.5.4.2  skrll  * are met:
     10  1.5.4.2  skrll  * 1. Redistributions of source code must retain the above copyright
     11  1.5.4.2  skrll  *    notice, this list of conditions and the following disclaimer.
     12  1.5.4.2  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.5.4.2  skrll  *    notice, this list of conditions and the following disclaimer in the
     14  1.5.4.2  skrll  *    documentation and/or other materials provided with the distribution.
     15  1.5.4.2  skrll  * 3. The name of the author may not be used to endorse or promote products
     16  1.5.4.2  skrll  *    derived from this software without specific prior written permission.
     17  1.5.4.2  skrll  *
     18  1.5.4.2  skrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  1.5.4.2  skrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  1.5.4.2  skrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  1.5.4.2  skrll  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  1.5.4.2  skrll  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  1.5.4.2  skrll  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  1.5.4.2  skrll  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  1.5.4.2  skrll  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  1.5.4.2  skrll  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  1.5.4.2  skrll  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.5.4.2  skrll  *
     29  1.5.4.2  skrll  * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
     30  1.5.4.2  skrll  */
     31  1.5.4.2  skrll 
     32  1.5.4.2  skrll #include <sys/cdefs.h>
     33  1.5.4.4  skrll __KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.5.4.4 2004/09/21 13:21:13 skrll Exp $");
     34  1.5.4.2  skrll 
     35  1.5.4.2  skrll #include <sys/param.h>
     36  1.5.4.2  skrll #include <sys/systm.h>
     37  1.5.4.2  skrll #include <sys/device.h>
     38  1.5.4.2  skrll #include <sys/malloc.h>
     39  1.5.4.2  skrll 
     40  1.5.4.2  skrll #include <dev/wscons/wsconsio.h>
     41  1.5.4.2  skrll #include <dev/wscons/wsdisplayvar.h>
     42  1.5.4.2  skrll #include <dev/wsfont/wsfont.h>
     43  1.5.4.2  skrll 
     44  1.5.4.2  skrll #include <sgimips/gio/giovar.h>
     45  1.5.4.2  skrll #include <sgimips/gio/newportvar.h>
     46  1.5.4.2  skrll #include <sgimips/gio/newportreg.h>
     47  1.5.4.2  skrll 
     48  1.5.4.2  skrll struct newport_softc {
     49  1.5.4.2  skrll 	struct device sc_dev;
     50  1.5.4.2  skrll 
     51  1.5.4.2  skrll 	struct newport_devconfig *sc_dc;
     52  1.5.4.2  skrll };
     53  1.5.4.2  skrll 
     54  1.5.4.2  skrll struct newport_devconfig {
     55  1.5.4.2  skrll 	uint32_t		dc_addr;
     56  1.5.4.2  skrll 
     57  1.5.4.2  skrll 	bus_space_tag_t		dc_st;
     58  1.5.4.2  skrll 	bus_space_handle_t	dc_sh;
     59  1.5.4.2  skrll 
     60  1.5.4.2  skrll 	int			dc_boardrev;
     61  1.5.4.2  skrll 	int			dc_vc2rev;
     62  1.5.4.2  skrll 	int			dc_cmaprev;
     63  1.5.4.2  skrll 	int			dc_xmaprev;
     64  1.5.4.2  skrll 	int			dc_rexrev;
     65  1.5.4.2  skrll 	int			dc_xres;
     66  1.5.4.2  skrll 	int			dc_yres;
     67  1.5.4.2  skrll 	int			dc_depth;
     68  1.5.4.2  skrll 
     69  1.5.4.2  skrll 	int			dc_font;
     70  1.5.4.2  skrll 	struct wsdisplay_font	*dc_fontdata;
     71  1.5.4.2  skrll };
     72  1.5.4.2  skrll 
     73  1.5.4.2  skrll static int  newport_match(struct device *, struct cfdata *, void *);
     74  1.5.4.2  skrll static void newport_attach(struct device *, struct device *, void *);
     75  1.5.4.2  skrll 
     76  1.5.4.2  skrll CFATTACH_DECL(newport, sizeof(struct newport_softc),
     77  1.5.4.2  skrll     newport_match, newport_attach, NULL, NULL);
     78  1.5.4.2  skrll 
     79  1.5.4.2  skrll /* textops */
     80  1.5.4.2  skrll static void newport_cursor(void *, int, int, int);
     81  1.5.4.2  skrll static int  newport_mapchar(void *, int, unsigned int *);
     82  1.5.4.2  skrll static void newport_putchar(void *, int, int, u_int, long);
     83  1.5.4.2  skrll static void newport_copycols(void *, int, int, int, int);
     84  1.5.4.2  skrll static void newport_erasecols(void *, int, int, int, long);
     85  1.5.4.2  skrll static void newport_copyrows(void *, int, int, int);
     86  1.5.4.2  skrll static void newport_eraserows(void *, int, int, long);
     87  1.5.4.2  skrll static int  newport_allocattr(void *, int, int, int, long *);
     88  1.5.4.2  skrll 
     89  1.5.4.2  skrll /* accessops */
     90  1.5.4.2  skrll static int     newport_ioctl(void *, u_long, caddr_t, int, struct proc *);
     91  1.5.4.2  skrll static paddr_t newport_mmap(void *, off_t, int);
     92  1.5.4.2  skrll static int     newport_alloc_screen(void *, const struct wsscreen_descr *,
     93  1.5.4.2  skrll     void **, int *, int *, long *);
     94  1.5.4.2  skrll static void    newport_free_screen(void *, void *);
     95  1.5.4.2  skrll static int     newport_show_screen(void *, void *, int,
     96  1.5.4.2  skrll     void (*)(void *, int, int), void *);
     97  1.5.4.2  skrll 
     98  1.5.4.2  skrll static const struct wsdisplay_emulops newport_textops = {
     99  1.5.4.2  skrll 	.cursor		= newport_cursor,
    100  1.5.4.2  skrll 	.mapchar	= newport_mapchar,
    101  1.5.4.2  skrll 	.putchar	= newport_putchar,
    102  1.5.4.2  skrll 	.copycols	= newport_copycols,
    103  1.5.4.2  skrll 	.erasecols	= newport_erasecols,
    104  1.5.4.2  skrll 	.copyrows	= newport_copyrows,
    105  1.5.4.2  skrll 	.eraserows	= newport_eraserows,
    106  1.5.4.2  skrll 	.allocattr	= newport_allocattr
    107  1.5.4.2  skrll };
    108  1.5.4.2  skrll 
    109  1.5.4.2  skrll static const struct wsdisplay_accessops newport_accessops = {
    110  1.5.4.2  skrll 	.ioctl		= newport_ioctl,
    111  1.5.4.2  skrll 	.mmap		= newport_mmap,
    112  1.5.4.2  skrll 	.alloc_screen	= newport_alloc_screen,
    113  1.5.4.2  skrll 	.free_screen	= newport_free_screen,
    114  1.5.4.2  skrll 	.show_screen	= newport_show_screen,
    115  1.5.4.2  skrll };
    116  1.5.4.2  skrll 
    117  1.5.4.2  skrll static const struct wsscreen_descr newport_screen_1024x768 = {
    118  1.5.4.2  skrll 	.name		= "1024x768",
    119  1.5.4.2  skrll 	.ncols		= 128,
    120  1.5.4.2  skrll 	.nrows		= 48,
    121  1.5.4.2  skrll 	.textops	= &newport_textops,
    122  1.5.4.2  skrll 	.fontwidth	= 8,
    123  1.5.4.2  skrll 	.fontheight	= 16,
    124  1.5.4.2  skrll 	.capabilities	= WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
    125  1.5.4.2  skrll };
    126  1.5.4.2  skrll 
    127  1.5.4.2  skrll static const struct wsscreen_descr newport_screen_1280x1024 = {
    128  1.5.4.2  skrll 	.name		= "1280x1024",
    129  1.5.4.2  skrll 	.ncols		= 160,
    130  1.5.4.2  skrll 	.nrows		= 64,
    131  1.5.4.2  skrll 	.textops	= &newport_textops,
    132  1.5.4.2  skrll 	.fontwidth	= 8,
    133  1.5.4.2  skrll 	.fontheight	= 16,
    134  1.5.4.2  skrll 	.capabilities	= WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
    135  1.5.4.2  skrll };
    136  1.5.4.2  skrll 
    137  1.5.4.2  skrll static const struct wsscreen_descr *_newport_screenlist[] = {
    138  1.5.4.2  skrll 	&newport_screen_1024x768,
    139  1.5.4.2  skrll 	&newport_screen_1280x1024
    140  1.5.4.2  skrll };
    141  1.5.4.2  skrll 
    142  1.5.4.2  skrll static const struct wsscreen_list newport_screenlist = {
    143  1.5.4.2  skrll 	sizeof(_newport_screenlist) / sizeof(struct wsscreen_descr *),
    144  1.5.4.2  skrll 	_newport_screenlist
    145  1.5.4.2  skrll };
    146  1.5.4.2  skrll 
    147  1.5.4.2  skrll static struct newport_devconfig newport_console_dc;
    148  1.5.4.2  skrll static int newport_is_console = 0;
    149  1.5.4.2  skrll 
    150  1.5.4.2  skrll #define NEWPORT_ATTR_ENCODE(fg,bg)	(((fg) << 8) | (bg))
    151  1.5.4.2  skrll #define NEWPORT_ATTR_BG(a)		((a) & 0xff)
    152  1.5.4.2  skrll #define NEWPORT_ATTR_FG(a)		(((a) >> 8) & 0xff)
    153  1.5.4.2  skrll 
    154  1.5.4.2  skrll static const uint16_t newport_cursor_data[128] = {
    155  1.5.4.2  skrll 	/* Bit 0 */
    156  1.5.4.2  skrll 	0xff00, 0x0000,
    157  1.5.4.2  skrll 	0xff00, 0x0000,
    158  1.5.4.2  skrll 	0xff00, 0x0000,
    159  1.5.4.2  skrll 	0xff00, 0x0000,
    160  1.5.4.2  skrll 	0xff00, 0x0000,
    161  1.5.4.2  skrll 	0xff00, 0x0000,
    162  1.5.4.2  skrll 	0xff00, 0x0000,
    163  1.5.4.2  skrll 	0xff00, 0x0000,
    164  1.5.4.2  skrll 	0xff00, 0x0000,
    165  1.5.4.2  skrll 	0xff00, 0x0000,
    166  1.5.4.2  skrll 	0xff00, 0x0000,
    167  1.5.4.2  skrll 	0xff00, 0x0000,
    168  1.5.4.2  skrll 	0xff00, 0x0000,
    169  1.5.4.2  skrll 	0xff00, 0x0000,
    170  1.5.4.2  skrll 	0xff00, 0x0000,
    171  1.5.4.2  skrll 	0xff00, 0x0000,
    172  1.5.4.2  skrll 	0x0000, 0x0000,
    173  1.5.4.2  skrll 	0x0000, 0x0000,
    174  1.5.4.2  skrll 	0x0000, 0x0000,
    175  1.5.4.2  skrll 	0x0000, 0x0000,
    176  1.5.4.2  skrll 	0x0000, 0x0000,
    177  1.5.4.2  skrll 	0x0000, 0x0000,
    178  1.5.4.2  skrll 	0x0000, 0x0000,
    179  1.5.4.2  skrll 	0x0000, 0x0000,
    180  1.5.4.2  skrll 	0x0000, 0x0000,
    181  1.5.4.2  skrll 	0x0000, 0x0000,
    182  1.5.4.2  skrll 	0x0000, 0x0000,
    183  1.5.4.2  skrll 	0x0000, 0x0000,
    184  1.5.4.2  skrll 	0x0000, 0x0000,
    185  1.5.4.2  skrll 	0x0000, 0x0000,
    186  1.5.4.2  skrll 	0x0000, 0x0000,
    187  1.5.4.2  skrll 	0x0000, 0x0000,
    188  1.5.4.2  skrll 
    189  1.5.4.2  skrll 	/* Bit 1 */
    190  1.5.4.2  skrll 	0x0000, 0x0000,
    191  1.5.4.2  skrll 	0x0000, 0x0000,
    192  1.5.4.2  skrll 	0x0000, 0x0000,
    193  1.5.4.2  skrll 	0x0000, 0x0000,
    194  1.5.4.2  skrll 	0x0000, 0x0000,
    195  1.5.4.2  skrll 	0x0000, 0x0000,
    196  1.5.4.2  skrll 	0x0000, 0x0000,
    197  1.5.4.2  skrll 	0x0000, 0x0000,
    198  1.5.4.2  skrll 	0x0000, 0x0000,
    199  1.5.4.2  skrll 	0x0000, 0x0000,
    200  1.5.4.2  skrll 	0x0000, 0x0000,
    201  1.5.4.2  skrll 	0x0000, 0x0000,
    202  1.5.4.2  skrll 	0x0000, 0x0000,
    203  1.5.4.2  skrll 	0x0000, 0x0000,
    204  1.5.4.2  skrll 	0x0000, 0x0000,
    205  1.5.4.2  skrll 	0x0000, 0x0000,
    206  1.5.4.2  skrll 	0x0000, 0x0000,
    207  1.5.4.2  skrll 	0x0000, 0x0000,
    208  1.5.4.2  skrll 	0x0000, 0x0000,
    209  1.5.4.2  skrll 	0x0000, 0x0000,
    210  1.5.4.2  skrll 	0x0000, 0x0000,
    211  1.5.4.2  skrll 	0x0000, 0x0000,
    212  1.5.4.2  skrll 	0x0000, 0x0000,
    213  1.5.4.2  skrll 	0x0000, 0x0000,
    214  1.5.4.2  skrll 	0x0000, 0x0000,
    215  1.5.4.2  skrll 	0x0000, 0x0000,
    216  1.5.4.2  skrll 	0x0000, 0x0000,
    217  1.5.4.2  skrll 	0x0000, 0x0000,
    218  1.5.4.2  skrll 	0x0000, 0x0000,
    219  1.5.4.2  skrll 	0x0000, 0x0000,
    220  1.5.4.2  skrll 	0x0000, 0x0000,
    221  1.5.4.2  skrll 	0x0000, 0x0000,
    222  1.5.4.2  skrll };
    223  1.5.4.2  skrll 
    224  1.5.4.2  skrll static const uint8_t newport_defcmap[16*3] = {
    225  1.5.4.2  skrll 	/* Normal colors */
    226  1.5.4.2  skrll 	0x00, 0x00, 0x00, /* black */
    227  1.5.4.2  skrll 	0x7f, 0x00, 0x00, /* red */
    228  1.5.4.2  skrll 	0x00, 0x7f, 0x00, /* green */
    229  1.5.4.2  skrll 	0x7f, 0x7f, 0x00, /* brown */
    230  1.5.4.2  skrll 	0x00, 0x00, 0x7f, /* blue */
    231  1.5.4.2  skrll 	0x7f, 0x00, 0x7f, /* magenta */
    232  1.5.4.2  skrll 	0x00, 0x7f, 0x7f, /* cyan */
    233  1.5.4.2  skrll 	0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
    234  1.5.4.2  skrll 
    235  1.5.4.2  skrll 	/* Hilite colors */
    236  1.5.4.2  skrll 	0x7f, 0x7f, 0x7f, /* black */
    237  1.5.4.2  skrll 	0xff, 0x00, 0x00, /* red */
    238  1.5.4.2  skrll 	0x00, 0xff, 0x00, /* green */
    239  1.5.4.2  skrll 	0xff, 0xff, 0x00, /* brown */
    240  1.5.4.2  skrll 	0x00, 0x00, 0xff, /* blue */
    241  1.5.4.2  skrll 	0xff, 0x00, 0xff, /* magenta */
    242  1.5.4.2  skrll 	0x00, 0xff, 0xff, /* cyan */
    243  1.5.4.2  skrll 	0xff, 0xff, 0xff, /* white */
    244  1.5.4.2  skrll };
    245  1.5.4.2  skrll 
    246  1.5.4.2  skrll /**** Low-level hardware register groveling functions ****/
    247  1.5.4.2  skrll static void
    248  1.5.4.2  skrll rex3_write(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
    249  1.5.4.2  skrll {
    250  1.5.4.2  skrll 	bus_space_write_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg,
    251  1.5.4.2  skrll 	    val);
    252  1.5.4.2  skrll }
    253  1.5.4.2  skrll 
    254  1.5.4.2  skrll static void
    255  1.5.4.2  skrll rex3_write_go(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
    256  1.5.4.2  skrll {
    257  1.5.4.2  skrll 	rex3_write(dc, rexreg + REX3_REG_GO, val);
    258  1.5.4.2  skrll }
    259  1.5.4.2  skrll 
    260  1.5.4.2  skrll static uint32_t
    261  1.5.4.2  skrll rex3_read(struct newport_devconfig *dc, bus_size_t rexreg)
    262  1.5.4.2  skrll {
    263  1.5.4.2  skrll 	return bus_space_read_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET +
    264  1.5.4.2  skrll 	    rexreg);
    265  1.5.4.2  skrll }
    266  1.5.4.2  skrll 
    267  1.5.4.2  skrll static void
    268  1.5.4.2  skrll rex3_wait_gfifo(struct newport_devconfig *dc)
    269  1.5.4.2  skrll {
    270  1.5.4.2  skrll 	while (rex3_read(dc, REX3_REG_STATUS) & REX3_STATUS_GFXBUSY)
    271  1.5.4.2  skrll 		;
    272  1.5.4.2  skrll }
    273  1.5.4.2  skrll 
    274  1.5.4.2  skrll static void
    275  1.5.4.2  skrll vc2_write_ireg(struct newport_devconfig *dc, uint8_t ireg, uint16_t val)
    276  1.5.4.2  skrll {
    277  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    278  1.5.4.2  skrll 	    REX3_DCBMODE_DW_3 |
    279  1.5.4.2  skrll 	    REX3_DCBMODE_ENCRSINC |
    280  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
    281  1.5.4.2  skrll 	    (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
    282  1.5.4.2  skrll 	    REX3_DCBMODE_ENASYNCACK |
    283  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    284  1.5.4.2  skrll 
    285  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, (ireg << 24) | (val << 8));
    286  1.5.4.2  skrll }
    287  1.5.4.2  skrll 
    288  1.5.4.2  skrll static uint16_t
    289  1.5.4.2  skrll vc2_read_ireg(struct newport_devconfig *dc, uint8_t ireg)
    290  1.5.4.2  skrll {
    291  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    292  1.5.4.2  skrll 	    REX3_DCBMODE_DW_1 |
    293  1.5.4.2  skrll 	    REX3_DCBMODE_ENCRSINC |
    294  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
    295  1.5.4.2  skrll 	    (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
    296  1.5.4.2  skrll 	    REX3_DCBMODE_ENASYNCACK |
    297  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    298  1.5.4.2  skrll 
    299  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, ireg << 24);
    300  1.5.4.2  skrll 
    301  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    302  1.5.4.2  skrll 	    REX3_DCBMODE_DW_2 |
    303  1.5.4.2  skrll 	    REX3_DCBMODE_ENCRSINC |
    304  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
    305  1.5.4.2  skrll 	    (VC2_DCBCRS_IREG << REX3_DCBMODE_DCBCRS_SHIFT) |
    306  1.5.4.2  skrll 	    REX3_DCBMODE_ENASYNCACK |
    307  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    308  1.5.4.2  skrll 
    309  1.5.4.2  skrll 	return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
    310  1.5.4.2  skrll }
    311  1.5.4.2  skrll 
    312  1.5.4.2  skrll static uint16_t
    313  1.5.4.2  skrll vc2_read_ram(struct newport_devconfig *dc, uint16_t addr)
    314  1.5.4.2  skrll {
    315  1.5.4.2  skrll 	vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
    316  1.5.4.2  skrll 
    317  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    318  1.5.4.2  skrll 	    REX3_DCBMODE_DW_2 |
    319  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
    320  1.5.4.2  skrll 	    (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
    321  1.5.4.2  skrll 	    REX3_DCBMODE_ENASYNCACK |
    322  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    323  1.5.4.2  skrll 
    324  1.5.4.2  skrll 	return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
    325  1.5.4.2  skrll }
    326  1.5.4.2  skrll 
    327  1.5.4.2  skrll static void
    328  1.5.4.2  skrll vc2_write_ram(struct newport_devconfig *dc, uint16_t addr, uint16_t val)
    329  1.5.4.2  skrll {
    330  1.5.4.2  skrll 	vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
    331  1.5.4.2  skrll 
    332  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    333  1.5.4.2  skrll 	    REX3_DCBMODE_DW_2 |
    334  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
    335  1.5.4.2  skrll 	    (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
    336  1.5.4.2  skrll 	    REX3_DCBMODE_ENASYNCACK |
    337  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    338  1.5.4.2  skrll 
    339  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, val << 16);
    340  1.5.4.2  skrll }
    341  1.5.4.2  skrll 
    342  1.5.4.2  skrll static u_int32_t
    343  1.5.4.2  skrll xmap9_read(struct newport_devconfig *dc, int crs)
    344  1.5.4.2  skrll {
    345  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    346  1.5.4.2  skrll 		REX3_DCBMODE_DW_1 |
    347  1.5.4.2  skrll 		(NEWPORT_DCBADDR_XMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
    348  1.5.4.2  skrll 		(crs << REX3_DCBMODE_DCBCRS_SHIFT) |
    349  1.5.4.2  skrll 		(3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    350  1.5.4.2  skrll 		(2 << REX3_DCBMODE_CSHOLD_SHIFT) |
    351  1.5.4.2  skrll 		(1 << REX3_DCBMODE_CSSETUP_SHIFT));
    352  1.5.4.2  skrll 	return rex3_read(dc, REX3_REG_DCBDATA0);
    353  1.5.4.2  skrll }
    354  1.5.4.2  skrll 
    355  1.5.4.2  skrll static void
    356  1.5.4.2  skrll xmap9_write(struct newport_devconfig *dc, int crs, uint8_t val)
    357  1.5.4.2  skrll {
    358  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    359  1.5.4.2  skrll 	    REX3_DCBMODE_DW_1 |
    360  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
    361  1.5.4.2  skrll 	    (crs << REX3_DCBMODE_DCBCRS_SHIFT) |
    362  1.5.4.2  skrll 	    (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    363  1.5.4.2  skrll 	    (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
    364  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    365  1.5.4.2  skrll 
    366  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, val << 24);
    367  1.5.4.2  skrll }
    368  1.5.4.2  skrll 
    369  1.5.4.2  skrll static void
    370  1.5.4.2  skrll xmap9_write_mode(struct newport_devconfig *dc, uint8_t index, uint32_t mode)
    371  1.5.4.2  skrll {
    372  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    373  1.5.4.2  skrll 	    REX3_DCBMODE_DW_4 |
    374  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
    375  1.5.4.2  skrll 	    (XMAP9_DCBCRS_MODE_SETUP << REX3_DCBMODE_DCBCRS_SHIFT) |
    376  1.5.4.2  skrll 	    (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    377  1.5.4.2  skrll 	    (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
    378  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    379  1.5.4.2  skrll 
    380  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, (index << 24) | mode);
    381  1.5.4.2  skrll }
    382  1.5.4.2  skrll 
    383  1.5.4.2  skrll /**** Helper functions ****/
    384  1.5.4.2  skrll static void
    385  1.5.4.2  skrll newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
    386  1.5.4.2  skrll     int y2, uint8_t color)
    387  1.5.4.2  skrll {
    388  1.5.4.2  skrll 	rex3_wait_gfifo(dc);
    389  1.5.4.2  skrll 
    390  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
    391  1.5.4.2  skrll 	    REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
    392  1.5.4.2  skrll 	    REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
    393  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
    394  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_COLORI, color);
    395  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
    396  1.5.4.2  skrll 
    397  1.5.4.2  skrll 	rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
    398  1.5.4.2  skrll }
    399  1.5.4.2  skrll 
    400  1.5.4.2  skrll static void
    401  1.5.4.2  skrll newport_copy_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
    402  1.5.4.2  skrll     int y2, int dx, int dy)
    403  1.5.4.2  skrll {
    404  1.5.4.2  skrll 	uint32_t tmp;
    405  1.5.4.2  skrll 
    406  1.5.4.2  skrll 	rex3_wait_gfifo(dc);
    407  1.5.4.2  skrll 
    408  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR |
    409  1.5.4.2  skrll 	    REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
    410  1.5.4.2  skrll 	    REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
    411  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
    412  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
    413  1.5.4.2  skrll 
    414  1.5.4.2  skrll 	tmp = (dy - y1) & 0xffff;
    415  1.5.4.2  skrll 	tmp |= (dx - x1) << REX3_XYMOVE_XSHIFT;
    416  1.5.4.2  skrll 
    417  1.5.4.2  skrll 	rex3_write_go(dc, REX3_REG_XYMOVE, tmp);
    418  1.5.4.2  skrll }
    419  1.5.4.2  skrll 
    420  1.5.4.2  skrll static void
    421  1.5.4.2  skrll newport_cmap_setrgb(struct newport_devconfig *dc, int index, uint8_t r,
    422  1.5.4.2  skrll     uint8_t g, uint8_t b)
    423  1.5.4.2  skrll {
    424  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    425  1.5.4.2  skrll 	    REX3_DCBMODE_DW_2 |
    426  1.5.4.2  skrll 	    REX3_DCBMODE_ENCRSINC |
    427  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
    428  1.5.4.2  skrll 	    (CMAP_DCBCRS_ADDRESS_LOW << REX3_DCBMODE_DCBCRS_SHIFT) |
    429  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    430  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
    431  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT) |
    432  1.5.4.2  skrll 	    REX3_DCBMODE_SWAPENDIAN);
    433  1.5.4.2  skrll 
    434  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, index << 16);
    435  1.5.4.2  skrll 
    436  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    437  1.5.4.2  skrll 	    REX3_DCBMODE_DW_3 |
    438  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
    439  1.5.4.2  skrll 	    (CMAP_DCBCRS_PALETTE << REX3_DCBMODE_DCBCRS_SHIFT) |
    440  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    441  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
    442  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    443  1.5.4.2  skrll 
    444  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBDATA0, (r << 24) + (g << 16) + (b << 8));
    445  1.5.4.2  skrll }
    446  1.5.4.2  skrll 
    447  1.5.4.2  skrll static void
    448  1.5.4.2  skrll newport_get_resolution(struct newport_devconfig *dc)
    449  1.5.4.2  skrll {
    450  1.5.4.2  skrll 	uint16_t vep,lines;
    451  1.5.4.2  skrll 	uint16_t linep,cols;
    452  1.5.4.2  skrll 	uint16_t data;
    453  1.5.4.2  skrll 
    454  1.5.4.2  skrll 	vep = vc2_read_ireg(dc, VC2_IREG_VIDEO_ENTRY);
    455  1.5.4.2  skrll 
    456  1.5.4.2  skrll 	dc->dc_xres = 0;
    457  1.5.4.2  skrll 	dc->dc_yres = 0;
    458  1.5.4.2  skrll 
    459  1.5.4.2  skrll 	for (;;) {
    460  1.5.4.2  skrll 		/* Iterate over runs in video timing table */
    461  1.5.4.2  skrll 
    462  1.5.4.2  skrll 		cols = 0;
    463  1.5.4.2  skrll 
    464  1.5.4.2  skrll 		linep = vc2_read_ram(dc, vep++);
    465  1.5.4.2  skrll 		lines = vc2_read_ram(dc, vep++);
    466  1.5.4.2  skrll 
    467  1.5.4.2  skrll 		if (lines == 0)
    468  1.5.4.2  skrll 			break;
    469  1.5.4.2  skrll 
    470  1.5.4.2  skrll 		do {
    471  1.5.4.2  skrll 			/* Iterate over state runs in line sequence table */
    472  1.5.4.2  skrll 
    473  1.5.4.2  skrll 			data = vc2_read_ram(dc, linep++);
    474  1.5.4.2  skrll 
    475  1.5.4.2  skrll 			if ((data & 0x0001) == 0)
    476  1.5.4.2  skrll 				cols += (data >> 7) & 0xfe;
    477  1.5.4.2  skrll 
    478  1.5.4.2  skrll 			if ((data & 0x0080) == 0)
    479  1.5.4.2  skrll 				data = vc2_read_ram(dc, linep++);
    480  1.5.4.2  skrll 		} while ((data & 0x8000) == 0);
    481  1.5.4.2  skrll 
    482  1.5.4.2  skrll 		if (cols != 0) {
    483  1.5.4.2  skrll 			if (cols > dc->dc_xres)
    484  1.5.4.2  skrll 				dc->dc_xres = cols;
    485  1.5.4.2  skrll 
    486  1.5.4.2  skrll 			dc->dc_yres += lines;
    487  1.5.4.2  skrll 		}
    488  1.5.4.2  skrll 	}
    489  1.5.4.2  skrll }
    490  1.5.4.2  skrll 
    491  1.5.4.2  skrll static void
    492  1.5.4.2  skrll newport_setup_hw(struct newport_devconfig *dc)
    493  1.5.4.2  skrll {
    494  1.5.4.2  skrll 	uint16_t curp,tmp;
    495  1.5.4.2  skrll 	int i;
    496  1.5.4.2  skrll 	uint32_t scratch;
    497  1.5.4.2  skrll 
    498  1.5.4.2  skrll 	/* Get various revisions */
    499  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DCBMODE,
    500  1.5.4.2  skrll 	    REX3_DCBMODE_DW_1 |
    501  1.5.4.2  skrll 	    (NEWPORT_DCBADDR_CMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
    502  1.5.4.2  skrll 	    (CMAP_DCBCRS_REVISION << REX3_DCBMODE_DCBCRS_SHIFT) |
    503  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
    504  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
    505  1.5.4.2  skrll 	    (1 << REX3_DCBMODE_CSSETUP_SHIFT));
    506  1.5.4.2  skrll 
    507  1.5.4.2  skrll 	scratch = vc2_read_ireg(dc, VC2_IREG_CONFIG);
    508  1.5.4.2  skrll 	dc->dc_vc2rev = (scratch & VC2_IREG_CONFIG_REVISION) >> 5;
    509  1.5.4.2  skrll 
    510  1.5.4.2  skrll 	scratch = rex3_read(dc, REX3_REG_DCBDATA0);
    511  1.5.4.2  skrll 
    512  1.5.4.2  skrll 	dc->dc_boardrev = (scratch >> 28) & 0x07;
    513  1.5.4.2  skrll 	dc->dc_cmaprev = scratch & 0x07;
    514  1.5.4.2  skrll 	dc->dc_xmaprev = xmap9_read(dc, XMAP9_DCBCRS_REVISION) & 0x07;
    515  1.5.4.2  skrll 	dc->dc_depth = ( (dc->dc_boardrev > 1) && (scratch & 0x80)) ? 8 : 24;
    516  1.5.4.2  skrll 
    517  1.5.4.2  skrll 	/* Setup cursor glyph */
    518  1.5.4.2  skrll 	curp = vc2_read_ireg(dc, VC2_IREG_CURSOR_ENTRY);
    519  1.5.4.2  skrll 
    520  1.5.4.2  skrll 	for (i=0; i<128; i++)
    521  1.5.4.2  skrll 		vc2_write_ram(dc, curp + i, newport_cursor_data[i]);
    522  1.5.4.2  skrll 
    523  1.5.4.2  skrll 	/* Setup VC2 to a known state */
    524  1.5.4.2  skrll 	tmp = vc2_read_ireg(dc, VC2_IREG_CONTROL) & VC2_CONTROL_INTERLACE;
    525  1.5.4.2  skrll 	vc2_write_ireg(dc, VC2_IREG_CONTROL, tmp |
    526  1.5.4.2  skrll 	    VC2_CONTROL_DISPLAY_ENABLE |
    527  1.5.4.2  skrll 	    VC2_CONTROL_VTIMING_ENABLE |
    528  1.5.4.2  skrll 	    VC2_CONTROL_DID_ENABLE |
    529  1.5.4.2  skrll 	    VC2_CONTROL_CURSORFUNC_ENABLE |
    530  1.5.4.2  skrll 	    VC2_CONTROL_CURSOR_ENABLE);
    531  1.5.4.2  skrll 
    532  1.5.4.2  skrll 	/* Setup XMAP9s */
    533  1.5.4.2  skrll 	xmap9_write(dc, XMAP9_DCBCRS_CONFIG,
    534  1.5.4.2  skrll 	    XMAP9_CONFIG_8BIT_SYSTEM | XMAP9_CONFIG_RGBMAP_CI);
    535  1.5.4.2  skrll 
    536  1.5.4.2  skrll 	xmap9_write(dc, XMAP9_DCBCRS_CURSOR_CMAP, 0);
    537  1.5.4.2  skrll 
    538  1.5.4.2  skrll 	xmap9_write_mode(dc, 0,
    539  1.5.4.2  skrll 	    XMAP9_MODE_GAMMA_BYPASS |
    540  1.5.4.2  skrll 	    XMAP9_MODE_PIXSIZE_8BPP);
    541  1.5.4.2  skrll 	xmap9_write(dc, XMAP9_DCBCRS_MODE_SELECT, 0);
    542  1.5.4.2  skrll 
    543  1.5.4.2  skrll 	/* Setup REX3 */
    544  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DRAWMODE1,
    545  1.5.4.2  skrll 	    REX3_DRAWMODE1_PLANES_CI |
    546  1.5.4.2  skrll 	    REX3_DRAWMODE1_DD_DD8 |
    547  1.5.4.2  skrll 	    REX3_DRAWMODE1_RWPACKED |
    548  1.5.4.2  skrll 	    REX3_DRAWMODE1_HD_HD8 |
    549  1.5.4.2  skrll 	    REX3_DRAWMODE1_COMPARE_LT |
    550  1.5.4.2  skrll 	    REX3_DRAWMODE1_COMPARE_EQ |
    551  1.5.4.2  skrll 	    REX3_DRAWMODE1_COMPARE_GT |
    552  1.5.4.2  skrll 	    REX3_DRAWMODE1_LO_SRC);
    553  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096);
    554  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */
    555  1.5.4.2  skrll 
    556  1.5.4.2  skrll 	/* Setup CMAP */
    557  1.5.4.2  skrll 	for (i=0; i<16; i++)
    558  1.5.4.2  skrll 		newport_cmap_setrgb(dc, i, newport_defcmap[i*3],
    559  1.5.4.2  skrll 		    newport_defcmap[i*3 + 1], newport_defcmap[i*3 + 2]);
    560  1.5.4.2  skrll }
    561  1.5.4.2  skrll 
    562  1.5.4.2  skrll /**** Attach routines ****/
    563  1.5.4.2  skrll static int
    564  1.5.4.2  skrll newport_match(struct device *parent, struct cfdata *self, void *aux)
    565  1.5.4.2  skrll {
    566  1.5.4.2  skrll 	struct gio_attach_args *ga = aux;
    567  1.5.4.2  skrll 
    568  1.5.4.2  skrll 	/* newport doesn't decode all addresses */
    569  1.5.4.2  skrll 	if (ga->ga_addr != 0x1f000000 && ga->ga_addr != 0x1f400000 &&
    570  1.5.4.2  skrll 	    ga->ga_addr != 0x1f800000 && ga->ga_addr != 0x1fc00000)
    571  1.5.4.2  skrll 		return 0;
    572  1.5.4.2  skrll 
    573  1.5.4.2  skrll 	/* newport doesn't respond with correct product id, empirically
    574  1.5.4.2  skrll 	 * both empty slots and newports seem to yield this result */
    575  1.5.4.2  skrll 	if (ga->ga_product != 0x04)
    576  1.5.4.2  skrll 		return 0;
    577  1.5.4.2  skrll 
    578  1.5.4.2  skrll 	/* Don't do the destructive probe if we're already attached */
    579  1.5.4.2  skrll 	if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr)
    580  1.5.4.2  skrll 		return 1;
    581  1.5.4.2  skrll 
    582  1.5.4.2  skrll 	/* Ugly, this probe is destructive, blame SGI... */
    583  1.5.4.2  skrll 	/* XXX Should be bus_space_peek/bus_space_poke XXX */
    584  1.5.4.2  skrll 	bus_space_write_4(ga->ga_iot, ga->ga_ioh,
    585  1.5.4.2  skrll 	    NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI, 0x12345678);
    586  1.5.4.2  skrll 	if (bus_space_read_4(ga->ga_iot, ga->ga_ioh,
    587  1.5.4.2  skrll 	      NEWPORT_REX3_OFFSET + REX3_REG_XSTART)
    588  1.5.4.2  skrll 	    != ((0x12345678 & 0xffff) << 11))
    589  1.5.4.2  skrll 		return 0;
    590  1.5.4.2  skrll 
    591  1.5.4.2  skrll 	return 1;
    592  1.5.4.2  skrll }
    593  1.5.4.2  skrll 
    594  1.5.4.2  skrll static void
    595  1.5.4.2  skrll newport_attach_common(struct newport_devconfig *dc, struct gio_attach_args *ga)
    596  1.5.4.2  skrll {
    597  1.5.4.2  skrll 	dc->dc_addr = ga->ga_addr;
    598  1.5.4.2  skrll 
    599  1.5.4.2  skrll 	dc->dc_st = ga->ga_iot;
    600  1.5.4.2  skrll 	dc->dc_sh = ga->ga_ioh;
    601  1.5.4.2  skrll 
    602  1.5.4.2  skrll 	wsfont_init();
    603  1.5.4.2  skrll 
    604  1.5.4.2  skrll 	dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
    605  1.5.4.2  skrll 	    WSDISPLAY_FONTORDER_L2R);
    606  1.5.4.2  skrll 	if (dc->dc_font < 0)
    607  1.5.4.2  skrll 		panic("newport_attach_common: no suitable fonts");
    608  1.5.4.2  skrll 
    609  1.5.4.2  skrll 	if (wsfont_lock(dc->dc_font, &dc->dc_fontdata))
    610  1.5.4.2  skrll 		panic("newport_attach_common: unable to lock font data");
    611  1.5.4.2  skrll 
    612  1.5.4.2  skrll 	newport_setup_hw(dc);
    613  1.5.4.2  skrll 
    614  1.5.4.2  skrll 	newport_get_resolution(dc);
    615  1.5.4.2  skrll 
    616  1.5.4.2  skrll 	newport_fill_rectangle(dc, 0, 0, dc->dc_xres, dc->dc_yres, 0);
    617  1.5.4.2  skrll }
    618  1.5.4.2  skrll 
    619  1.5.4.2  skrll static void
    620  1.5.4.2  skrll newport_attach(struct device *parent, struct device *self, void *aux)
    621  1.5.4.2  skrll {
    622  1.5.4.2  skrll 	struct gio_attach_args *ga = aux;
    623  1.5.4.2  skrll 	struct newport_softc *sc = (void *)self;
    624  1.5.4.2  skrll 	struct wsemuldisplaydev_attach_args wa;
    625  1.5.4.2  skrll 
    626  1.5.4.2  skrll 	if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) {
    627  1.5.4.2  skrll 		wa.console = 1;
    628  1.5.4.2  skrll 		sc->sc_dc = &newport_console_dc;
    629  1.5.4.2  skrll 	} else {
    630  1.5.4.2  skrll 		wa.console = 0;
    631  1.5.4.2  skrll 		sc->sc_dc = malloc(sizeof(struct newport_devconfig),
    632  1.5.4.2  skrll 		    M_DEVBUF, M_WAITOK | M_ZERO);
    633  1.5.4.2  skrll 		if (sc->sc_dc == NULL)
    634  1.5.4.2  skrll 			panic("newport_attach: out of memory");
    635  1.5.4.2  skrll 
    636  1.5.4.2  skrll 		newport_attach_common(sc->sc_dc, ga);
    637  1.5.4.2  skrll 	}
    638  1.5.4.2  skrll 
    639  1.5.4.2  skrll 	aprint_naive(": Display adapter\n");
    640  1.5.4.2  skrll 
    641  1.5.4.2  skrll 	aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n",
    642  1.5.4.2  skrll 	    sc->sc_dc->dc_boardrev, sc->sc_dc->dc_cmaprev,
    643  1.5.4.2  skrll 	    sc->sc_dc->dc_xmaprev, sc->sc_dc->dc_vc2rev, sc->sc_dc->dc_depth);
    644  1.5.4.2  skrll 
    645  1.5.4.2  skrll 	wa.scrdata = &newport_screenlist;
    646  1.5.4.2  skrll 	wa.accessops = &newport_accessops;
    647  1.5.4.2  skrll 	wa.accesscookie = sc->sc_dc;
    648  1.5.4.2  skrll 
    649  1.5.4.2  skrll 	config_found(&sc->sc_dev, &wa, wsemuldisplaydevprint);
    650  1.5.4.2  skrll }
    651  1.5.4.2  skrll 
    652  1.5.4.2  skrll int
    653  1.5.4.2  skrll newport_cnattach(struct gio_attach_args *ga)
    654  1.5.4.2  skrll {
    655  1.5.4.2  skrll 	long defattr = NEWPORT_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK);
    656  1.5.4.2  skrll 	const struct wsscreen_descr *screen;
    657  1.5.4.2  skrll 
    658  1.5.4.2  skrll 	if (!newport_match(NULL, NULL, ga)) {
    659  1.5.4.2  skrll 		return ENXIO;
    660  1.5.4.2  skrll 	}
    661  1.5.4.2  skrll 
    662  1.5.4.2  skrll 	newport_attach_common(&newport_console_dc, ga);
    663  1.5.4.2  skrll 
    664  1.5.4.2  skrll 	if (newport_console_dc.dc_xres >= 1280 &&
    665  1.5.4.2  skrll 	    newport_console_dc.dc_yres >= 1024)
    666  1.5.4.2  skrll 		screen = &newport_screen_1280x1024;
    667  1.5.4.2  skrll 	else
    668  1.5.4.2  skrll 		screen = &newport_screen_1024x768;
    669  1.5.4.2  skrll 
    670  1.5.4.2  skrll 	wsdisplay_cnattach(screen, &newport_console_dc, 0, 0, defattr);
    671  1.5.4.2  skrll 
    672  1.5.4.2  skrll 	newport_is_console = 1;
    673  1.5.4.2  skrll 
    674  1.5.4.2  skrll 	return 0;
    675  1.5.4.2  skrll }
    676  1.5.4.2  skrll 
    677  1.5.4.2  skrll /**** wsdisplay textops ****/
    678  1.5.4.2  skrll static void
    679  1.5.4.2  skrll newport_cursor(void *c, int on, int row, int col)
    680  1.5.4.2  skrll {
    681  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    682  1.5.4.2  skrll 	uint16_t control;
    683  1.5.4.2  skrll 	int x_offset;
    684  1.5.4.2  skrll 
    685  1.5.4.2  skrll 	control = vc2_read_ireg(dc, VC2_IREG_CONTROL);
    686  1.5.4.2  skrll 
    687  1.5.4.2  skrll 	if (!on) {
    688  1.5.4.2  skrll 		vc2_write_ireg(dc, VC2_IREG_CONTROL,
    689  1.5.4.2  skrll 		    control & ~VC2_CONTROL_CURSOR_ENABLE);
    690  1.5.4.2  skrll 	} else {
    691  1.5.4.2  skrll 		/* Work around bug in some board revisions */
    692  1.5.4.2  skrll 		if (dc->dc_boardrev < 6)
    693  1.5.4.2  skrll 			x_offset = 21;
    694  1.5.4.2  skrll 		else if (dc->dc_vc2rev == 0)
    695  1.5.4.2  skrll 			x_offset = 29;
    696  1.5.4.2  skrll 		else
    697  1.5.4.2  skrll 			x_offset = 31;
    698  1.5.4.2  skrll 
    699  1.5.4.2  skrll 		vc2_write_ireg(dc, VC2_IREG_CURSOR_X,
    700  1.5.4.2  skrll 		    col * dc->dc_fontdata->fontwidth + x_offset);
    701  1.5.4.2  skrll 		vc2_write_ireg(dc, VC2_IREG_CURSOR_Y,
    702  1.5.4.2  skrll 		    row * dc->dc_fontdata->fontheight + 31);
    703  1.5.4.2  skrll 
    704  1.5.4.2  skrll 		vc2_write_ireg(dc, VC2_IREG_CONTROL,
    705  1.5.4.2  skrll 		    control | VC2_CONTROL_CURSOR_ENABLE);
    706  1.5.4.2  skrll 	}
    707  1.5.4.2  skrll }
    708  1.5.4.2  skrll 
    709  1.5.4.2  skrll static int
    710  1.5.4.2  skrll newport_mapchar(void *c, int ch, unsigned int *cp)
    711  1.5.4.2  skrll {
    712  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    713  1.5.4.2  skrll 
    714  1.5.4.2  skrll 	if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
    715  1.5.4.2  skrll 		ch = wsfont_map_unichar(dc->dc_fontdata, ch);
    716  1.5.4.2  skrll 
    717  1.5.4.2  skrll 		if (ch < 0)
    718  1.5.4.2  skrll 			goto fail;
    719  1.5.4.2  skrll 	}
    720  1.5.4.2  skrll 
    721  1.5.4.2  skrll 	if (ch < dc->dc_fontdata->firstchar ||
    722  1.5.4.2  skrll 	    ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars)
    723  1.5.4.2  skrll 		goto fail;
    724  1.5.4.2  skrll 
    725  1.5.4.2  skrll 	*cp = ch;
    726  1.5.4.2  skrll 	return 5;
    727  1.5.4.2  skrll 
    728  1.5.4.2  skrll fail:
    729  1.5.4.2  skrll 	*cp = ' ';
    730  1.5.4.2  skrll 	return 0;
    731  1.5.4.2  skrll }
    732  1.5.4.2  skrll 
    733  1.5.4.2  skrll static void
    734  1.5.4.2  skrll newport_putchar(void *c, int row, int col, u_int ch, long attr)
    735  1.5.4.2  skrll {
    736  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    737  1.5.4.2  skrll 	struct wsdisplay_font *font = dc->dc_fontdata;
    738  1.5.4.2  skrll 	uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) *
    739  1.5.4.2  skrll 	    font->fontheight * font->stride;
    740  1.5.4.2  skrll 	uint32_t pattern;
    741  1.5.4.2  skrll 	int i;
    742  1.5.4.2  skrll 	int x = col * font->fontwidth;
    743  1.5.4.2  skrll 	int y = row * font->fontheight;
    744  1.5.4.2  skrll 
    745  1.5.4.2  skrll 	rex3_wait_gfifo(dc);
    746  1.5.4.2  skrll 
    747  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
    748  1.5.4.2  skrll 	    REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX |
    749  1.5.4.2  skrll 	    REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE);
    750  1.5.4.2  skrll 
    751  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y);
    752  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_XYENDI,
    753  1.5.4.2  skrll 	    (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT);
    754  1.5.4.2  skrll 
    755  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr));
    756  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr));
    757  1.5.4.2  skrll 
    758  1.5.4.2  skrll 	rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
    759  1.5.4.2  skrll 
    760  1.5.4.2  skrll 	for (i=0; i<font->fontheight; i++) {
    761  1.5.4.2  skrll 		/* XXX Works only with font->fontwidth == 8 XXX */
    762  1.5.4.2  skrll 		pattern = *bitmap << 24;
    763  1.5.4.2  skrll 
    764  1.5.4.2  skrll 		rex3_write_go(dc, REX3_REG_ZPATTERN, pattern);
    765  1.5.4.2  skrll 
    766  1.5.4.2  skrll 		bitmap += font->stride;
    767  1.5.4.2  skrll 	}
    768  1.5.4.2  skrll }
    769  1.5.4.2  skrll 
    770  1.5.4.2  skrll static void
    771  1.5.4.2  skrll newport_copycols(void *c, int row, int srccol, int dstcol, int ncols)
    772  1.5.4.2  skrll {
    773  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    774  1.5.4.2  skrll 	struct wsdisplay_font *font = dc->dc_fontdata;
    775  1.5.4.2  skrll 
    776  1.5.4.2  skrll 	newport_copy_rectangle(dc,
    777  1.5.4.2  skrll 	    srccol * font->fontwidth,			/* x1 */
    778  1.5.4.2  skrll 	    row * font->fontheight,			/* y1 */
    779  1.5.4.2  skrll 	    (srccol + ncols + 1) * font->fontwidth - 1,	/* x2 */
    780  1.5.4.2  skrll 	    (row + 1) * font->fontheight - 1,		/* y2 */
    781  1.5.4.2  skrll 	    dstcol * font->fontheight,			/* dx */
    782  1.5.4.2  skrll 	    row * font->fontheight);			/* dy */
    783  1.5.4.2  skrll }
    784  1.5.4.2  skrll 
    785  1.5.4.2  skrll static void
    786  1.5.4.2  skrll newport_erasecols(void *c, int row, int startcol, int ncols,
    787  1.5.4.2  skrll     long attr)
    788  1.5.4.2  skrll {
    789  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    790  1.5.4.2  skrll 	struct wsdisplay_font *font = dc->dc_fontdata;
    791  1.5.4.2  skrll 
    792  1.5.4.2  skrll 	newport_fill_rectangle(dc,
    793  1.5.4.2  skrll 	    startcol * font->fontwidth,				/* x1 */
    794  1.5.4.2  skrll 	    row * font->fontheight,				/* y1 */
    795  1.5.4.2  skrll 	    (startcol + ncols + 1) * font->fontwidth - 1,	/* x2 */
    796  1.5.4.2  skrll 	    (row + 1) * font->fontheight - 1,			/* y2 */
    797  1.5.4.2  skrll 	    NEWPORT_ATTR_BG(attr));
    798  1.5.4.2  skrll }
    799  1.5.4.2  skrll 
    800  1.5.4.2  skrll static void
    801  1.5.4.2  skrll newport_copyrows(void *c, int srcrow, int dstrow, int nrows)
    802  1.5.4.2  skrll {
    803  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    804  1.5.4.2  skrll 	struct wsdisplay_font *font = dc->dc_fontdata;
    805  1.5.4.2  skrll 
    806  1.5.4.2  skrll 	newport_copy_rectangle(dc,
    807  1.5.4.2  skrll 	    0,							/* x1 */
    808  1.5.4.2  skrll 	    srcrow * font->fontheight,				/* y1 */
    809  1.5.4.2  skrll 	    dc->dc_xres,					/* x2 */
    810  1.5.4.2  skrll 	    (srcrow + nrows + 1) * font->fontheight - 1,	/* y2 */
    811  1.5.4.2  skrll 	    0,							/* dx */
    812  1.5.4.2  skrll 	    dstrow * font->fontheight);				/* dy */
    813  1.5.4.2  skrll }
    814  1.5.4.2  skrll 
    815  1.5.4.2  skrll static void
    816  1.5.4.2  skrll newport_eraserows(void *c, int startrow, int nrows, long attr)
    817  1.5.4.2  skrll {
    818  1.5.4.2  skrll 	struct newport_devconfig *dc = (void *)c;
    819  1.5.4.2  skrll 	struct wsdisplay_font *font = dc->dc_fontdata;
    820  1.5.4.2  skrll 
    821  1.5.4.2  skrll 	newport_fill_rectangle(dc,
    822  1.5.4.2  skrll 	    0,							/* x1 */
    823  1.5.4.2  skrll 	    startrow * font->fontheight,			/* y1 */
    824  1.5.4.2  skrll 	    dc->dc_xres,					/* x2 */
    825  1.5.4.2  skrll 	    (startrow + nrows + 1) * font->fontheight - 1,	/* y2 */
    826  1.5.4.2  skrll 	    NEWPORT_ATTR_BG(attr));
    827  1.5.4.2  skrll }
    828  1.5.4.2  skrll 
    829  1.5.4.2  skrll static int
    830  1.5.4.2  skrll newport_allocattr(void *c, int fg, int bg, int flags, long *attr)
    831  1.5.4.2  skrll {
    832  1.5.4.2  skrll 	if (flags & WSATTR_BLINK)
    833  1.5.4.2  skrll 		return EINVAL;
    834  1.5.4.2  skrll 
    835  1.5.4.2  skrll 	if ((flags & WSATTR_WSCOLORS) == 0) {
    836  1.5.4.2  skrll 		fg = WSCOL_WHITE;
    837  1.5.4.2  skrll 		bg = WSCOL_BLACK;
    838  1.5.4.2  skrll 	}
    839  1.5.4.2  skrll 
    840  1.5.4.2  skrll 	if (flags & WSATTR_HILIT)
    841  1.5.4.2  skrll 		fg += 8;
    842  1.5.4.2  skrll 
    843  1.5.4.2  skrll 	if (flags & WSATTR_REVERSE) {
    844  1.5.4.2  skrll 		int tmp = fg;
    845  1.5.4.2  skrll 		fg = bg;
    846  1.5.4.2  skrll 		bg = tmp;
    847  1.5.4.2  skrll 	}
    848  1.5.4.2  skrll 
    849  1.5.4.2  skrll 	*attr = NEWPORT_ATTR_ENCODE(fg, bg);
    850  1.5.4.2  skrll 
    851  1.5.4.2  skrll 	return 0;
    852  1.5.4.2  skrll }
    853  1.5.4.2  skrll 
    854  1.5.4.2  skrll /**** wsdisplay accessops ****/
    855  1.5.4.2  skrll 
    856  1.5.4.2  skrll static int
    857  1.5.4.2  skrll newport_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc *p)
    858  1.5.4.2  skrll {
    859  1.5.4.2  skrll 	struct newport_softc *sc = c;
    860  1.5.4.2  skrll 
    861  1.5.4.2  skrll #define FBINFO (*(struct wsdisplay_fbinfo*)data)
    862  1.5.4.2  skrll 
    863  1.5.4.2  skrll 	switch (cmd) {
    864  1.5.4.2  skrll 	case WSDISPLAYIO_GINFO:
    865  1.5.4.2  skrll 		FBINFO.width  = sc->sc_dc->dc_xres;
    866  1.5.4.2  skrll 		FBINFO.height = sc->sc_dc->dc_yres;
    867  1.5.4.2  skrll 		FBINFO.depth  = sc->sc_dc->dc_depth;
    868  1.5.4.2  skrll 		FBINFO.cmsize = 1 << FBINFO.depth;
    869  1.5.4.2  skrll 		return 0;
    870  1.5.4.2  skrll 	case WSDISPLAYIO_GTYPE:
    871  1.5.4.2  skrll 		*(u_int *)data = WSDISPLAY_TYPE_NEWPORT;
    872  1.5.4.2  skrll 		return 0;
    873  1.5.4.2  skrll 	}
    874  1.5.4.2  skrll 	return EPASSTHROUGH;
    875  1.5.4.2  skrll }
    876  1.5.4.2  skrll 
    877  1.5.4.2  skrll static paddr_t
    878  1.5.4.2  skrll newport_mmap(void *c, off_t offset, int prot)
    879  1.5.4.2  skrll {
    880  1.5.4.2  skrll 	struct newport_devconfig *dc = c;
    881  1.5.4.2  skrll 
    882  1.5.4.2  skrll 	if ( offset >= 0xfffff)
    883  1.5.4.2  skrll 		return -1;
    884  1.5.4.2  skrll 
    885  1.5.4.2  skrll 	return mips_btop(dc->dc_addr + offset);
    886  1.5.4.2  skrll }
    887  1.5.4.2  skrll 
    888  1.5.4.2  skrll static int
    889  1.5.4.2  skrll newport_alloc_screen(void *c, const struct wsscreen_descr *type, void **cookiep,
    890  1.5.4.2  skrll     int *cursxp, int *cursyp, long *attrp)
    891  1.5.4.2  skrll {
    892  1.5.4.2  skrll 	/* This won't get called for console screen and we don't support
    893  1.5.4.2  skrll 	 * virtual screens */
    894  1.5.4.2  skrll 
    895  1.5.4.2  skrll 	return ENOMEM;
    896  1.5.4.2  skrll }
    897  1.5.4.2  skrll 
    898  1.5.4.2  skrll static void
    899  1.5.4.2  skrll newport_free_screen(void *c, void *cookie)
    900  1.5.4.2  skrll {
    901  1.5.4.2  skrll 	panic("newport_free_screen");
    902  1.5.4.2  skrll }
    903  1.5.4.2  skrll static int
    904  1.5.4.2  skrll newport_show_screen(void *c, void *cookie, int waitok,
    905  1.5.4.2  skrll     void (*cb)(void *, int, int), void *cbarg)
    906  1.5.4.2  skrll {
    907  1.5.4.2  skrll 	return 0;
    908  1.5.4.2  skrll }
    909