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