1*0aeb5daeSandvar /* $NetBSD: grtwo.c,v 1.19 2023/12/13 20:53:14 andvar Exp $ */
227be14d3Ssekiya
327be14d3Ssekiya /*
427be14d3Ssekiya * Copyright (c) 2004 Christopher SEKIYA
527be14d3Ssekiya * All rights reserved.
627be14d3Ssekiya *
727be14d3Ssekiya * Redistribution and use in source and binary forms, with or without
827be14d3Ssekiya * modification, are permitted provided that the following conditions
927be14d3Ssekiya * are met:
1027be14d3Ssekiya * 1. Redistributions of source code must retain the above copyright
1127be14d3Ssekiya * notice, this list of conditions and the following disclaimer.
1227be14d3Ssekiya * 2. Redistributions in binary form must reproduce the above copyright
1327be14d3Ssekiya * notice, this list of conditions and the following disclaimer in the
1427be14d3Ssekiya * documentation and/or other materials provided with the distribution.
1527be14d3Ssekiya * 3. The name of the author may not be used to endorse or promote products
1627be14d3Ssekiya * derived from this software without specific prior written permission.
1727be14d3Ssekiya *
1827be14d3Ssekiya * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1927be14d3Ssekiya * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2027be14d3Ssekiya * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2127be14d3Ssekiya * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2227be14d3Ssekiya * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2327be14d3Ssekiya * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2427be14d3Ssekiya * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2527be14d3Ssekiya * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2627be14d3Ssekiya * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2727be14d3Ssekiya * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2827be14d3Ssekiya *
2927be14d3Ssekiya * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
3027be14d3Ssekiya */
3127be14d3Ssekiya
3227be14d3Ssekiya /* wscons driver for SGI GR2 family of framebuffers
3327be14d3Ssekiya *
3427be14d3Ssekiya * Heavily based on the newport wscons driver.
3527be14d3Ssekiya */
3627be14d3Ssekiya
3727be14d3Ssekiya #include <sys/cdefs.h>
38*0aeb5daeSandvar __KERNEL_RCSID(0, "$NetBSD: grtwo.c,v 1.19 2023/12/13 20:53:14 andvar Exp $");
3927be14d3Ssekiya
4027be14d3Ssekiya #include <sys/param.h>
4127be14d3Ssekiya #include <sys/systm.h>
4227be14d3Ssekiya #include <sys/device.h>
4361a80495Sthorpej #include <sys/kmem.h>
4427be14d3Ssekiya
451426ceedSrumble #include <machine/sysconf.h>
461426ceedSrumble
4727be14d3Ssekiya #include <dev/wscons/wsconsio.h>
4827be14d3Ssekiya #include <dev/wscons/wsdisplayvar.h>
4927be14d3Ssekiya #include <dev/wsfont/wsfont.h>
5027be14d3Ssekiya
5127be14d3Ssekiya #include <sgimips/gio/giovar.h>
5227be14d3Ssekiya #include <sgimips/gio/grtwovar.h>
5327be14d3Ssekiya #include <sgimips/gio/grtworeg.h>
5427be14d3Ssekiya
5527be14d3Ssekiya #include <sgimips/dev/int2var.h>
5627be14d3Ssekiya
5727be14d3Ssekiya struct grtwo_softc {
5827be14d3Ssekiya struct grtwo_devconfig *sc_dc;
5927be14d3Ssekiya };
6027be14d3Ssekiya
6127be14d3Ssekiya struct grtwo_devconfig {
6227be14d3Ssekiya u_int32_t dc_addr;
6327be14d3Ssekiya
6427be14d3Ssekiya bus_space_tag_t iot;
6527be14d3Ssekiya bus_space_handle_t ioh;
6627be14d3Ssekiya
6727be14d3Ssekiya u_int8_t boardrev;
6827be14d3Ssekiya u_int8_t backendrev;
6927be14d3Ssekiya int hq2rev;
7027be14d3Ssekiya int ge7rev;
7127be14d3Ssekiya int vc1rev;
7227be14d3Ssekiya int zbuffer;
7327be14d3Ssekiya int cmaprev;
7427be14d3Ssekiya int xmaprev;
7527be14d3Ssekiya int rexrev;
7627be14d3Ssekiya int xres;
7727be14d3Ssekiya int yres;
7827be14d3Ssekiya int depth;
7927be14d3Ssekiya int monitor;
8027be14d3Ssekiya
8127be14d3Ssekiya int dc_font;
8227be14d3Ssekiya struct wsdisplay_font *dc_fontdata;
8327be14d3Ssekiya };
8427be14d3Ssekiya
85cbab9cadSchs static int grtwo_match(device_t, cfdata_t, void *);
86cbab9cadSchs static void grtwo_attach(device_t, device_t, void *);
8727be14d3Ssekiya
88cbab9cadSchs CFATTACH_DECL_NEW(grtwo, sizeof(struct grtwo_softc),
8927be14d3Ssekiya grtwo_match, grtwo_attach, NULL, NULL);
9027be14d3Ssekiya
9127be14d3Ssekiya /* textops */
9227be14d3Ssekiya static void grtwo_cursor(void *, int, int, int);
9327be14d3Ssekiya static int grtwo_mapchar(void *, int, unsigned int *);
9427be14d3Ssekiya static void grtwo_putchar(void *, int, int, u_int, long);
9527be14d3Ssekiya static void grtwo_copycols(void *, int, int, int, int);
9627be14d3Ssekiya static void grtwo_erasecols(void *, int, int, int, long);
9727be14d3Ssekiya static void grtwo_copyrows(void *, int, int, int);
9827be14d3Ssekiya static void grtwo_eraserows(void *, int, int, long);
9927be14d3Ssekiya static int grtwo_allocattr(void *, int, int, int, long *);
10027be14d3Ssekiya
10127be14d3Ssekiya /* accessops */
10253524e44Schristos static int grtwo_ioctl(void *, void *, u_long, void *, int, struct lwp *);
1037a51d4ddSjmmv static paddr_t grtwo_mmap(void *, void *, off_t, int);
10427be14d3Ssekiya static int
10527be14d3Ssekiya grtwo_alloc_screen(void *, const struct wsscreen_descr *,
10627be14d3Ssekiya void **, int *, int *, long *);
10727be14d3Ssekiya static void grtwo_free_screen(void *, void *);
10827be14d3Ssekiya static int
10927be14d3Ssekiya grtwo_show_screen(void *, void *, int, void (*) (void *, int, int), void *);
11027be14d3Ssekiya
1119c873da2Ssekiya static int grtwo_intr0(void *);
1129c873da2Ssekiya static int grtwo_intr6(void *);
1139c873da2Ssekiya
11427be14d3Ssekiya static const struct wsdisplay_emulops grtwo_textops = {
11527be14d3Ssekiya .cursor = grtwo_cursor,
11627be14d3Ssekiya .mapchar = grtwo_mapchar,
11727be14d3Ssekiya .putchar = grtwo_putchar,
11827be14d3Ssekiya .copycols = grtwo_copycols,
11927be14d3Ssekiya .erasecols = grtwo_erasecols,
12027be14d3Ssekiya .copyrows = grtwo_copyrows,
12127be14d3Ssekiya .eraserows = grtwo_eraserows,
12227be14d3Ssekiya .allocattr = grtwo_allocattr
12327be14d3Ssekiya };
12427be14d3Ssekiya
12527be14d3Ssekiya static const struct wsdisplay_accessops grtwo_accessops = {
12627be14d3Ssekiya .ioctl = grtwo_ioctl,
12727be14d3Ssekiya .mmap = grtwo_mmap,
12827be14d3Ssekiya .alloc_screen = grtwo_alloc_screen,
12927be14d3Ssekiya .free_screen = grtwo_free_screen,
13027be14d3Ssekiya .show_screen = grtwo_show_screen,
13127be14d3Ssekiya };
13227be14d3Ssekiya
13327be14d3Ssekiya static const struct wsscreen_descr grtwo_screen = {
13427be14d3Ssekiya .name = "1280x1024",
13527be14d3Ssekiya .ncols = 160,
1369c873da2Ssekiya .nrows = 64, /* 40 */
13727be14d3Ssekiya .textops = &grtwo_textops,
13827be14d3Ssekiya .fontwidth = 8,
13927be14d3Ssekiya .fontheight = 16,
14027be14d3Ssekiya .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
14127be14d3Ssekiya };
14227be14d3Ssekiya
14327be14d3Ssekiya static const struct wsscreen_descr *_grtwo_screenlist[] = {
14427be14d3Ssekiya &grtwo_screen
14527be14d3Ssekiya };
14627be14d3Ssekiya
14727be14d3Ssekiya static const struct wsscreen_list grtwo_screenlist = {
14827be14d3Ssekiya sizeof(_grtwo_screenlist) / sizeof(struct wsscreen_descr *),
14927be14d3Ssekiya _grtwo_screenlist
15027be14d3Ssekiya };
15127be14d3Ssekiya
15227be14d3Ssekiya static struct grtwo_devconfig grtwo_console_dc;
15327be14d3Ssekiya static int grtwo_is_console = 0;
15427be14d3Ssekiya
15527be14d3Ssekiya #define GR2_ATTR_ENCODE(fg,bg) (((fg) << 8) | (bg))
15627be14d3Ssekiya #define GR2_ATTR_BG(a) ((a) & 0xff)
15727be14d3Ssekiya #define GR2_ATTR_FG(a) (((a) >> 8) & 0xff)
15827be14d3Ssekiya
159be83b2c0Smrg #if 0
16027be14d3Ssekiya static const u_int16_t grtwo_cursor_data[128] = {
16127be14d3Ssekiya /* Bit 0 */
16227be14d3Ssekiya 0xff00, 0x0000,
16327be14d3Ssekiya 0xff00, 0x0000,
16427be14d3Ssekiya 0xff00, 0x0000,
16527be14d3Ssekiya 0xff00, 0x0000,
16627be14d3Ssekiya 0xff00, 0x0000,
16727be14d3Ssekiya 0xff00, 0x0000,
16827be14d3Ssekiya 0xff00, 0x0000,
16927be14d3Ssekiya 0xff00, 0x0000,
17027be14d3Ssekiya 0xff00, 0x0000,
17127be14d3Ssekiya 0xff00, 0x0000,
17227be14d3Ssekiya 0xff00, 0x0000,
17327be14d3Ssekiya 0xff00, 0x0000,
17427be14d3Ssekiya 0xff00, 0x0000,
17527be14d3Ssekiya 0xff00, 0x0000,
17627be14d3Ssekiya 0xff00, 0x0000,
17727be14d3Ssekiya 0xff00, 0x0000,
17827be14d3Ssekiya 0x0000, 0x0000,
17927be14d3Ssekiya 0x0000, 0x0000,
18027be14d3Ssekiya 0x0000, 0x0000,
18127be14d3Ssekiya 0x0000, 0x0000,
18227be14d3Ssekiya 0x0000, 0x0000,
18327be14d3Ssekiya 0x0000, 0x0000,
18427be14d3Ssekiya 0x0000, 0x0000,
18527be14d3Ssekiya 0x0000, 0x0000,
18627be14d3Ssekiya 0x0000, 0x0000,
18727be14d3Ssekiya 0x0000, 0x0000,
18827be14d3Ssekiya 0x0000, 0x0000,
18927be14d3Ssekiya 0x0000, 0x0000,
19027be14d3Ssekiya 0x0000, 0x0000,
19127be14d3Ssekiya 0x0000, 0x0000,
19227be14d3Ssekiya 0x0000, 0x0000,
19327be14d3Ssekiya 0x0000, 0x0000,
19427be14d3Ssekiya
19527be14d3Ssekiya /* Bit 1 */
19627be14d3Ssekiya 0x0000, 0x0000,
19727be14d3Ssekiya 0x0000, 0x0000,
19827be14d3Ssekiya 0x0000, 0x0000,
19927be14d3Ssekiya 0x0000, 0x0000,
20027be14d3Ssekiya 0x0000, 0x0000,
20127be14d3Ssekiya 0x0000, 0x0000,
20227be14d3Ssekiya 0x0000, 0x0000,
20327be14d3Ssekiya 0x0000, 0x0000,
20427be14d3Ssekiya 0x0000, 0x0000,
20527be14d3Ssekiya 0x0000, 0x0000,
20627be14d3Ssekiya 0x0000, 0x0000,
20727be14d3Ssekiya 0x0000, 0x0000,
20827be14d3Ssekiya 0x0000, 0x0000,
20927be14d3Ssekiya 0x0000, 0x0000,
21027be14d3Ssekiya 0x0000, 0x0000,
21127be14d3Ssekiya 0x0000, 0x0000,
21227be14d3Ssekiya 0x0000, 0x0000,
21327be14d3Ssekiya 0x0000, 0x0000,
21427be14d3Ssekiya 0x0000, 0x0000,
21527be14d3Ssekiya 0x0000, 0x0000,
21627be14d3Ssekiya 0x0000, 0x0000,
21727be14d3Ssekiya 0x0000, 0x0000,
21827be14d3Ssekiya 0x0000, 0x0000,
21927be14d3Ssekiya 0x0000, 0x0000,
22027be14d3Ssekiya 0x0000, 0x0000,
22127be14d3Ssekiya 0x0000, 0x0000,
22227be14d3Ssekiya 0x0000, 0x0000,
22327be14d3Ssekiya 0x0000, 0x0000,
22427be14d3Ssekiya 0x0000, 0x0000,
22527be14d3Ssekiya 0x0000, 0x0000,
22627be14d3Ssekiya 0x0000, 0x0000,
22727be14d3Ssekiya 0x0000, 0x0000,
22827be14d3Ssekiya };
229be83b2c0Smrg #endif
23027be14d3Ssekiya
23127be14d3Ssekiya static const u_int8_t grtwo_defcmap[8 * 3] = {
23227be14d3Ssekiya /* Normal colors */
23327be14d3Ssekiya 0x00, 0x00, 0x00, /* black */
23427be14d3Ssekiya 0x7f, 0x00, 0x00, /* red */
23527be14d3Ssekiya 0x00, 0x7f, 0x00, /* green */
23627be14d3Ssekiya 0x7f, 0x7f, 0x00, /* brown */
23727be14d3Ssekiya 0x00, 0x00, 0x7f, /* blue */
23827be14d3Ssekiya 0x7f, 0x00, 0x7f, /* magenta */
23927be14d3Ssekiya 0x00, 0x7f, 0x7f, /* cyan */
24027be14d3Ssekiya 0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
24127be14d3Ssekiya };
24227be14d3Ssekiya
24327be14d3Ssekiya static void
grtwo_wait_gfifo(struct grtwo_devconfig * dc)24427be14d3Ssekiya grtwo_wait_gfifo(struct grtwo_devconfig * dc)
24527be14d3Ssekiya {
24627be14d3Ssekiya int2_wait_fifo(1);
24727be14d3Ssekiya }
24827be14d3Ssekiya
2499c873da2Ssekiya static inline void
grtwo_set_color(bus_space_tag_t iot,bus_space_handle_t ioh,int color)2509c873da2Ssekiya grtwo_set_color(bus_space_tag_t iot, bus_space_handle_t ioh, int color)
2519c873da2Ssekiya {
2529c873da2Ssekiya bus_space_write_4(iot, ioh, GR2_FIFO_COLOR, color);
2539c873da2Ssekiya }
2549c873da2Ssekiya
25527be14d3Ssekiya /* Helper functions */
25627be14d3Ssekiya static void
grtwo_fill_rectangle(struct grtwo_devconfig * dc,int x1,int y1,int x2,int y2,u_int8_t color)25727be14d3Ssekiya grtwo_fill_rectangle(struct grtwo_devconfig * dc, int x1, int y1, int x2,
25827be14d3Ssekiya int y2, u_int8_t color)
25927be14d3Ssekiya {
2609c873da2Ssekiya int remaining;
2619c873da2Ssekiya int from_y;
2629c873da2Ssekiya int to_y;
2639c873da2Ssekiya
2649c873da2Ssekiya /* gr2 sees coordinate 0,0 as the lower left corner, and 1279,1023
2659c873da2Ssekiya as the upper right. To keep things consistent, we shall flip the
2669c873da2Ssekiya y axis. */
2679c873da2Ssekiya
2689c873da2Ssekiya /* There appears to be a limit to the number of vertical lines that we
2690ae57f90Smbalmer can run through the graphics engine at one go. This probably has
2709c873da2Ssekiya something to do with vertical refresh. Single-row fills are okay,
2719c873da2Ssekiya multiple-row screw up the board in exciting ways. The copy_rectangle
2729c873da2Ssekiya workaround doesn't work for fills. */
2739c873da2Ssekiya
2749c873da2Ssekiya /* Coordinates, not length. Remember that! */
2759c873da2Ssekiya
276d1579b2dSriastradh to_y = uimin(dc->yres - 1 - y1, dc->yres - 1 - y2);
277d1579b2dSriastradh from_y = uimax(dc->yres - 1 - y1, dc->yres - 1 - y2);
2789c873da2Ssekiya
2799c873da2Ssekiya remaining = to_y - from_y;
28027be14d3Ssekiya
28127be14d3Ssekiya grtwo_wait_gfifo(dc);
2829c873da2Ssekiya grtwo_set_color(dc->iot, dc->ioh, color);
2839c873da2Ssekiya
2849c873da2Ssekiya while (remaining) {
2859c873da2Ssekiya if (remaining <= 32)
2869c873da2Ssekiya {
2879c873da2Ssekiya delay(10000);
28827be14d3Ssekiya grtwo_wait_gfifo(dc);
28927be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTI2D, x1);
2909c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y);
29127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
2929c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y + remaining);
2939c873da2Ssekiya break;
2949c873da2Ssekiya } else {
2959c873da2Ssekiya delay(100000);
2969c873da2Ssekiya grtwo_wait_gfifo(dc);
2979c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTI2D, x1);
2989c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y);
2999c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
3009c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y + remaining);
3019c873da2Ssekiya from_y += 32;
3029c873da2Ssekiya remaining -=32;
3039c873da2Ssekiya }
3049c873da2Ssekiya }
30527be14d3Ssekiya }
30627be14d3Ssekiya
30727be14d3Ssekiya static void
grtwo_copy_rectangle(struct grtwo_devconfig * dc,int x1,int y1,int x2,int y2,int width,int height)30827be14d3Ssekiya grtwo_copy_rectangle(struct grtwo_devconfig * dc, int x1, int y1, int x2,
3099c873da2Ssekiya int y2, int width, int height)
31027be14d3Ssekiya {
3119c873da2Ssekiya int length = (width + 3) >> 2;
31227be14d3Ssekiya int lines = 4864 / length;
31327be14d3Ssekiya int from_y;
31427be14d3Ssekiya int to_y;
3159c873da2Ssekiya int temp_height;
31627be14d3Ssekiya
3179c873da2Ssekiya if ((y2 <= y1) || (height < lines)) {
31827be14d3Ssekiya grtwo_wait_gfifo(dc);
31927be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTCOPY, length);
32027be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, lines);
32127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x1);
32227be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y1);
3239c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, width);
3249c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, height);
32527be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
32627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y2);
32727be14d3Ssekiya } else {
3289c873da2Ssekiya from_y = y1 + height - lines;
3299c873da2Ssekiya to_y = y2 + height - lines;
3309c873da2Ssekiya temp_height = MIN(height, lines);
33127be14d3Ssekiya
3329c873da2Ssekiya while (temp_height) {
33327be14d3Ssekiya grtwo_wait_gfifo(dc);
33427be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTCOPY, length);
33527be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, lines);
33627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x1);
33727be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y);
3389c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, width);
3399c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, temp_height);
34027be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
34127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, to_y);
3429c873da2Ssekiya height -= temp_height;
3439c873da2Ssekiya height = MIN(height, lines);
3449c873da2Ssekiya from_y -= temp_height;
3459c873da2Ssekiya to_y -= temp_height;
34627be14d3Ssekiya }
34727be14d3Ssekiya }
34827be14d3Ssekiya }
34927be14d3Ssekiya
35027be14d3Ssekiya static void
grtwo_cmap_setrgb(struct grtwo_devconfig * dc,int index,u_int8_t r,u_int8_t g,u_int8_t b)35127be14d3Ssekiya grtwo_cmap_setrgb(struct grtwo_devconfig * dc, int index, u_int8_t r, u_int8_t g, u_int8_t b)
35227be14d3Ssekiya {
35327be14d3Ssekiya grtwo_wait_gfifo(dc);
3549c873da2Ssekiya bus_space_write_1(dc->iot, dc->ioh, XMAPALL_ADDRHI,
3559c873da2Ssekiya ((index & 0x1f00) >> 8) );
3569c873da2Ssekiya bus_space_write_1(dc->iot, dc->ioh, XMAPALL_ADDRLO,
35727be14d3Ssekiya (index & 0xff));
3589c873da2Ssekiya bus_space_write_1(dc->iot, dc->ioh, XMAPALL_CLUT, r);
3599c873da2Ssekiya bus_space_write_1(dc->iot, dc->ioh, XMAPALL_CLUT, g);
3609c873da2Ssekiya bus_space_write_1(dc->iot, dc->ioh, XMAPALL_CLUT, b);
36127be14d3Ssekiya }
36227be14d3Ssekiya
36327be14d3Ssekiya static void
grtwo_setup_hw(struct grtwo_devconfig * dc)36427be14d3Ssekiya grtwo_setup_hw(struct grtwo_devconfig * dc)
36527be14d3Ssekiya {
36627be14d3Ssekiya int i = 0;
36727be14d3Ssekiya
36827be14d3Ssekiya /* Get various revisions */
36927be14d3Ssekiya dc->boardrev = (~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD0))) & GR2_REVISION_RD0_VERSION_MASK;
37027be14d3Ssekiya
37127be14d3Ssekiya /*
37227be14d3Ssekiya * boards prior to rev 4 have a pretty whacky config scheme.
37327be14d3Ssekiya * what is doubly weird is that i have a rev 2 board, but the rev 4
37427be14d3Ssekiya * probe routines work just fine.
37527be14d3Ssekiya * we'll trust SGI, though, and separate things a bit. it's only
37627be14d3Ssekiya * critical for the display depth calculation.
37727be14d3Ssekiya */
37827be14d3Ssekiya
37927be14d3Ssekiya if (dc->boardrev < 4) {
38027be14d3Ssekiya dc->backendrev = ~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD2) & GR2_REVISION_RD2_BACKEND_REV) >> 2;
38127be14d3Ssekiya if (dc->backendrev == 0)
38227be14d3Ssekiya return;
38327be14d3Ssekiya dc->zbuffer = !(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION_RD1_ZBUFFER);
38427be14d3Ssekiya if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMA) != 3)
38527be14d3Ssekiya i++;
38627be14d3Ssekiya if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMB) != 0x0c)
38727be14d3Ssekiya i++;
38827be14d3Ssekiya if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMC) != 0x30)
38927be14d3Ssekiya i++;
39027be14d3Ssekiya dc->depth = 8 * i;
39127be14d3Ssekiya dc->monitor =
39227be14d3Ssekiya ((bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD2) & 0x03) << 1) |
39327be14d3Ssekiya (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & 0x01);
39427be14d3Ssekiya } else {
39527be14d3Ssekiya dc->backendrev = ~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1)) & 0x03;
39627be14d3Ssekiya if (dc->backendrev == 0)
39727be14d3Ssekiya return;
39827be14d3Ssekiya dc->zbuffer = bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION4_RD1_ZBUFFER;
39927be14d3Ssekiya dc->depth = ((bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION4_RD1_24BPP) >> 4) ? 24 : 8;
40027be14d3Ssekiya dc->monitor = (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD0) & GR2_REVISION4_RD0_MONITOR_MASK) >> 4;
40127be14d3Ssekiya }
40227be14d3Ssekiya
40327be14d3Ssekiya dc->hq2rev = (bus_space_read_4(dc->iot, dc->ioh, HQ2_VERSION) & HQ2_VERSION_MASK) >> HQ2_VERSION_SHIFT;
40427be14d3Ssekiya dc->ge7rev = (bus_space_read_4(dc->iot, dc->ioh, GE7_REVISION) & GE7_REVISION_MASK) >> 5;
40527be14d3Ssekiya /* dc->vc1rev = vc1_read_ireg(dc, 5) & 0x07; */
40627be14d3Ssekiya
40727be14d3Ssekiya /* gr2 supports 1280x1024 only */
40827be14d3Ssekiya dc->xres = 1280;
40927be14d3Ssekiya dc->yres = 1024;
41027be14d3Ssekiya
41127be14d3Ssekiya #if 0
41227be14d3Ssekiya /* Setup cursor glyph */
41327be14d3Ssekiya
41427be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI,
41527be14d3Ssekiya (VC1_SRAM_CURSOR0_BASE >> 8) & 0xff);
41627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO,
41727be14d3Ssekiya VC1_SRAM_CURSOR0_BASE & 0xff);
41827be14d3Ssekiya for (i = 0; i < 128; i++)
41927be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_SRAM, grtwo_cursor_data[i]);
42027be14d3Ssekiya
42127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI,
42227be14d3Ssekiya (VC1_CURSOR_EP >> 8) & 0xff);
42327be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO,
42427be14d3Ssekiya VC1_CURSOR_EP & 0xff);
42527be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, VC1_SRAM_CURSOR0_BASE);
42627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
42727be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
42827be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
42927be14d3Ssekiya
43027be14d3Ssekiya /* Turn on cursor function, display, DID */
43127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
43227be14d3Ssekiya VC1_SYSCTL_VC1 | VC1_SYSCTL_DID |
43327be14d3Ssekiya VC1_SYSCTL_CURSOR | VC1_SYSCTL_CURSOR_DISPLAY);
43427be14d3Ssekiya #endif
43527be14d3Ssekiya
43627be14d3Ssekiya /* Setup CMAP */
43727be14d3Ssekiya for (i = 0; i < 8; i++)
43827be14d3Ssekiya grtwo_cmap_setrgb(dc, i, grtwo_defcmap[i * 3],
43927be14d3Ssekiya grtwo_defcmap[i * 3 + 1], grtwo_defcmap[i * 3 + 2]);
44027be14d3Ssekiya }
44127be14d3Ssekiya
44227be14d3Ssekiya /* Attach routines */
44327be14d3Ssekiya static int
grtwo_match(device_t parent,cfdata_t cf,void * aux)444cbab9cadSchs grtwo_match(device_t parent, cfdata_t cf, void *aux)
44527be14d3Ssekiya {
44627be14d3Ssekiya struct gio_attach_args *ga = aux;
44727be14d3Ssekiya
448860011e4Srumble if (ga->ga_addr != 0x1f000000 && ga->ga_addr != 0x1f400000 &&
449860011e4Srumble ga->ga_addr != 0x1f600000)
450860011e4Srumble return (0);
451860011e4Srumble
45227be14d3Ssekiya /*
45327be14d3Ssekiya * grtwo doesn't have anything that even vaguely resembles a product
45427be14d3Ssekiya * ID. Instead, we determine presence by looking at the HQ2 "mystery"
45527be14d3Ssekiya * register, which contains a magic number.
45627be14d3Ssekiya */
457*0aeb5daeSandvar if ( platform.badaddr((void *)(intptr_t)(ga->ga_ioh + HQ2_MYSTERY),
4581426ceedSrumble sizeof(u_int32_t)) )
45927be14d3Ssekiya return 0;
46027be14d3Ssekiya
46127be14d3Ssekiya if ( (bus_space_read_4(ga->ga_iot, ga->ga_ioh, HQ2_MYSTERY)) != 0xdeadbeef)
46227be14d3Ssekiya return 0;
46327be14d3Ssekiya
46427be14d3Ssekiya return 1;
46527be14d3Ssekiya }
46627be14d3Ssekiya
46727be14d3Ssekiya static void
grtwo_attach_common(struct grtwo_devconfig * dc,struct gio_attach_args * ga)46827be14d3Ssekiya grtwo_attach_common(struct grtwo_devconfig * dc, struct gio_attach_args * ga)
46927be14d3Ssekiya {
47027be14d3Ssekiya dc->dc_addr = ga->ga_addr;
47127be14d3Ssekiya
47227be14d3Ssekiya dc->iot = ga->ga_iot;
47327be14d3Ssekiya dc->ioh = ga->ga_ioh;
4749c873da2Ssekiya int i = 0;
47527be14d3Ssekiya
47627be14d3Ssekiya wsfont_init();
47727be14d3Ssekiya
47827be14d3Ssekiya dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
479b98ab6a8Smacallan WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP);
48027be14d3Ssekiya
48127be14d3Ssekiya if (dc->dc_font < 0)
48227be14d3Ssekiya panic("grtwo_attach_common: no suitable fonts");
48327be14d3Ssekiya
48427be14d3Ssekiya if (wsfont_lock(dc->dc_font, &dc->dc_fontdata))
48527be14d3Ssekiya panic("grtwo_attach_common: unable to lock font data");
48627be14d3Ssekiya
48727be14d3Ssekiya grtwo_setup_hw(dc);
48827be14d3Ssekiya
4899c873da2Ssekiya /* Large fills are broken. For now, clear the screen line-by-line. */
4909c873da2Ssekiya for (i = 0; i < 64; i++)
4919c873da2Ssekiya grtwo_eraserows(dc, i, 1, 0);
4929c873da2Ssekiya
4939c873da2Ssekiya /* If large fills worked, we'd do this instead:
4949c873da2Ssekiya grtwo_fill_rectangle(dc, 0, 0, dc->xres - 1, dc->yres - 1, 0);
4959c873da2Ssekiya */
49627be14d3Ssekiya }
49727be14d3Ssekiya
49827be14d3Ssekiya static void
grtwo_attach(device_t parent,device_t self,void * aux)499cbab9cadSchs grtwo_attach(device_t parent, device_t self, void *aux)
50027be14d3Ssekiya {
50127be14d3Ssekiya struct gio_attach_args *ga = aux;
502cbab9cadSchs struct grtwo_softc *sc = device_private(self);
50327be14d3Ssekiya struct wsemuldisplaydev_attach_args wa;
50427be14d3Ssekiya
50527be14d3Ssekiya if (grtwo_is_console && ga->ga_addr == grtwo_console_dc.dc_addr) {
50627be14d3Ssekiya wa.console = 1;
50727be14d3Ssekiya sc->sc_dc = &grtwo_console_dc;
50827be14d3Ssekiya } else {
50927be14d3Ssekiya wa.console = 0;
51061a80495Sthorpej sc->sc_dc = kmem_zalloc(sizeof(struct grtwo_devconfig),
51161a80495Sthorpej KM_SLEEP);
51227be14d3Ssekiya
51327be14d3Ssekiya grtwo_attach_common(sc->sc_dc, ga);
51427be14d3Ssekiya }
51527be14d3Ssekiya
51627be14d3Ssekiya aprint_naive(": Display adapter\n");
51727be14d3Ssekiya
518faa2f316Ssekiya aprint_normal(": GR2 (board rev %x, monitor %d, depth %d)\n",
51927be14d3Ssekiya sc->sc_dc->boardrev, sc->sc_dc->monitor, sc->sc_dc->depth);
52027be14d3Ssekiya
52127be14d3Ssekiya wa.scrdata = &grtwo_screenlist;
52227be14d3Ssekiya wa.accessops = &grtwo_accessops;
52327be14d3Ssekiya wa.accesscookie = sc->sc_dc;
52427be14d3Ssekiya
5259c873da2Ssekiya if ((cpu_intr_establish(0, IPL_TTY, grtwo_intr0, sc)) == NULL)
5269c873da2Ssekiya printf(": unable to establish interrupt!\n");
5279c873da2Ssekiya
5289c873da2Ssekiya if ((cpu_intr_establish(6, IPL_TTY, grtwo_intr6, sc)) == NULL)
5299c873da2Ssekiya printf(": unable to establish interrupt!\n");
5309c873da2Ssekiya
531c7fb772bSthorpej config_found(self, &wa, wsemuldisplaydevprint, CFARGS_NONE);
53227be14d3Ssekiya }
53327be14d3Ssekiya
53427be14d3Ssekiya int
grtwo_cnattach(struct gio_attach_args * ga)53527be14d3Ssekiya grtwo_cnattach(struct gio_attach_args * ga)
53627be14d3Ssekiya {
53727be14d3Ssekiya long defattr = GR2_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK);
53827be14d3Ssekiya
53927be14d3Ssekiya if (!grtwo_match(NULL, NULL, ga)) {
54027be14d3Ssekiya return ENXIO;
54127be14d3Ssekiya }
54227be14d3Ssekiya
54327be14d3Ssekiya grtwo_attach_common(&grtwo_console_dc, ga);
5449c289db8Ssekiya wsdisplay_cnattach(&grtwo_screen, &grtwo_console_dc, 0, 0, defattr);
54527be14d3Ssekiya
54627be14d3Ssekiya grtwo_is_console = 1;
54727be14d3Ssekiya
54827be14d3Ssekiya return 0;
54927be14d3Ssekiya }
55027be14d3Ssekiya
55127be14d3Ssekiya /* wsdisplay textops */
55227be14d3Ssekiya static void
grtwo_cursor(void * c,int on,int row,int col)55327be14d3Ssekiya grtwo_cursor(void *c, int on, int row, int col)
55427be14d3Ssekiya {
55527be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
55627be14d3Ssekiya u_int32_t control;
55727be14d3Ssekiya control = bus_space_read_4(dc->iot, dc->ioh, VC1_SYSCTL);
55827be14d3Ssekiya
55927be14d3Ssekiya if (!on) {
56027be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
56127be14d3Ssekiya control & ~VC1_SYSCTL_CURSOR_DISPLAY);
56227be14d3Ssekiya } else {
56327be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI, (VC1_CURSOR_XL & 0xff00) >> 8
56427be14d3Ssekiya );
56527be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO, VC1_CURSOR_XL & 0xff);
56627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND,
56727be14d3Ssekiya col * dc->dc_fontdata->fontwidth);
56827be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND,
56927be14d3Ssekiya row * dc->dc_fontdata->fontheight);
57027be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
57127be14d3Ssekiya control | VC1_SYSCTL_CURSOR_DISPLAY);
57227be14d3Ssekiya }
57327be14d3Ssekiya }
57427be14d3Ssekiya
57527be14d3Ssekiya static int
grtwo_mapchar(void * c,int ch,unsigned int * cp)57627be14d3Ssekiya grtwo_mapchar(void *c, int ch, unsigned int *cp)
57727be14d3Ssekiya {
57827be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
57927be14d3Ssekiya
58027be14d3Ssekiya if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
58127be14d3Ssekiya ch = wsfont_map_unichar(dc->dc_fontdata, ch);
58227be14d3Ssekiya
58327be14d3Ssekiya if (ch < 0)
58427be14d3Ssekiya goto fail;
58527be14d3Ssekiya }
58627be14d3Ssekiya if (ch < dc->dc_fontdata->firstchar ||
58727be14d3Ssekiya ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars)
58827be14d3Ssekiya goto fail;
58927be14d3Ssekiya
59027be14d3Ssekiya *cp = ch;
59127be14d3Ssekiya return 5;
59227be14d3Ssekiya
59327be14d3Ssekiya fail:
59427be14d3Ssekiya *cp = ' ';
59527be14d3Ssekiya return 0;
59627be14d3Ssekiya }
59727be14d3Ssekiya
59827be14d3Ssekiya static void
grtwo_putchar(void * c,int row,int col,u_int ch,long attr)59927be14d3Ssekiya grtwo_putchar(void *c, int row, int col, u_int ch, long attr)
60027be14d3Ssekiya {
60127be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
60227be14d3Ssekiya struct wsdisplay_font *font = dc->dc_fontdata;
6039c873da2Ssekiya u_int8_t *bitmap = (u_int8_t *) font->data + (ch - font->firstchar + 1) * font->fontheight * font->stride;
60427be14d3Ssekiya u_int32_t pattern;
60527be14d3Ssekiya int i;
60627be14d3Ssekiya int x = col * font->fontwidth;
60727be14d3Ssekiya int y = dc->yres - ( (row + 1) * font->fontheight);
60827be14d3Ssekiya
60927be14d3Ssekiya /* Set the drawing color */
61027be14d3Ssekiya grtwo_wait_gfifo(dc);
6119c873da2Ssekiya grtwo_set_color(dc->iot, dc->ioh, (((attr) >> 8) & 0xff));
6129c873da2Ssekiya grtwo_wait_gfifo(dc);
61327be14d3Ssekiya
61427be14d3Ssekiya /* Set drawing coordinates */
61527be14d3Ssekiya grtwo_wait_gfifo(dc);
61627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_CMOV2I, x);
61727be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y);
61827be14d3Ssekiya
6199c873da2Ssekiya /* This works for font sizes < 18 */
62027be14d3Ssekiya grtwo_wait_gfifo(dc);
62127be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DRAWCHAR, font->fontwidth);
62227be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, font->fontheight);
6239c873da2Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 2);
62427be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0); /* x offset */
62527be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0); /* y offset */
62627be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0);
62727be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0);
62827be14d3Ssekiya
62927be14d3Ssekiya for (i = 0; i < font->fontheight; i++) {
63027be14d3Ssekiya /* It appears that writes have to be 16 bits. An "I tell you
63127be14d3Ssekiya two times" sort of thing? Thanks, SGI */
63227be14d3Ssekiya pattern = *bitmap | (*bitmap << 8);
63327be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, pattern);
6349c873da2Ssekiya bitmap -= font->stride;
63527be14d3Ssekiya }
63627be14d3Ssekiya
63727be14d3Ssekiya /* pad up to 18 */
63827be14d3Ssekiya for (i = font->fontheight; i < 18; i++)
63927be14d3Ssekiya bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0x0000);
64027be14d3Ssekiya }
64127be14d3Ssekiya
64227be14d3Ssekiya static void
grtwo_copycols(void * c,int row,int srccol,int dstcol,int ncols)64327be14d3Ssekiya grtwo_copycols(void *c, int row, int srccol, int dstcol, int ncols)
64427be14d3Ssekiya {
6459c873da2Ssekiya #if 1
6469c873da2Ssekiya printf("grtwo_copycols: %i %i %i %i\n", row, srccol, dstcol, ncols);
6479c873da2Ssekiya #else
64827be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
64927be14d3Ssekiya struct wsdisplay_font *font = dc->dc_fontdata;
65027be14d3Ssekiya grtwo_copy_rectangle(dc,
65127be14d3Ssekiya srccol * font->fontwidth, /* x1 */
6529c873da2Ssekiya 0, /* y1 */
6539c873da2Ssekiya dstcol * font->fontwidth, /* x2 */
6549c873da2Ssekiya 0, /* y2 */
6559c873da2Ssekiya ncols * font->fontwidth, /* dx */
6569c873da2Ssekiya dc->yres ); /* dy */
6579c873da2Ssekiya #endif
65827be14d3Ssekiya }
65927be14d3Ssekiya
66027be14d3Ssekiya static void
grtwo_erasecols(void * c,int row,int startcol,int ncols,long attr)66127be14d3Ssekiya grtwo_erasecols(void *c, int row, int startcol, int ncols, long attr)
66227be14d3Ssekiya {
66327be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
66427be14d3Ssekiya struct wsdisplay_font *font = dc->dc_fontdata;
66527be14d3Ssekiya
66627be14d3Ssekiya grtwo_fill_rectangle(dc,
66727be14d3Ssekiya startcol * font->fontwidth, /* x1 */
6689c873da2Ssekiya 0, /* y1 */
6699c873da2Ssekiya (startcol * font->fontwidth) + ncols * font->fontwidth, /* x2 */
6709c873da2Ssekiya dc->yres, /* y2 */
67127be14d3Ssekiya GR2_ATTR_BG(attr));
67227be14d3Ssekiya }
67327be14d3Ssekiya
67427be14d3Ssekiya static void
grtwo_copyrows(void * c,int srcrow,int dstrow,int nrows)67527be14d3Ssekiya grtwo_copyrows(void *c, int srcrow, int dstrow, int nrows)
67627be14d3Ssekiya {
67727be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
67827be14d3Ssekiya struct wsdisplay_font *font = dc->dc_fontdata;
67927be14d3Ssekiya
68027be14d3Ssekiya grtwo_copy_rectangle(dc,
68127be14d3Ssekiya 0, /* x1 */
68227be14d3Ssekiya srcrow * font->fontheight, /* y1 */
6839c873da2Ssekiya 0, /* x2 */
6849c873da2Ssekiya dstrow * font->fontheight, /* y2 */
6859c873da2Ssekiya dc->xres, /* dx */
6869c873da2Ssekiya nrows * font->fontheight);
68727be14d3Ssekiya }
68827be14d3Ssekiya
68927be14d3Ssekiya static void
grtwo_eraserows(void * c,int startrow,int nrows,long attr)69027be14d3Ssekiya grtwo_eraserows(void *c, int startrow, int nrows, long attr)
69127be14d3Ssekiya {
69227be14d3Ssekiya struct grtwo_devconfig *dc = (void *) c;
69327be14d3Ssekiya struct wsdisplay_font *font = dc->dc_fontdata;
69427be14d3Ssekiya grtwo_fill_rectangle(dc,
69527be14d3Ssekiya 0, /* x1 */
69627be14d3Ssekiya startrow * font->fontheight, /* y1 */
69727be14d3Ssekiya dc->xres, /* x2 */
6989c873da2Ssekiya (startrow * font->fontheight) + nrows * font->fontheight, /* y2 */
69927be14d3Ssekiya GR2_ATTR_BG(attr));
70027be14d3Ssekiya }
70127be14d3Ssekiya
70227be14d3Ssekiya static int
grtwo_allocattr(void * c,int fg,int bg,int flags,long * attr)70327be14d3Ssekiya grtwo_allocattr(void *c, int fg, int bg, int flags, long *attr)
70427be14d3Ssekiya {
70527be14d3Ssekiya if (flags & WSATTR_BLINK)
70627be14d3Ssekiya return EINVAL;
70727be14d3Ssekiya
70827be14d3Ssekiya if ((flags & WSATTR_WSCOLORS) == 0) {
70927be14d3Ssekiya fg = WSCOL_WHITE;
71027be14d3Ssekiya bg = WSCOL_BLACK;
71127be14d3Ssekiya }
71227be14d3Ssekiya if (flags & WSATTR_HILIT)
71327be14d3Ssekiya fg += 8;
71427be14d3Ssekiya
71527be14d3Ssekiya if (flags & WSATTR_REVERSE) {
71627be14d3Ssekiya int tmp = fg;
71727be14d3Ssekiya fg = bg;
71827be14d3Ssekiya bg = tmp;
71927be14d3Ssekiya }
72027be14d3Ssekiya *attr = GR2_ATTR_ENCODE(fg, bg);
72127be14d3Ssekiya
72227be14d3Ssekiya return 0;
72327be14d3Ssekiya }
72427be14d3Ssekiya
72527be14d3Ssekiya /* wsdisplay accessops */
72627be14d3Ssekiya
72727be14d3Ssekiya static int
grtwo_ioctl(void * c,void * vs,u_long cmd,void * data,int flag,struct lwp * l)72853524e44Schristos grtwo_ioctl(void *c, void *vs, u_long cmd, void *data, int flag,
7297a51d4ddSjmmv struct lwp *l)
73027be14d3Ssekiya {
73127be14d3Ssekiya struct grtwo_softc *sc = c;
73227be14d3Ssekiya
73327be14d3Ssekiya #define FBINFO (*(struct wsdisplay_fbinfo*)data)
73427be14d3Ssekiya
73527be14d3Ssekiya switch (cmd) {
73627be14d3Ssekiya case WSDISPLAYIO_GINFO:
73727be14d3Ssekiya FBINFO.width = sc->sc_dc->xres;
73827be14d3Ssekiya FBINFO.height = sc->sc_dc->yres;
73927be14d3Ssekiya FBINFO.depth = sc->sc_dc->depth;
74027be14d3Ssekiya FBINFO.cmsize = 1 << FBINFO.depth;
74127be14d3Ssekiya return 0;
74227be14d3Ssekiya case WSDISPLAYIO_GTYPE:
74327be14d3Ssekiya *(u_int *) data = WSDISPLAY_TYPE_GR2;
74427be14d3Ssekiya return 0;
74527be14d3Ssekiya }
74627be14d3Ssekiya return EPASSTHROUGH;
74727be14d3Ssekiya }
74827be14d3Ssekiya
74927be14d3Ssekiya static paddr_t
grtwo_mmap(void * c,void * vs,off_t offset,int prot)7507a51d4ddSjmmv grtwo_mmap(void *c, void *vs, off_t offset, int prot)
75127be14d3Ssekiya {
75227be14d3Ssekiya struct grtwo_devconfig *dc = c;
75327be14d3Ssekiya
75427be14d3Ssekiya if (offset >= 0xfffff)
75527be14d3Ssekiya return -1;
75627be14d3Ssekiya
75727be14d3Ssekiya return mips_btop(dc->dc_addr + offset);
75827be14d3Ssekiya }
75927be14d3Ssekiya
76027be14d3Ssekiya static int
grtwo_alloc_screen(void * c,const struct wsscreen_descr * type,void ** cookiep,int * cursxp,int * cursyp,long * attrp)76127be14d3Ssekiya grtwo_alloc_screen(void *c, const struct wsscreen_descr * type, void **cookiep,
76227be14d3Ssekiya int *cursxp, int *cursyp, long *attrp)
76327be14d3Ssekiya {
76427be14d3Ssekiya /*
76527be14d3Ssekiya * This won't get called for console screen and we don't support
76627be14d3Ssekiya * virtual screens
76727be14d3Ssekiya */
76827be14d3Ssekiya
76927be14d3Ssekiya return ENOMEM;
77027be14d3Ssekiya }
77127be14d3Ssekiya
77227be14d3Ssekiya static void
grtwo_free_screen(void * c,void * cookie)77327be14d3Ssekiya grtwo_free_screen(void *c, void *cookie)
77427be14d3Ssekiya {
77527be14d3Ssekiya panic("grtwo_free_screen");
77627be14d3Ssekiya }
77727be14d3Ssekiya static int
grtwo_show_screen(void * c,void * cookie,int waitok,void (* cb)(void *,int,int),void * cbarg)77827be14d3Ssekiya grtwo_show_screen(void *c, void *cookie, int waitok,
77927be14d3Ssekiya void (*cb) (void *, int, int), void *cbarg)
78027be14d3Ssekiya {
78127be14d3Ssekiya return 0;
78227be14d3Ssekiya }
7839c873da2Ssekiya
7849c873da2Ssekiya static int
grtwo_intr0(void * arg)7859c873da2Ssekiya grtwo_intr0(void *arg)
7869c873da2Ssekiya {
7879c873da2Ssekiya /* struct grtwo_devconfig *dc = arg; */
7889c873da2Ssekiya return 1;
7899c873da2Ssekiya }
7909c873da2Ssekiya
7919c873da2Ssekiya
7929c873da2Ssekiya static int
grtwo_intr6(void * arg)7939c873da2Ssekiya grtwo_intr6(void *arg)
7949c873da2Ssekiya {
7959c873da2Ssekiya /* struct grtwo_devconfig *dc = arg; */
7969c873da2Ssekiya return 1;
7979c873da2Ssekiya }
7989c873da2Ssekiya
799