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