Home | History | Annotate | Line # | Download | only in ee
gsfb.c revision 1.1.4.2
      1  1.1.4.2  nathanw /*	$NetBSD: gsfb.c,v 1.1.4.2 2002/04/01 07:41:51 nathanw Exp $	*/
      2  1.1.4.2  nathanw 
      3  1.1.4.2  nathanw /*-
      4  1.1.4.2  nathanw  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  1.1.4.2  nathanw  * All rights reserved.
      6  1.1.4.2  nathanw  *
      7  1.1.4.2  nathanw  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1.4.2  nathanw  * by UCHIYAMA Yasushi.
      9  1.1.4.2  nathanw  *
     10  1.1.4.2  nathanw  * Redistribution and use in source and binary forms, with or without
     11  1.1.4.2  nathanw  * modification, are permitted provided that the following conditions
     12  1.1.4.2  nathanw  * are met:
     13  1.1.4.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     14  1.1.4.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     15  1.1.4.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1.4.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     17  1.1.4.2  nathanw  *    documentation and/or other materials provided with the distribution.
     18  1.1.4.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     19  1.1.4.2  nathanw  *    must display the following acknowledgement:
     20  1.1.4.2  nathanw  *        This product includes software developed by the NetBSD
     21  1.1.4.2  nathanw  *        Foundation, Inc. and its contributors.
     22  1.1.4.2  nathanw  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1.4.2  nathanw  *    contributors may be used to endorse or promote products derived
     24  1.1.4.2  nathanw  *    from this software without specific prior written permission.
     25  1.1.4.2  nathanw  *
     26  1.1.4.2  nathanw  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1.4.2  nathanw  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1.4.2  nathanw  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1.4.2  nathanw  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1.4.2  nathanw  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1.4.2  nathanw  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1.4.2  nathanw  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1.4.2  nathanw  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1.4.2  nathanw  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1.4.2  nathanw  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1.4.2  nathanw  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1.4.2  nathanw  */
     38  1.1.4.2  nathanw 
     39  1.1.4.2  nathanw #include "debug_playstation2.h"
     40  1.1.4.2  nathanw 
     41  1.1.4.2  nathanw #include <sys/param.h>
     42  1.1.4.2  nathanw #include <sys/systm.h>
     43  1.1.4.2  nathanw 
     44  1.1.4.2  nathanw #include <machine/autoconf.h>
     45  1.1.4.2  nathanw 
     46  1.1.4.2  nathanw #include <dev/cons.h>
     47  1.1.4.2  nathanw 
     48  1.1.4.2  nathanw #include <dev/wscons/wsconsio.h>
     49  1.1.4.2  nathanw #include <dev/wscons/wsdisplayvar.h>
     50  1.1.4.2  nathanw #include <dev/wscons/wscons_callbacks.h>
     51  1.1.4.2  nathanw 
     52  1.1.4.2  nathanw #include <dev/wsfont/wsfont.h>
     53  1.1.4.2  nathanw 
     54  1.1.4.2  nathanw #include <playstation2/ee/eevar.h>
     55  1.1.4.2  nathanw #include <playstation2/ee/gsvar.h>
     56  1.1.4.2  nathanw #include <playstation2/ee/gsreg.h>
     57  1.1.4.2  nathanw #include <playstation2/ee/dmacvar.h>
     58  1.1.4.2  nathanw #include <playstation2/ee/dmacreg.h>
     59  1.1.4.2  nathanw 
     60  1.1.4.2  nathanw #ifdef DEBUG
     61  1.1.4.2  nathanw #define STATIC
     62  1.1.4.2  nathanw #else
     63  1.1.4.2  nathanw #define STATIC	static
     64  1.1.4.2  nathanw #endif
     65  1.1.4.2  nathanw 
     66  1.1.4.2  nathanw STATIC struct gsfb {
     67  1.1.4.2  nathanw 	int initialized;
     68  1.1.4.2  nathanw 	int attached;
     69  1.1.4.2  nathanw 	int is_console;
     70  1.1.4.2  nathanw 	const struct wsscreen_descr *screen;
     71  1.1.4.2  nathanw 	struct wsdisplay_font *font;
     72  1.1.4.2  nathanw } gsfb;
     73  1.1.4.2  nathanw 
     74  1.1.4.2  nathanw STATIC void gsfb_dma_kick(paddr_t, size_t);
     75  1.1.4.2  nathanw STATIC void gsfb_font_expand_psmct32(const struct wsdisplay_font *, u_int,
     76  1.1.4.2  nathanw     long, u_int32_t *);
     77  1.1.4.2  nathanw STATIC __inline__ void gsfb_set_cursor_pos(u_int32_t *, int, int, int, int);
     78  1.1.4.2  nathanw 
     79  1.1.4.2  nathanw #define ATTR_FG_GET(a)	(((a )>> 24) & 0xf)
     80  1.1.4.2  nathanw #define ATTR_BG_GET(a)	(((a )>> 16) & 0xf)
     81  1.1.4.2  nathanw #define ATTR_FG_SET(x)	(((x) << 24) & 0x0f000000)
     82  1.1.4.2  nathanw #define ATTR_BG_SET(x)	(((x) << 16) & 0x000f0000)
     83  1.1.4.2  nathanw 
     84  1.1.4.2  nathanw STATIC const u_int32_t gsfb_ansi_psmct32[] = {
     85  1.1.4.2  nathanw 	0x80000000, /* black */
     86  1.1.4.2  nathanw 	0x800000aa, /* red */
     87  1.1.4.2  nathanw 	0x8000aa00, /* green */
     88  1.1.4.2  nathanw 	0x8000aaaa, /* brown */
     89  1.1.4.2  nathanw 	0x80aa0000, /* blue */
     90  1.1.4.2  nathanw 	0x80aa00aa, /* magenta */
     91  1.1.4.2  nathanw 	0x80aaaa00, /* cyan */
     92  1.1.4.2  nathanw 	0x80aaaaaa, /* white */
     93  1.1.4.2  nathanw 	0x80000000, /* black */
     94  1.1.4.2  nathanw 	0x800000ff, /* red */
     95  1.1.4.2  nathanw 	0x8000ff00, /* green */
     96  1.1.4.2  nathanw 	0x8000ffff, /* brown */
     97  1.1.4.2  nathanw 	0x80ff0000, /* blue */
     98  1.1.4.2  nathanw 	0x80ff00ff, /* magenta */
     99  1.1.4.2  nathanw 	0x80ffff00, /* cyan */
    100  1.1.4.2  nathanw 	0x80ffffff, /* black */
    101  1.1.4.2  nathanw };
    102  1.1.4.2  nathanw 
    103  1.1.4.2  nathanw #define TRXPOS_DXY(f, x, y)						\
    104  1.1.4.2  nathanw ({									\
    105  1.1.4.2  nathanw 	f[9] = ((x) & 0x000007ff) | (((y) << 16) & 0x07ff0000);		\
    106  1.1.4.2  nathanw })
    107  1.1.4.2  nathanw 
    108  1.1.4.2  nathanw #define TRXPOS_SY_DY(f, sy, dy)						\
    109  1.1.4.2  nathanw ({									\
    110  1.1.4.2  nathanw 	f[8] = (((sy) << 16) & 0x07ff0000);				\
    111  1.1.4.2  nathanw 	f[9] = (((dy) << 16) & 0x07ff0000);				\
    112  1.1.4.2  nathanw })
    113  1.1.4.2  nathanw 
    114  1.1.4.2  nathanw #define TRXPOS_DXY_SXY(f, dx, dy, sx, sy)				\
    115  1.1.4.2  nathanw ({									\
    116  1.1.4.2  nathanw 	f[8] = ((((sy) << 16) & 0x07ff0000) | ((sx) & 0x000007ff));	\
    117  1.1.4.2  nathanw 	f[9] = ((((dy) << 16) & 0x07ff0000) | ((dx) & 0x000007ff));	\
    118  1.1.4.2  nathanw })
    119  1.1.4.2  nathanw 
    120  1.1.4.2  nathanw STATIC u_int32_t gsfb_scroll_cmd_640x16[] __attribute__((__aligned__(16))) = {
    121  1.1.4.2  nathanw         0x00008004, 0x10000000, 0x0000000e, 0x00000000,
    122  1.1.4.2  nathanw         0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
    123  1.1.4.2  nathanw         0x07ff0000, 0x07ff0000, 0x00000051, 0x00000000,
    124  1.1.4.2  nathanw         0x00000280, 0x00000010, 0x00000052, 0x00000000,
    125  1.1.4.2  nathanw         0x00000002, 0x00000000, 0x00000053, 0x00000000,
    126  1.1.4.2  nathanw };
    127  1.1.4.2  nathanw 
    128  1.1.4.2  nathanw STATIC u_int32_t gsfb_cursor_cmd[] __attribute__((__aligned__(16))) = {
    129  1.1.4.2  nathanw 	0x00008007, 0x10000000, 0x0000000e, 0x00000000,
    130  1.1.4.2  nathanw 	0x00000001, 0x00000000, 0x0000001a, 0x00000000,
    131  1.1.4.2  nathanw         0x000000a4, 0x00000080, 0x00000042, 0x00000000,
    132  1.1.4.2  nathanw 	0x00000046, 0x00000000, 0x00000000, 0x00000000,
    133  1.1.4.2  nathanw 	0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
    134  1.1.4.2  nathanw 	0x00000000, 0x00000000, 0x0000000d, 0x00000000,
    135  1.1.4.2  nathanw 	0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
    136  1.1.4.2  nathanw 	0x00000000, 0x00000000, 0x00000005, 0x00000000,
    137  1.1.4.2  nathanw };
    138  1.1.4.2  nathanw 
    139  1.1.4.2  nathanw STATIC u_int32_t gsfb_copy_cmd_8x16[] __attribute__((__aligned__(16))) = {
    140  1.1.4.2  nathanw         0x00008004, 0x10000000, 0x0000000e, 0x00000000,
    141  1.1.4.2  nathanw         0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
    142  1.1.4.2  nathanw         0x07ff07ff, 0x07ff07ff, 0x00000051, 0x00000000,
    143  1.1.4.2  nathanw         0x00000008, 0x00000010, 0x00000052, 0x00000000,
    144  1.1.4.2  nathanw         0x00000002, 0x00000000, 0x00000053, 0x00000000,
    145  1.1.4.2  nathanw };
    146  1.1.4.2  nathanw 
    147  1.1.4.2  nathanw STATIC u_int32_t gsfb_init_cmd_640x480[] __attribute__((__aligned__(16))) = {
    148  1.1.4.2  nathanw 	0x00008008, 0x10000000, 0x0000000e, 0x00000000,
    149  1.1.4.2  nathanw 	0x000a0000, 0x00000000, 0x0000004c, 0x00000000,
    150  1.1.4.2  nathanw 	0x00000096, 0x00000000, 0x0000004e, 0x00000000,
    151  1.1.4.2  nathanw 	0x02800000, 0x01e00000, 0x00000040, 0x00000000,
    152  1.1.4.2  nathanw 	0x00000006, 0x00000000, 0x00000000, 0x00000000,
    153  1.1.4.2  nathanw 	0x80000000, 0x00000000, 0x00000001, 0x00000000,
    154  1.1.4.2  nathanw 	0x00000000, 0x00000000, 0x0000000d, 0x00000000,
    155  1.1.4.2  nathanw 	0x80000000, 0x00000000, 0x00000001, 0x00000000,
    156  1.1.4.2  nathanw 	0x1e002800, 0x00000000, 0x00000005, 0x00000000,
    157  1.1.4.2  nathanw };
    158  1.1.4.2  nathanw 
    159  1.1.4.2  nathanw STATIC u_int32_t gsfb_load_cmd_8x16_psmct32[(6 + 32) * 4]
    160  1.1.4.2  nathanw 	__attribute__((__aligned__(16))) = {
    161  1.1.4.2  nathanw 	/* GIF tag + GS command */
    162  1.1.4.2  nathanw         0x00000004, 0x10000000, 0x0000000e, 0x00000000,
    163  1.1.4.2  nathanw         0x00000000, 0x000a0000, 0x00000050, 0x00000000,
    164  1.1.4.2  nathanw         0x00000000, 0x00000000, 0x00000051, 0x00000000,
    165  1.1.4.2  nathanw         0x00000008, 0x00000016, 0x00000052, 0x00000000,
    166  1.1.4.2  nathanw         0x00000000, 0x00000000, 0x00000053, 0x00000000,
    167  1.1.4.2  nathanw         0x00008020, 0x08000000, 0x00000000, 0x00000000,
    168  1.1.4.2  nathanw 	/* Load area */
    169  1.1.4.2  nathanw #define FONT_SCRATCH_BASE	(6 * 4)
    170  1.1.4.2  nathanw };
    171  1.1.4.2  nathanw 
    172  1.1.4.2  nathanw #ifdef GSFB_DEBUG_MONITOR
    173  1.1.4.2  nathanw #include <machine/stdarg.h>
    174  1.1.4.2  nathanw STATIC const struct _gsfb_debug_window {
    175  1.1.4.2  nathanw 	int start, nrow, attr;
    176  1.1.4.2  nathanw } _gsfb_debug_window[3] = {
    177  1.1.4.2  nathanw 	{ 24, 2 , ATTR_BG_SET(WSCOL_BROWN) | ATTR_FG_SET(WSCOL_BLUE) },
    178  1.1.4.2  nathanw 	{ 26, 2 , ATTR_BG_SET(WSCOL_CYAN) | ATTR_FG_SET(WSCOL_BLUE) },
    179  1.1.4.2  nathanw 	{ 28, 2 , ATTR_BG_SET(WSCOL_WHITE) | ATTR_FG_SET(WSCOL_BLUE) },
    180  1.1.4.2  nathanw };
    181  1.1.4.2  nathanw STATIC char _gsfb_debug_buf[80 * 2];
    182  1.1.4.2  nathanw #endif /* GSFB_DEBUG_MONITOR */
    183  1.1.4.2  nathanw 
    184  1.1.4.2  nathanw STATIC int gsfb_match(struct device *, struct cfdata *, void *);
    185  1.1.4.2  nathanw STATIC void gsfb_attach(struct device *, struct device *, void *);
    186  1.1.4.2  nathanw 
    187  1.1.4.2  nathanw struct cfattach gsfb_ca = {
    188  1.1.4.2  nathanw 	sizeof(struct device), gsfb_match, gsfb_attach
    189  1.1.4.2  nathanw };
    190  1.1.4.2  nathanw 
    191  1.1.4.2  nathanw STATIC void gsfb_hwinit(void);
    192  1.1.4.2  nathanw STATIC int gsfb_swinit(void);
    193  1.1.4.2  nathanw 
    194  1.1.4.2  nathanw /* console */
    195  1.1.4.2  nathanw void gsfbcnprobe(struct consdev *);
    196  1.1.4.2  nathanw void gsfbcninit(struct consdev *);
    197  1.1.4.2  nathanw 
    198  1.1.4.2  nathanw /* emul ops */
    199  1.1.4.2  nathanw STATIC void _gsfb_cursor(void *, int, int, int);
    200  1.1.4.2  nathanw STATIC int _gsfb_mapchar(void *, int, unsigned int *);
    201  1.1.4.2  nathanw STATIC void _gsfb_putchar(void *, int, int, u_int, long);
    202  1.1.4.2  nathanw STATIC void _gsfb_copycols(void *, int, int, int, int);
    203  1.1.4.2  nathanw STATIC void _gsfb_erasecols(void *, int, int, int, long);
    204  1.1.4.2  nathanw STATIC void _gsfb_copyrows(void *, int, int, int);
    205  1.1.4.2  nathanw STATIC void _gsfb_eraserows(void *, int, int, long);
    206  1.1.4.2  nathanw STATIC int _gsfb_alloc_attr(void *, int, int, int, long *);
    207  1.1.4.2  nathanw 
    208  1.1.4.2  nathanw /* access ops */
    209  1.1.4.2  nathanw STATIC int _gsfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
    210  1.1.4.2  nathanw STATIC paddr_t _gsfb_mmap(void *, off_t, int);
    211  1.1.4.2  nathanw STATIC int _gsfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
    212  1.1.4.2  nathanw     int *, int *, long *);
    213  1.1.4.2  nathanw STATIC void _gsfb_free_screen(void *, void *);
    214  1.1.4.2  nathanw STATIC int _gsfb_show_screen(void *, void *, int, void (*)(void *, int, int),
    215  1.1.4.2  nathanw     void *);
    216  1.1.4.2  nathanw STATIC void _gsfb_pollc(void *, int);
    217  1.1.4.2  nathanw 
    218  1.1.4.2  nathanw /*
    219  1.1.4.2  nathanw  * wsdisplay attach args
    220  1.1.4.2  nathanw  *   std: screen size 640 x 480, font size 8 x 16
    221  1.1.4.2  nathanw  */
    222  1.1.4.2  nathanw #define GSFB_STD_SCREEN_WIDTH		640
    223  1.1.4.2  nathanw #define GSFB_STD_SCREEN_HEIGHT		480
    224  1.1.4.2  nathanw #define GSFB_STD_FONT_WIDTH		8
    225  1.1.4.2  nathanw #define GSFB_STD_FONT_HEIGHT		16
    226  1.1.4.2  nathanw const struct wsdisplay_emulops _gsfb_emulops = {
    227  1.1.4.2  nathanw 	.cursor		= _gsfb_cursor,
    228  1.1.4.2  nathanw 	.mapchar	= _gsfb_mapchar,
    229  1.1.4.2  nathanw 	.putchar	= _gsfb_putchar,
    230  1.1.4.2  nathanw 	.copycols	= _gsfb_copycols,
    231  1.1.4.2  nathanw 	.erasecols	= _gsfb_erasecols,
    232  1.1.4.2  nathanw 	.copyrows	= _gsfb_copyrows,
    233  1.1.4.2  nathanw 	.eraserows	= _gsfb_eraserows,
    234  1.1.4.2  nathanw 	.alloc_attr	= _gsfb_alloc_attr
    235  1.1.4.2  nathanw };
    236  1.1.4.2  nathanw 
    237  1.1.4.2  nathanw const struct wsscreen_descr _gsfb_std_screen = {
    238  1.1.4.2  nathanw 	.name		= "std",
    239  1.1.4.2  nathanw 	.ncols		= 80,
    240  1.1.4.2  nathanw #ifdef GSFB_DEBUG_MONITOR
    241  1.1.4.2  nathanw 	.nrows		= 24,
    242  1.1.4.2  nathanw #else
    243  1.1.4.2  nathanw 	.nrows		= 30,
    244  1.1.4.2  nathanw #endif
    245  1.1.4.2  nathanw 	.textops	= &_gsfb_emulops,
    246  1.1.4.2  nathanw 	.fontwidth	= 8,
    247  1.1.4.2  nathanw 	.fontheight	= 16,
    248  1.1.4.2  nathanw 	.capabilities	= WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
    249  1.1.4.2  nathanw 	WSSCREEN_WSCOLORS
    250  1.1.4.2  nathanw };
    251  1.1.4.2  nathanw 
    252  1.1.4.2  nathanw const struct wsscreen_descr *_gsfb_screen_table[] = {
    253  1.1.4.2  nathanw 	&_gsfb_std_screen,
    254  1.1.4.2  nathanw };
    255  1.1.4.2  nathanw 
    256  1.1.4.2  nathanw struct wsscreen_list _gsfb_screen_list = {
    257  1.1.4.2  nathanw 	.nscreens	= sizeof(_gsfb_screen_table) /
    258  1.1.4.2  nathanw 	sizeof(_gsfb_screen_table[0]),
    259  1.1.4.2  nathanw 	.screens	= _gsfb_screen_table
    260  1.1.4.2  nathanw };
    261  1.1.4.2  nathanw 
    262  1.1.4.2  nathanw struct wsdisplay_accessops _gsfb_accessops = {
    263  1.1.4.2  nathanw 	.ioctl		= _gsfb_ioctl,
    264  1.1.4.2  nathanw 	.mmap		= _gsfb_mmap,
    265  1.1.4.2  nathanw 	.alloc_screen	= _gsfb_alloc_screen,
    266  1.1.4.2  nathanw 	.free_screen	= _gsfb_free_screen,
    267  1.1.4.2  nathanw 	.show_screen	= _gsfb_show_screen,
    268  1.1.4.2  nathanw 	.load_font	= 0,
    269  1.1.4.2  nathanw 	.pollc		= _gsfb_pollc
    270  1.1.4.2  nathanw };
    271  1.1.4.2  nathanw 
    272  1.1.4.2  nathanw int
    273  1.1.4.2  nathanw gsfb_match(struct device *parent, struct cfdata *cf, void *aux)
    274  1.1.4.2  nathanw {
    275  1.1.4.2  nathanw 	extern struct cfdriver gsfb_cd;
    276  1.1.4.2  nathanw 	struct mainbus_attach_args *ma = aux;
    277  1.1.4.2  nathanw 
    278  1.1.4.2  nathanw 	if (strcmp(ma->ma_name, gsfb_cd.cd_name) != 0)
    279  1.1.4.2  nathanw 		return (0);
    280  1.1.4.2  nathanw 
    281  1.1.4.2  nathanw 	return (!gsfb.attached);
    282  1.1.4.2  nathanw }
    283  1.1.4.2  nathanw 
    284  1.1.4.2  nathanw void
    285  1.1.4.2  nathanw gsfb_attach(struct device *parent, struct device *self, void *aux)
    286  1.1.4.2  nathanw {
    287  1.1.4.2  nathanw 	struct wsemuldisplaydev_attach_args wa;
    288  1.1.4.2  nathanw 
    289  1.1.4.2  nathanw 	gsfb.attached = 1;
    290  1.1.4.2  nathanw 	if (!gsfb.is_console && gsfb_swinit() != 0)
    291  1.1.4.2  nathanw 		return;
    292  1.1.4.2  nathanw 
    293  1.1.4.2  nathanw 	printf("\n");
    294  1.1.4.2  nathanw 
    295  1.1.4.2  nathanw 	wa.console	= gsfb.is_console;
    296  1.1.4.2  nathanw 	wa.scrdata	= &_gsfb_screen_list;
    297  1.1.4.2  nathanw 	wa.accessops	= &_gsfb_accessops;
    298  1.1.4.2  nathanw 	wa.accesscookie	= &gsfb;
    299  1.1.4.2  nathanw 
    300  1.1.4.2  nathanw 	config_found(self, &wa, wsdisplaydevprint);
    301  1.1.4.2  nathanw }
    302  1.1.4.2  nathanw 
    303  1.1.4.2  nathanw /*
    304  1.1.4.2  nathanw  * console
    305  1.1.4.2  nathanw  */
    306  1.1.4.2  nathanw void
    307  1.1.4.2  nathanw gsfbcnprobe(struct consdev *cndev)
    308  1.1.4.2  nathanw {
    309  1.1.4.2  nathanw 
    310  1.1.4.2  nathanw 	cndev->cn_pri = CN_INTERNAL;
    311  1.1.4.2  nathanw }
    312  1.1.4.2  nathanw 
    313  1.1.4.2  nathanw void
    314  1.1.4.2  nathanw gsfbcninit(struct consdev *cndev)
    315  1.1.4.2  nathanw {
    316  1.1.4.2  nathanw 	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_init_cmd_640x480);
    317  1.1.4.2  nathanw 	long defattr =  ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
    318  1.1.4.2  nathanw 
    319  1.1.4.2  nathanw 	gsfb.is_console = 1;
    320  1.1.4.2  nathanw 
    321  1.1.4.2  nathanw 	gsfb_hwinit();
    322  1.1.4.2  nathanw 	gsfb_swinit();
    323  1.1.4.2  nathanw 
    324  1.1.4.2  nathanw 	gsfb_dma_kick(paddr, sizeof gsfb_init_cmd_640x480);
    325  1.1.4.2  nathanw #ifdef GSFB_DEBUG_MONITOR
    326  1.1.4.2  nathanw 	{
    327  1.1.4.2  nathanw 		const struct _gsfb_debug_window *win;
    328  1.1.4.2  nathanw 		int i;
    329  1.1.4.2  nathanw 
    330  1.1.4.2  nathanw 		for (i = 0; i < 3; i++) {
    331  1.1.4.2  nathanw 			win = &_gsfb_debug_window[i];
    332  1.1.4.2  nathanw 			_gsfb_eraserows(0, win->start, win->nrow, win->attr);
    333  1.1.4.2  nathanw 		}
    334  1.1.4.2  nathanw 	}
    335  1.1.4.2  nathanw #endif /* GSFB_DEBUG_MONITOR */
    336  1.1.4.2  nathanw 
    337  1.1.4.2  nathanw 	wsdisplay_cnattach(&_gsfb_std_screen, &gsfb, 0, 0, defattr);
    338  1.1.4.2  nathanw }
    339  1.1.4.2  nathanw 
    340  1.1.4.2  nathanw void
    341  1.1.4.2  nathanw gsfb_hwinit()
    342  1.1.4.2  nathanw {
    343  1.1.4.2  nathanw 	gs_init(VESA_1A);
    344  1.1.4.2  nathanw 	dmac_init();
    345  1.1.4.2  nathanw 
    346  1.1.4.2  nathanw 	/* reset GIF channel DMA */
    347  1.1.4.2  nathanw 	_reg_write_4(D2_QWC_REG, 0);
    348  1.1.4.2  nathanw 	_reg_write_4(D2_MADR_REG, 0);
    349  1.1.4.2  nathanw 	_reg_write_4(D2_TADR_REG, 0);
    350  1.1.4.2  nathanw 	_reg_write_4(D2_CHCR_REG, 0);
    351  1.1.4.2  nathanw }
    352  1.1.4.2  nathanw 
    353  1.1.4.2  nathanw int
    354  1.1.4.2  nathanw gsfb_swinit()
    355  1.1.4.2  nathanw {
    356  1.1.4.2  nathanw 	int font;
    357  1.1.4.2  nathanw 
    358  1.1.4.2  nathanw 	wsfont_init();
    359  1.1.4.2  nathanw 	font = wsfont_find(NULL, 8, 16, 0,  WSDISPLAY_FONTORDER_L2R,
    360  1.1.4.2  nathanw 	    WSDISPLAY_FONTORDER_L2R);
    361  1.1.4.2  nathanw 	if (font < 0)
    362  1.1.4.2  nathanw 		return (1);
    363  1.1.4.2  nathanw 
    364  1.1.4.2  nathanw 	if (wsfont_lock(font, &gsfb.font))
    365  1.1.4.2  nathanw 		return (1);
    366  1.1.4.2  nathanw 
    367  1.1.4.2  nathanw 	gsfb.screen = &_gsfb_std_screen;
    368  1.1.4.2  nathanw 	gsfb.initialized = 1;
    369  1.1.4.2  nathanw 
    370  1.1.4.2  nathanw 	return (0);
    371  1.1.4.2  nathanw }
    372  1.1.4.2  nathanw 
    373  1.1.4.2  nathanw /*
    374  1.1.4.2  nathanw  * wsdisplay
    375  1.1.4.2  nathanw  */
    376  1.1.4.2  nathanw void
    377  1.1.4.2  nathanw _gsfb_cursor(void *cookie, int on, int row, int col)
    378  1.1.4.2  nathanw {
    379  1.1.4.2  nathanw 	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_cursor_cmd);
    380  1.1.4.2  nathanw 	u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
    381  1.1.4.2  nathanw 	struct wsdisplay_font *font = gsfb.font;
    382  1.1.4.2  nathanw 
    383  1.1.4.2  nathanw 	gsfb_set_cursor_pos(buf, col, row, font->fontwidth, font->fontheight);
    384  1.1.4.2  nathanw 
    385  1.1.4.2  nathanw 	gsfb_dma_kick(paddr, sizeof gsfb_cursor_cmd);
    386  1.1.4.2  nathanw }
    387  1.1.4.2  nathanw 
    388  1.1.4.2  nathanw __inline__ void
    389  1.1.4.2  nathanw gsfb_set_cursor_pos(u_int32_t *p, int x, int y, int w, int h)
    390  1.1.4.2  nathanw {
    391  1.1.4.2  nathanw 
    392  1.1.4.2  nathanw 	x *= w;
    393  1.1.4.2  nathanw 	y *= h;
    394  1.1.4.2  nathanw 	p[20] = ((x << 4) & 0xffff) | ((y << 20) & 0xffff0000);
    395  1.1.4.2  nathanw 	p[28] = (((x + w - 1) << 4) & 0xffff) |
    396  1.1.4.2  nathanw 	    (((y + h - 1) << 20) & 0xffff0000);
    397  1.1.4.2  nathanw }
    398  1.1.4.2  nathanw 
    399  1.1.4.2  nathanw int
    400  1.1.4.2  nathanw _gsfb_mapchar(void *cookie, int c, unsigned int *cp)
    401  1.1.4.2  nathanw {
    402  1.1.4.2  nathanw 	struct wsdisplay_font *font = gsfb.font;
    403  1.1.4.2  nathanw 
    404  1.1.4.2  nathanw 	if (font->encoding != WSDISPLAY_FONTENC_ISO)
    405  1.1.4.2  nathanw 		if ((c = wsfont_map_unichar(font, c)) < 0)
    406  1.1.4.2  nathanw 			goto nomap;
    407  1.1.4.2  nathanw 
    408  1.1.4.2  nathanw 	if (c < font->firstchar || c >= font->firstchar + font->numchars)
    409  1.1.4.2  nathanw 			goto nomap;
    410  1.1.4.2  nathanw 
    411  1.1.4.2  nathanw 	*cp = c;
    412  1.1.4.2  nathanw 	return (5);
    413  1.1.4.2  nathanw 
    414  1.1.4.2  nathanw  nomap:
    415  1.1.4.2  nathanw 	*cp = ' ';
    416  1.1.4.2  nathanw 	return (0);
    417  1.1.4.2  nathanw }
    418  1.1.4.2  nathanw 
    419  1.1.4.2  nathanw void
    420  1.1.4.2  nathanw _gsfb_putchar(void *cookie, int row, int col, u_int uc, long attr)
    421  1.1.4.2  nathanw {
    422  1.1.4.2  nathanw 	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_load_cmd_8x16_psmct32);
    423  1.1.4.2  nathanw 	u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
    424  1.1.4.2  nathanw 	struct wsdisplay_font *font = gsfb.font;
    425  1.1.4.2  nathanw 
    426  1.1.4.2  nathanw 	/* copy font data to DMA region */
    427  1.1.4.2  nathanw 	gsfb_font_expand_psmct32(font, uc, attr, &buf[FONT_SCRATCH_BASE]);
    428  1.1.4.2  nathanw 
    429  1.1.4.2  nathanw 	/* set destination position */
    430  1.1.4.2  nathanw 	TRXPOS_DXY(buf, col * font->fontwidth, row * font->fontheight);
    431  1.1.4.2  nathanw 
    432  1.1.4.2  nathanw 	/* kick to GIF */
    433  1.1.4.2  nathanw 	gsfb_dma_kick(paddr, sizeof gsfb_load_cmd_8x16_psmct32);
    434  1.1.4.2  nathanw }
    435  1.1.4.2  nathanw 
    436  1.1.4.2  nathanw void
    437  1.1.4.2  nathanw _gsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
    438  1.1.4.2  nathanw {
    439  1.1.4.2  nathanw 	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_copy_cmd_8x16);
    440  1.1.4.2  nathanw 	u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
    441  1.1.4.2  nathanw 	int y = gsfb.font->fontheight * row;
    442  1.1.4.2  nathanw 	int w = gsfb.font->fontwidth;
    443  1.1.4.2  nathanw 	int i;
    444  1.1.4.2  nathanw 
    445  1.1.4.2  nathanw 	if (dstcol > srccol) {
    446  1.1.4.2  nathanw 		for (i = ncols - 1; i >= 0; i--) {
    447  1.1.4.2  nathanw 			TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
    448  1.1.4.2  nathanw 			gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
    449  1.1.4.2  nathanw 		}
    450  1.1.4.2  nathanw 	} else {
    451  1.1.4.2  nathanw 		for (i = 0; i < ncols; i++) {
    452  1.1.4.2  nathanw 			TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
    453  1.1.4.2  nathanw 			gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
    454  1.1.4.2  nathanw 		}
    455  1.1.4.2  nathanw 	}
    456  1.1.4.2  nathanw }
    457  1.1.4.2  nathanw 
    458  1.1.4.2  nathanw void
    459  1.1.4.2  nathanw _gsfb_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
    460  1.1.4.2  nathanw {
    461  1.1.4.2  nathanw 	int i;
    462  1.1.4.2  nathanw 
    463  1.1.4.2  nathanw 	for (i = 0; i < ncols; i++)
    464  1.1.4.2  nathanw 		_gsfb_putchar(cookie, row, startcol + i, ' ', attr);
    465  1.1.4.2  nathanw }
    466  1.1.4.2  nathanw 
    467  1.1.4.2  nathanw void
    468  1.1.4.2  nathanw _gsfb_copyrows(void *cookie, int src, int dst, int num)
    469  1.1.4.2  nathanw {
    470  1.1.4.2  nathanw 	paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_scroll_cmd_640x16);
    471  1.1.4.2  nathanw 	u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
    472  1.1.4.2  nathanw 	int i;
    473  1.1.4.2  nathanw 	int h = gsfb.font->fontheight;
    474  1.1.4.2  nathanw 
    475  1.1.4.2  nathanw 	if (dst > src) {
    476  1.1.4.2  nathanw 		for (i = num - 1; i >= 0; i--) {
    477  1.1.4.2  nathanw 			TRXPOS_SY_DY(cmd, (src + i) * h, (dst  + i) * h);
    478  1.1.4.2  nathanw 			gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
    479  1.1.4.2  nathanw 		}
    480  1.1.4.2  nathanw 	} else {
    481  1.1.4.2  nathanw 		for (i = 0; i < num; i++) {
    482  1.1.4.2  nathanw 			TRXPOS_SY_DY(cmd, (src + i) * h, (dst  + i) * h);
    483  1.1.4.2  nathanw 			gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
    484  1.1.4.2  nathanw 		}
    485  1.1.4.2  nathanw 	}
    486  1.1.4.2  nathanw }
    487  1.1.4.2  nathanw 
    488  1.1.4.2  nathanw void
    489  1.1.4.2  nathanw _gsfb_eraserows(void *cookie, int row, int nrow, long attr)
    490  1.1.4.2  nathanw {
    491  1.1.4.2  nathanw 	int i, j;
    492  1.1.4.2  nathanw 
    493  1.1.4.2  nathanw 	for (j = 0; j < nrow; j++)
    494  1.1.4.2  nathanw 		for (i = 0; i < gsfb.screen->ncols; i++)
    495  1.1.4.2  nathanw 			_gsfb_putchar(cookie, row + j, i, ' ', attr);
    496  1.1.4.2  nathanw }
    497  1.1.4.2  nathanw 
    498  1.1.4.2  nathanw int
    499  1.1.4.2  nathanw _gsfb_alloc_attr(void *cookie, int fg, int bg, int flags, long *attr)
    500  1.1.4.2  nathanw {
    501  1.1.4.2  nathanw 
    502  1.1.4.2  nathanw 	if ((flags & WSATTR_BLINK) != 0)
    503  1.1.4.2  nathanw 		return (EINVAL);
    504  1.1.4.2  nathanw 
    505  1.1.4.2  nathanw 	if ((flags & WSATTR_WSCOLORS) == 0) {
    506  1.1.4.2  nathanw 		fg = WSCOL_WHITE;
    507  1.1.4.2  nathanw 		bg = WSCOL_BLACK;
    508  1.1.4.2  nathanw 	}
    509  1.1.4.2  nathanw 
    510  1.1.4.2  nathanw 	if ((flags & WSATTR_HILIT) != 0)
    511  1.1.4.2  nathanw 		fg += 8;
    512  1.1.4.2  nathanw 
    513  1.1.4.2  nathanw 	flags = (flags & WSATTR_UNDERLINE) ? 1 : 0;
    514  1.1.4.2  nathanw 
    515  1.1.4.2  nathanw 
    516  1.1.4.2  nathanw 	*attr = ATTR_BG_SET(bg) | ATTR_FG_SET(fg) | flags;
    517  1.1.4.2  nathanw 
    518  1.1.4.2  nathanw 	return (0);
    519  1.1.4.2  nathanw }
    520  1.1.4.2  nathanw 
    521  1.1.4.2  nathanw int
    522  1.1.4.2  nathanw _gsfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
    523  1.1.4.2  nathanw {
    524  1.1.4.2  nathanw 
    525  1.1.4.2  nathanw 	return (EPASSTHROUGH); /* Inappropriate ioctl for device */
    526  1.1.4.2  nathanw }
    527  1.1.4.2  nathanw 
    528  1.1.4.2  nathanw paddr_t
    529  1.1.4.2  nathanw _gsfb_mmap(void *v, off_t offset, int prot)
    530  1.1.4.2  nathanw {
    531  1.1.4.2  nathanw 
    532  1.1.4.2  nathanw 	return (NULL); /* can't mmap */
    533  1.1.4.2  nathanw }
    534  1.1.4.2  nathanw 
    535  1.1.4.2  nathanw int
    536  1.1.4.2  nathanw _gsfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
    537  1.1.4.2  nathanw     int *curxp, int *curyp, long *attrp)
    538  1.1.4.2  nathanw {
    539  1.1.4.2  nathanw 
    540  1.1.4.2  nathanw 	*attrp = ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
    541  1.1.4.2  nathanw 
    542  1.1.4.2  nathanw 	return (0);
    543  1.1.4.2  nathanw }
    544  1.1.4.2  nathanw 
    545  1.1.4.2  nathanw void
    546  1.1.4.2  nathanw _gsfb_free_screen(void *v, void *cookie)
    547  1.1.4.2  nathanw {
    548  1.1.4.2  nathanw }
    549  1.1.4.2  nathanw 
    550  1.1.4.2  nathanw int
    551  1.1.4.2  nathanw _gsfb_show_screen(void *v, void *cookie, int waitok,
    552  1.1.4.2  nathanw     void (*cb)(void *, int, int), void *cbarg)
    553  1.1.4.2  nathanw {
    554  1.1.4.2  nathanw 
    555  1.1.4.2  nathanw 	return (0);
    556  1.1.4.2  nathanw }
    557  1.1.4.2  nathanw 
    558  1.1.4.2  nathanw void
    559  1.1.4.2  nathanw _gsfb_pollc(void *v, int on)
    560  1.1.4.2  nathanw {
    561  1.1.4.2  nathanw 
    562  1.1.4.2  nathanw }
    563  1.1.4.2  nathanw 
    564  1.1.4.2  nathanw /*
    565  1.1.4.2  nathanw  * font expansion
    566  1.1.4.2  nathanw  *   PSMCT32 only
    567  1.1.4.2  nathanw  */
    568  1.1.4.2  nathanw void
    569  1.1.4.2  nathanw gsfb_font_expand_psmct32(const struct wsdisplay_font *font, u_int c, long attr,
    570  1.1.4.2  nathanw     u_int32_t *buf)
    571  1.1.4.2  nathanw {
    572  1.1.4.2  nathanw 	u_int32_t fg, bg;
    573  1.1.4.2  nathanw 	u_int8_t *bitmap;
    574  1.1.4.2  nathanw 	int i, j;
    575  1.1.4.2  nathanw 
    576  1.1.4.2  nathanw 	KDASSERT(((u_int32_t)buf & 15) == 0);
    577  1.1.4.2  nathanw 
    578  1.1.4.2  nathanw 	fg = gsfb_ansi_psmct32[ATTR_FG_GET(attr)];
    579  1.1.4.2  nathanw 	bg = gsfb_ansi_psmct32[ATTR_BG_GET(attr)];
    580  1.1.4.2  nathanw 
    581  1.1.4.2  nathanw 	bitmap = (u_int8_t *)font->data + (c - font->firstchar) *
    582  1.1.4.2  nathanw 	    font->fontheight * font->stride;
    583  1.1.4.2  nathanw 	for (i = 0; i < font->fontheight; i++, bitmap++) {
    584  1.1.4.2  nathanw 		u_int32_t b = *bitmap;
    585  1.1.4.2  nathanw 		for (j = 0; j < font->fontwidth; j++, b <<= 1)
    586  1.1.4.2  nathanw 			*buf++ = (b & 0x80) ? fg : bg;
    587  1.1.4.2  nathanw 	}
    588  1.1.4.2  nathanw }
    589  1.1.4.2  nathanw 
    590  1.1.4.2  nathanw void
    591  1.1.4.2  nathanw gsfb_dma_kick(paddr_t addr, size_t size)
    592  1.1.4.2  nathanw {
    593  1.1.4.2  nathanw 	/* Wait for previous DMA request complete */
    594  1.1.4.2  nathanw 	while (_reg_read_4(D2_QWC_REG))
    595  1.1.4.2  nathanw 		;
    596  1.1.4.2  nathanw 
    597  1.1.4.2  nathanw 	/* Wait until GS FIFO empty */
    598  1.1.4.2  nathanw 	while ((_reg_read_8(GS_S_CSR_REG) & (3 << 14)) != (1 << 14))
    599  1.1.4.2  nathanw 		;
    600  1.1.4.2  nathanw 
    601  1.1.4.2  nathanw 	/* wait for DMA complete */
    602  1.1.4.2  nathanw 	dmac_bus_poll(D_CH2_GIF);
    603  1.1.4.2  nathanw 
    604  1.1.4.2  nathanw 	/* transfer addr */
    605  1.1.4.2  nathanw 	_reg_write_4(D2_MADR_REG, addr);
    606  1.1.4.2  nathanw 	/* transfer data size (unit qword) */
    607  1.1.4.2  nathanw 	_reg_write_4(D2_QWC_REG, bytetoqwc(size));
    608  1.1.4.2  nathanw 
    609  1.1.4.2  nathanw 	/* kick DMA (normal-mode) */
    610  1.1.4.2  nathanw 	dmac_chcr_write(D_CH2_GIF, D_CHCR_STR);
    611  1.1.4.2  nathanw }
    612  1.1.4.2  nathanw 
    613  1.1.4.2  nathanw #ifdef GSFB_DEBUG_MONITOR
    614  1.1.4.2  nathanw void
    615  1.1.4.2  nathanw __gsfb_print(int window, const char *fmt, ...)
    616  1.1.4.2  nathanw {
    617  1.1.4.2  nathanw 	const struct _gsfb_debug_window *win;
    618  1.1.4.2  nathanw 	int i, s, x, y, n, a;
    619  1.1.4.2  nathanw 	u_int c;
    620  1.1.4.2  nathanw 	va_list ap;
    621  1.1.4.2  nathanw 
    622  1.1.4.2  nathanw 	if (!gsfb.initialized)
    623  1.1.4.2  nathanw 		return;
    624  1.1.4.2  nathanw 
    625  1.1.4.2  nathanw 	s = _intr_suspend();
    626  1.1.4.2  nathanw 	win = &_gsfb_debug_window[window];
    627  1.1.4.2  nathanw 	x = 0;
    628  1.1.4.2  nathanw 	y = win->start;
    629  1.1.4.2  nathanw 	n = win->nrow * 80;
    630  1.1.4.2  nathanw 	a = win->attr;
    631  1.1.4.2  nathanw 
    632  1.1.4.2  nathanw 	va_start(ap, fmt);
    633  1.1.4.2  nathanw 	vsnprintf(_gsfb_debug_buf, n, fmt, ap);
    634  1.1.4.2  nathanw 	va_end(ap);
    635  1.1.4.2  nathanw 
    636  1.1.4.2  nathanw 	_gsfb_eraserows(0, y, win->nrow, a);
    637  1.1.4.2  nathanw 
    638  1.1.4.2  nathanw 	for (i = 0; i < n &&
    639  1.1.4.2  nathanw 	    (c = (u_int)_gsfb_debug_buf[i] & 0x7f) != 0; i++) {
    640  1.1.4.2  nathanw 		if (c == '\n')
    641  1.1.4.2  nathanw 			x = 0, y++;
    642  1.1.4.2  nathanw 		else
    643  1.1.4.2  nathanw 			_gsfb_putchar(0, y, x++, c, a);
    644  1.1.4.2  nathanw 	}
    645  1.1.4.2  nathanw 
    646  1.1.4.2  nathanw 	_intr_resume(s);
    647  1.1.4.2  nathanw }
    648  1.1.4.2  nathanw 
    649  1.1.4.2  nathanw void
    650  1.1.4.2  nathanw __gsfb_print_hex(int a0, int a1, int a2, int a3)
    651  1.1.4.2  nathanw {
    652  1.1.4.2  nathanw 	__gsfb_print(2, "a0=%08x a1=%08x a2=%08x a3=%08x",
    653  1.1.4.2  nathanw 	    a0, a1, a2, a3);
    654  1.1.4.2  nathanw }
    655  1.1.4.2  nathanw #endif /* GSFB_DEBUG_MONITOR */
    656