xref: /netbsd-src/sys/arch/amiga/dev/mntva.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: mntva.c,v 1.5 2021/08/07 16:18:41 thorpej Exp $	*/
2a1ee30a1Srkujawa 
3a1ee30a1Srkujawa /*
4a1ee30a1Srkujawa  * Copyright (c) 2012, 2016 The NetBSD Foundation, Inc.
5a1ee30a1Srkujawa  * All rights reserved.
6a1ee30a1Srkujawa  *
7a1ee30a1Srkujawa  * This code is derived from software contributed to The NetBSD Foundation
8a1ee30a1Srkujawa  * by Lukas F. Hartmann.
9a1ee30a1Srkujawa  * This code is derived from software contributed to The NetBSD Foundation
10a1ee30a1Srkujawa  * by Radoslaw Kujawa.
11a1ee30a1Srkujawa  *
12a1ee30a1Srkujawa  * Redistribution and use in source and binary forms, with or without
13a1ee30a1Srkujawa  * modification, are permitted provided that the following conditions
14a1ee30a1Srkujawa  * are met:
15a1ee30a1Srkujawa  * 1. Redistributions of source code must retain the above copyright
16a1ee30a1Srkujawa  *	notice, this list of conditions and the following disclaimer.
17a1ee30a1Srkujawa  * 2. Redistributions in binary form must reproduce the above copyright
18a1ee30a1Srkujawa  *	notice, this list of conditions and the following disclaimer in the
19a1ee30a1Srkujawa  *	documentation and/or other materials provided with the distribution.
20a1ee30a1Srkujawa  *
21a1ee30a1Srkujawa  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22a1ee30a1Srkujawa  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23a1ee30a1Srkujawa  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24a1ee30a1Srkujawa  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25a1ee30a1Srkujawa  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26a1ee30a1Srkujawa  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27a1ee30a1Srkujawa  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28a1ee30a1Srkujawa  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29a1ee30a1Srkujawa  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30a1ee30a1Srkujawa  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31a1ee30a1Srkujawa  */
32a1ee30a1Srkujawa 
33a1ee30a1Srkujawa #include <sys/cdefs.h>
34*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: mntva.c,v 1.5 2021/08/07 16:18:41 thorpej Exp $");
35a1ee30a1Srkujawa 
36a1ee30a1Srkujawa #include <sys/param.h>
37a1ee30a1Srkujawa #include <sys/systm.h>
38a1ee30a1Srkujawa #include <sys/kernel.h>
39a1ee30a1Srkujawa #include <sys/device.h>
40a1ee30a1Srkujawa #include <sys/endian.h>
41a1ee30a1Srkujawa #include <sys/bus.h>
42a1ee30a1Srkujawa #include <sys/cpu.h>
43a1ee30a1Srkujawa #include <sys/conf.h>
44a1ee30a1Srkujawa 
45a1ee30a1Srkujawa #include <dev/cons.h>
46a1ee30a1Srkujawa 
47a1ee30a1Srkujawa #include <amiga/amiga/device.h>
48a1ee30a1Srkujawa #include <amiga/amiga/isr.h>
49a1ee30a1Srkujawa 
50a1ee30a1Srkujawa #include <amiga/dev/zbusvar.h>
51a1ee30a1Srkujawa #include <amiga/dev/mntvavar.h>
52a1ee30a1Srkujawa #include <amiga/dev/mntvareg.h>
53a1ee30a1Srkujawa #include <dev/wsfb/genfbvar.h>
54a1ee30a1Srkujawa 
55a1ee30a1Srkujawa #include "opt_amigacons.h"
56a1ee30a1Srkujawa #include "opt_wsemul.h"
57a1ee30a1Srkujawa #include "opt_mntva.h"
58a1ee30a1Srkujawa #include "opt_wsfb.h"
59a1ee30a1Srkujawa 
60a1ee30a1Srkujawa #include "mntva.h"
61a1ee30a1Srkujawa 
62a1ee30a1Srkujawa /* #define MNTVA_DEBUG 1 */
63a1ee30a1Srkujawa 
64a1ee30a1Srkujawa static int mntva_match(device_t, cfdata_t, void *);
65a1ee30a1Srkujawa static void mntva_attach(device_t, device_t, void *);
66a1ee30a1Srkujawa 
67a1ee30a1Srkujawa static uint16_t mntva_reg_read(struct mntva_softc *sc, uint32_t reg);
68a1ee30a1Srkujawa static void mntva_reg_write(struct mntva_softc *sc, uint32_t reg, uint32_t val);
69a1ee30a1Srkujawa 
70a1ee30a1Srkujawa static bool mntva_mode_set(struct mntva_softc *sc);
71a1ee30a1Srkujawa 
72a1ee30a1Srkujawa static paddr_t mntva_mmap(void *v, void *vs, off_t offset, int prot);
73a1ee30a1Srkujawa static int mntva_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
74a1ee30a1Srkujawa     struct lwp *l);
75a1ee30a1Srkujawa static void mntva_init_screen(void *cookie, struct vcons_screen *scr,
76a1ee30a1Srkujawa     int existing, long *defattr);
77a1ee30a1Srkujawa static void mntva_init_palette(struct mntva_softc *sc);
78a1ee30a1Srkujawa /* blitter support */
79a1ee30a1Srkujawa static void mntva_rectfill(struct mntva_softc *sc, int x, int y, int wi,
80a1ee30a1Srkujawa     int he, uint32_t color);
81a1ee30a1Srkujawa static void mntva_bitblt(struct mntva_softc *sc, int xs, int ys, int xd,
82a1ee30a1Srkujawa     int yd, int wi, int he);
83a1ee30a1Srkujawa 
84a1ee30a1Srkujawa /* accelerated raster ops */
85a1ee30a1Srkujawa static void mntva_eraserows(void *cookie, int row, int nrows, long fillattr);
86a1ee30a1Srkujawa static void mntva_copyrows(void *cookie, int srcrow, int dstrow, int nrows);
87a1ee30a1Srkujawa static void mntva_copycols(void *cookie, int row, int srccol, int dstcol,
88a1ee30a1Srkujawa     int ncols);
89a1ee30a1Srkujawa static void mntva_erasecols(void *cookie, int row, int startcol, int ncols,
90a1ee30a1Srkujawa     long fillattr);
91a1ee30a1Srkujawa #if 0
92a1ee30a1Srkujawa static void mntva_cursor(void *cookie, int on, int row, int col);
93a1ee30a1Srkujawa #endif
94a1ee30a1Srkujawa 
95a1ee30a1Srkujawa /*
96a1ee30a1Srkujawa  * XXX: these will be called by console handling code, shouldn't they be
97a1ee30a1Srkujawa  * included from somewhere else?
98a1ee30a1Srkujawa  */
99a1ee30a1Srkujawa void mntvacninit(struct consdev *cd);
100a1ee30a1Srkujawa void mntvacnprobe(struct consdev *cd);
101a1ee30a1Srkujawa void mntvacnputc(dev_t cd, int ch);
102a1ee30a1Srkujawa int mntvacngetc(dev_t cd);
103a1ee30a1Srkujawa void mntvacnpollc(dev_t cd, int on);
104a1ee30a1Srkujawa 
105a1ee30a1Srkujawa CFATTACH_DECL_NEW(mntva, sizeof(struct mntva_softc),
106a1ee30a1Srkujawa     mntva_match, mntva_attach, NULL, NULL);
107a1ee30a1Srkujawa 
108a1ee30a1Srkujawa struct wsdisplay_accessops mntva_accessops = {
109a1ee30a1Srkujawa 	mntva_ioctl,
110a1ee30a1Srkujawa 	mntva_mmap,
111a1ee30a1Srkujawa 	NULL,			// alloc_screen
112a1ee30a1Srkujawa 	NULL,			// free_screen
113a1ee30a1Srkujawa 	NULL,			// show_screen
114a1ee30a1Srkujawa 	NULL,			// load_font
115a1ee30a1Srkujawa 	NULL,			// pollc
116a1ee30a1Srkujawa 	NULL			// scroll
117a1ee30a1Srkujawa };
118a1ee30a1Srkujawa 
119a1ee30a1Srkujawa static int
mntva_match(device_t parent,cfdata_t match,void * aux)120a1ee30a1Srkujawa mntva_match(device_t parent, cfdata_t match, void *aux)
121a1ee30a1Srkujawa {
122a1ee30a1Srkujawa 	struct zbus_args *zap = aux;
123a1ee30a1Srkujawa 
124a1ee30a1Srkujawa 	if (zap->manid == 0x6d6e && zap->prodid == 1) {
125a1ee30a1Srkujawa #ifdef MNTVA_DEBUG
126a1ee30a1Srkujawa 		/* XXX: this might not work during console init? */
127a1ee30a1Srkujawa 		aprint_normal("mntva_match... success!\n");
128a1ee30a1Srkujawa #endif /* MNTVA_DEBUG */
129a1ee30a1Srkujawa 		return 1;
130a1ee30a1Srkujawa 	}
131a1ee30a1Srkujawa 
132a1ee30a1Srkujawa 	return 0;
133a1ee30a1Srkujawa }
134a1ee30a1Srkujawa 
135a1ee30a1Srkujawa static void
mntva_attach(device_t parent,device_t self,void * aux)136a1ee30a1Srkujawa mntva_attach(device_t parent, device_t self, void *aux)
137a1ee30a1Srkujawa {
138a1ee30a1Srkujawa 	struct mntva_softc *sc = device_private(self);
139a1ee30a1Srkujawa 	struct wsemuldisplaydev_attach_args ws_aa;
140a1ee30a1Srkujawa 	struct rasops_info *ri;
141a1ee30a1Srkujawa 	struct zbus_args *zap = aux;
142a1ee30a1Srkujawa 	long defattr;
143a1ee30a1Srkujawa 
144a1ee30a1Srkujawa 	sc->sc_isconsole = false;
145a1ee30a1Srkujawa /* this should come from "opt_mntva.h" auto generated by kernel conf system */
146a1ee30a1Srkujawa #ifdef MNTVA_CONSOLE
147a1ee30a1Srkujawa 	sc->sc_isconsole = true;
148a1ee30a1Srkujawa #endif /* MNTVA_CONSOLE */
149a1ee30a1Srkujawa 
15066eee726Srkujawa 	printf(": MNT VA2000");
151a1ee30a1Srkujawa 
152a1ee30a1Srkujawa 	if(sc->sc_isconsole)
153a1ee30a1Srkujawa 		printf(" (console)");
154a1ee30a1Srkujawa 
155a1ee30a1Srkujawa 	printf("\n");
156a1ee30a1Srkujawa 
157a1ee30a1Srkujawa 	sc->sc_dev = self;
158a1ee30a1Srkujawa 	sc->sc_memsize = MNTVA_FB_SIZE;
159a1ee30a1Srkujawa 
160a1ee30a1Srkujawa 	sc->sc_bst.base = (bus_addr_t) zap->va;
161a1ee30a1Srkujawa 	sc->sc_bst.absm = &amiga_bus_stride_1;
162a1ee30a1Srkujawa 	sc->sc_iot = &sc->sc_bst;
163a1ee30a1Srkujawa 
164a1ee30a1Srkujawa 	if (bus_space_map(sc->sc_iot, MNTVA_OFF_REG, MNTVA_REG_SIZE , 0,
165a1ee30a1Srkujawa 	    &sc->sc_regh)) {
166a1ee30a1Srkujawa 		aprint_error_dev(sc->sc_dev, "mapping registers failed\n");
167a1ee30a1Srkujawa 		return;
168a1ee30a1Srkujawa 	}
16966eee726Srkujawa 	if (bus_space_map(sc->sc_iot, MNTVA_OFF_FB, sc->sc_memsize,
17066eee726Srkujawa 	    BUS_SPACE_MAP_LINEAR, &sc->sc_fbh)) {
17166eee726Srkujawa 		aprint_error_dev(sc->sc_dev, "mapping framebuffer failed\n");
17266eee726Srkujawa 		return;
17366eee726Srkujawa 	}
174a1ee30a1Srkujawa 
175a1ee30a1Srkujawa 	sc->sc_regpa = (bus_addr_t) kvtop((void*) sc->sc_regh);
176a1ee30a1Srkujawa 	sc->sc_fbpa = (bus_addr_t) kvtop((void*) sc->sc_fbh);
177a1ee30a1Srkujawa 
178a1ee30a1Srkujawa 	/* print the physical and virt addresses for registers and fb */
179a1ee30a1Srkujawa 	aprint_normal_dev(sc->sc_dev,
180a1ee30a1Srkujawa 	    "registers at pa/va 0x%08x/0x%08x, fb at pa/va 0x%08x/0x%08x\n",
181a1ee30a1Srkujawa 	    (uint32_t) sc->sc_regpa,
182a1ee30a1Srkujawa 	    (uint32_t) bus_space_vaddr(sc->sc_iot, sc->sc_regh),
183a1ee30a1Srkujawa 	    (uint32_t) sc->sc_fbpa,
184a1ee30a1Srkujawa 	    (uint32_t) bus_space_vaddr(sc->sc_iot, sc->sc_fbh));
185a1ee30a1Srkujawa 
186a1ee30a1Srkujawa 	sc->sc_width = 1280;
187a1ee30a1Srkujawa 	sc->sc_height = 720;
188a1ee30a1Srkujawa 	sc->sc_bpp = 16;
189a1ee30a1Srkujawa 	sc->sc_linebytes = 4096;
190a1ee30a1Srkujawa 
191a1ee30a1Srkujawa 	aprint_normal_dev(sc->sc_dev, "%zu kB framebuffer memory present\n",
192a1ee30a1Srkujawa 	    sc->sc_memsize / 1024);
193a1ee30a1Srkujawa 
194a1ee30a1Srkujawa 	aprint_normal_dev(sc->sc_dev, "setting %dx%d %d bpp resolution\n",
195a1ee30a1Srkujawa 	    sc->sc_width, sc->sc_height, sc->sc_bpp);
196a1ee30a1Srkujawa 
197a1ee30a1Srkujawa 	mntva_mode_set(sc);
198a1ee30a1Srkujawa 
199a1ee30a1Srkujawa 	sc->sc_defaultscreen_descr = (struct wsscreen_descr) {
200a1ee30a1Srkujawa 	    "default", 0, 0, NULL, 8, 16,
201a1ee30a1Srkujawa 	    WSSCREEN_WSCOLORS | WSSCREEN_HILIT, NULL };
202a1ee30a1Srkujawa 	sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
203a1ee30a1Srkujawa 	sc->sc_screenlist = (struct wsscreen_list) { 1, sc->sc_screens };
204a1ee30a1Srkujawa 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
205a1ee30a1Srkujawa 
206a1ee30a1Srkujawa 	vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, &mntva_accessops);
207a1ee30a1Srkujawa 	sc->vd.init_screen = mntva_init_screen;
208a1ee30a1Srkujawa 
209a1ee30a1Srkujawa 	ri = &sc->sc_console_screen.scr_ri;
210a1ee30a1Srkujawa 
211a1ee30a1Srkujawa 	mntva_init_palette(sc);
212a1ee30a1Srkujawa 
213a1ee30a1Srkujawa 	if (sc->sc_isconsole) {
214a1ee30a1Srkujawa 		vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
215a1ee30a1Srkujawa 				&defattr);
216a1ee30a1Srkujawa 
217a1ee30a1Srkujawa 		sc->sc_console_screen.scr_flags = VCONS_SCREEN_IS_STATIC;
218a1ee30a1Srkujawa 		vcons_redraw_screen(&sc->sc_console_screen);
219a1ee30a1Srkujawa 
220a1ee30a1Srkujawa 		sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
221a1ee30a1Srkujawa 		sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
222a1ee30a1Srkujawa 		sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
223a1ee30a1Srkujawa 		sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
224a1ee30a1Srkujawa 
225a1ee30a1Srkujawa 		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
226a1ee30a1Srkujawa 		     defattr);
227a1ee30a1Srkujawa 		vcons_replay_msgbuf(&sc->sc_console_screen);
228a1ee30a1Srkujawa 	} else {
22966eee726Srkujawa 		if (sc->sc_console_screen.scr_ri.ri_rows == 0)
230a1ee30a1Srkujawa 			vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
231a1ee30a1Srkujawa 			    &defattr);
23266eee726Srkujawa 		else
233a1ee30a1Srkujawa 			(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
234a1ee30a1Srkujawa 	}
235a1ee30a1Srkujawa 
236a1ee30a1Srkujawa 	ws_aa.console = sc->sc_isconsole;
237a1ee30a1Srkujawa 	ws_aa.scrdata = &sc->sc_screenlist;
238a1ee30a1Srkujawa 	ws_aa.accessops = &mntva_accessops;
239a1ee30a1Srkujawa 	ws_aa.accesscookie = &sc->vd;
240a1ee30a1Srkujawa 
241*c7fb772bSthorpej 	config_found(sc->sc_dev, &ws_aa, wsemuldisplaydevprint, CFARGS_NONE);
242a1ee30a1Srkujawa }
243a1ee30a1Srkujawa 
244a1ee30a1Srkujawa static void
mntva_init_palette(struct mntva_softc * sc)245a1ee30a1Srkujawa mntva_init_palette(struct mntva_softc *sc)
246a1ee30a1Srkujawa {
247a1ee30a1Srkujawa 	int i, j;
248a1ee30a1Srkujawa 
249a1ee30a1Srkujawa 	j = 0;
250a1ee30a1Srkujawa 	for (i=0; i<256; i++) {
251a1ee30a1Srkujawa 		mntva_reg_write(sc, 0x200+i*2, rasops_cmap[j]);
252a1ee30a1Srkujawa 		mntva_reg_write(sc, 0x400+i*2, rasops_cmap[j+1]);
253a1ee30a1Srkujawa 		mntva_reg_write(sc, 0x600+i*2, rasops_cmap[j+2]);
254a1ee30a1Srkujawa 		j+=3;
255a1ee30a1Srkujawa 	}
256a1ee30a1Srkujawa }
257a1ee30a1Srkujawa 
258a1ee30a1Srkujawa static void
mntva_init_screen(void * cookie,struct vcons_screen * scr,int existing,long * defattr)259a1ee30a1Srkujawa mntva_init_screen(void *cookie, struct vcons_screen *scr, int existing,
260a1ee30a1Srkujawa     long *defattr)
261a1ee30a1Srkujawa {
262a1ee30a1Srkujawa 	struct mntva_softc *sc = cookie;
263a1ee30a1Srkujawa 	struct rasops_info *ri = &scr->scr_ri;
264a1ee30a1Srkujawa 
265a1ee30a1Srkujawa 	wsfont_init();
266a1ee30a1Srkujawa 
267a1ee30a1Srkujawa 	ri->ri_depth = sc->sc_bpp;
268a1ee30a1Srkujawa 	ri->ri_width = sc->sc_width;
269a1ee30a1Srkujawa 	ri->ri_height = sc->sc_height;
270a1ee30a1Srkujawa 	ri->ri_stride = sc->sc_linebytes;
271a1ee30a1Srkujawa 	ri->ri_flg = 0;
272a1ee30a1Srkujawa 
273a1ee30a1Srkujawa 	/*ri->ri_flg = RI_BSWAP;*/
274a1ee30a1Srkujawa 
275a1ee30a1Srkujawa 	ri->ri_bits = (char *) bus_space_vaddr(sc->sc_iot, sc->sc_fbh);
276a1ee30a1Srkujawa #ifdef MNTVA_DEBUG
277a1ee30a1Srkujawa 	aprint_normal_dev(sc->sc_dev, "ri_bits: %p\n", ri->ri_bits);
278a1ee30a1Srkujawa #endif /* MNTVA_DEBUG */
279a1ee30a1Srkujawa 
280a1ee30a1Srkujawa 	scr->scr_flags = VCONS_SCREEN_IS_STATIC;
281a1ee30a1Srkujawa 
282a1ee30a1Srkujawa 	rasops_init(ri, 0, 0);
283a1ee30a1Srkujawa 	ri->ri_caps = WSSCREEN_WSCOLORS;
284a1ee30a1Srkujawa 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
285a1ee30a1Srkujawa 	    sc->sc_width / ri->ri_font->fontwidth);
286a1ee30a1Srkujawa 
287a1ee30a1Srkujawa 	ri->ri_hw = scr;
288a1ee30a1Srkujawa 
289a1ee30a1Srkujawa 	ri->ri_ops.eraserows = mntva_eraserows;
290a1ee30a1Srkujawa 	ri->ri_ops.copyrows = mntva_copyrows;
291a1ee30a1Srkujawa 	ri->ri_ops.erasecols = mntva_erasecols;
292a1ee30a1Srkujawa 	ri->ri_ops.copycols = mntva_copycols;
293a1ee30a1Srkujawa #if 0
294a1ee30a1Srkujawa 	ri->ri_ops.cursor = mntva_cursor;
295a1ee30a1Srkujawa #endif
296a1ee30a1Srkujawa }
297a1ee30a1Srkujawa 
298a1ee30a1Srkujawa static bool
mntva_mode_set(struct mntva_softc * sc)299a1ee30a1Srkujawa mntva_mode_set(struct mntva_softc *sc)
300a1ee30a1Srkujawa {
30166eee726Srkujawa 	mntva_reg_write(sc, MNTVA_CAPTURE_MODE, 0);
30266eee726Srkujawa 
30366eee726Srkujawa 	mntva_reg_write(sc, MNTVA_H_SYNC_START, 1390);
30466eee726Srkujawa 	mntva_reg_write(sc, MNTVA_H_SYNC_END, 1430);
30566eee726Srkujawa 	mntva_reg_write(sc, MNTVA_H_MAX, 1650);
30666eee726Srkujawa 	mntva_reg_write(sc, MNTVA_V_SYNC_START, 725);
30766eee726Srkujawa 	mntva_reg_write(sc, MNTVA_V_SYNC_END, 730);
30866eee726Srkujawa 	mntva_reg_write(sc, MNTVA_V_MAX, 750);
30966eee726Srkujawa 	mntva_reg_write(sc, MNTVA_PIXEL_CLK_SEL, MNTVA_CLK_75MHZ);
31066eee726Srkujawa 
311a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_SCALEMODE, 0);
312a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_SCREENW, sc->sc_width);
313a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_SCREENH, sc->sc_height);
31466eee726Srkujawa 	mntva_reg_write(sc, MNTVA_ROW_PITCH, 2048);
31566eee726Srkujawa 	mntva_reg_write(sc, MNTVA_ROW_PITCH_SHIFT, 11);
31666eee726Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTER_ROW_PITCH, 2048);
31766eee726Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTER_ROW_PITCH_SHIFT, 11);
31866eee726Srkujawa 	mntva_reg_write(sc, MNTVA_MARGIN_X, 8);
31966eee726Srkujawa 	mntva_reg_write(sc, MNTVA_SAFE_X, 0x50);
320a1ee30a1Srkujawa 
321a1ee30a1Srkujawa 	if (sc->sc_bpp == 8)
322a1ee30a1Srkujawa 		mntva_reg_write(sc, MNTVA_COLORMODE, MNTVA_COLORMODE8);
323a1ee30a1Srkujawa 	else if (sc->sc_bpp == 16)
324a1ee30a1Srkujawa 		mntva_reg_write(sc, MNTVA_COLORMODE, MNTVA_COLORMODE16);
325a1ee30a1Srkujawa 	else if (sc->sc_bpp == 32)
326a1ee30a1Srkujawa 		mntva_reg_write(sc, MNTVA_COLORMODE, MNTVA_COLORMODE32);
327a1ee30a1Srkujawa 
328a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_PANPTRHI, 0);
329a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_PANPTRLO, 0);
330a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERBASEHI, 0);
331a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERBASELO, 0);
332a1ee30a1Srkujawa 
333a1ee30a1Srkujawa 	return true;
334a1ee30a1Srkujawa }
335a1ee30a1Srkujawa 
336a1ee30a1Srkujawa static uint16_t
mntva_reg_read(struct mntva_softc * sc,uint32_t reg)337a1ee30a1Srkujawa mntva_reg_read(struct mntva_softc *sc, uint32_t reg)
338a1ee30a1Srkujawa {
339a1ee30a1Srkujawa 	uint32_t rv;
340a1ee30a1Srkujawa 	rv = bus_space_read_2(sc->sc_iot, sc->sc_regh, reg);
341a1ee30a1Srkujawa 	return rv;
342a1ee30a1Srkujawa }
343a1ee30a1Srkujawa 
344a1ee30a1Srkujawa static void
mntva_reg_write(struct mntva_softc * sc,uint32_t reg,uint32_t val)345a1ee30a1Srkujawa mntva_reg_write(struct mntva_softc *sc, uint32_t reg, uint32_t val)
346a1ee30a1Srkujawa {
347a1ee30a1Srkujawa 	bus_space_write_2(sc->sc_iot, sc->sc_regh, reg, val);
348a1ee30a1Srkujawa }
349a1ee30a1Srkujawa 
350a1ee30a1Srkujawa static void
mntva_rectfill(struct mntva_softc * sc,int x,int y,int wi,int he,uint32_t color)351a1ee30a1Srkujawa mntva_rectfill(struct mntva_softc *sc, int x, int y, int wi, int he,
352a1ee30a1Srkujawa     uint32_t color)
353a1ee30a1Srkujawa {
354a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERRGB, (uint16_t) color);
355a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX1, (uint16_t) x);
356a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY1, (uint16_t) y);
357a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX2, (uint16_t) x + wi - 1);
358a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY2, (uint16_t) y + he - 1);
359a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTER_ENABLE, MNTVA_BLITTER_FILL);
360a1ee30a1Srkujawa 
361a1ee30a1Srkujawa 	while(mntva_reg_read(sc, MNTVA_BLITTER_ENABLE)) {
362a1ee30a1Srkujawa 		/* busy wait */
363a1ee30a1Srkujawa 	}
364a1ee30a1Srkujawa }
365a1ee30a1Srkujawa 
366a1ee30a1Srkujawa static void
mntva_bitblt(struct mntva_softc * sc,int xs,int ys,int xd,int yd,int wi,int he)367a1ee30a1Srkujawa mntva_bitblt(struct mntva_softc *sc, int xs, int ys, int xd, int yd, int wi,
368a1ee30a1Srkujawa     int he)
369a1ee30a1Srkujawa {
370a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX1, (uint16_t) xd);
371a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY1, (uint16_t) yd);
372a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX2, (uint16_t) xd + wi - 1);
373a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY2, (uint16_t) yd + he - 1);
374a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX3, (uint16_t) xs);
375a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY3, (uint16_t) ys);
376a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERX4, (uint16_t) xs + wi - 1);
377a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTERY4, (uint16_t) ys + he - 1);
378a1ee30a1Srkujawa 	mntva_reg_write(sc, MNTVA_BLITTER_ENABLE, MNTVA_BLITTER_COPY);
379a1ee30a1Srkujawa 
380a1ee30a1Srkujawa 	while(mntva_reg_read(sc, MNTVA_BLITTER_ENABLE)) {
381a1ee30a1Srkujawa 		/* busy wait */
382a1ee30a1Srkujawa 	}
383a1ee30a1Srkujawa }
384a1ee30a1Srkujawa 
385a1ee30a1Srkujawa static void
mntva_copyrows(void * cookie,int srcrow,int dstrow,int nrows)386a1ee30a1Srkujawa mntva_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
387a1ee30a1Srkujawa {
388a1ee30a1Srkujawa 	struct mntva_softc *sc;
389a1ee30a1Srkujawa 	struct rasops_info *ri;
390a1ee30a1Srkujawa 	struct vcons_screen *scr;
391a1ee30a1Srkujawa 	int x, ys, yd, wi, he;
392a1ee30a1Srkujawa 
393a1ee30a1Srkujawa 	ri = cookie;
394a1ee30a1Srkujawa 	scr = ri->ri_hw;
395a1ee30a1Srkujawa 	sc = scr->scr_cookie;
396a1ee30a1Srkujawa 
397a1ee30a1Srkujawa 	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
398a1ee30a1Srkujawa 		x = ri->ri_xorigin;
399a1ee30a1Srkujawa 		ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
400a1ee30a1Srkujawa 		yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
401a1ee30a1Srkujawa 		wi = ri->ri_emuwidth;
402a1ee30a1Srkujawa 		he = ri->ri_font->fontheight * nrows;
403a1ee30a1Srkujawa 		mntva_bitblt(sc, x, ys, x, yd, wi, he);
404a1ee30a1Srkujawa 	}
405a1ee30a1Srkujawa }
406a1ee30a1Srkujawa 
407a1ee30a1Srkujawa static void
mntva_eraserows(void * cookie,int row,int nrows,long fillattr)408a1ee30a1Srkujawa mntva_eraserows(void *cookie, int row, int nrows, long fillattr)
409a1ee30a1Srkujawa {
410a1ee30a1Srkujawa 	struct mntva_softc *sc;
411a1ee30a1Srkujawa 	struct rasops_info *ri;
412a1ee30a1Srkujawa 	struct vcons_screen *scr;
413a1ee30a1Srkujawa 	int x, y, wi, he, fg, bg, ul;
414a1ee30a1Srkujawa 
415a1ee30a1Srkujawa 	ri = cookie;
416a1ee30a1Srkujawa 	scr = ri->ri_hw;
417a1ee30a1Srkujawa 	sc = scr->scr_cookie;
418a1ee30a1Srkujawa 
419a1ee30a1Srkujawa 	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
420a1ee30a1Srkujawa 		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
421a1ee30a1Srkujawa 		if ((row == 0) && (nrows == ri->ri_rows))
422a1ee30a1Srkujawa 			mntva_rectfill(sc, 0, 0, ri->ri_width,
423a1ee30a1Srkujawa 			    ri->ri_height, ri->ri_devcmap[bg]);
424a1ee30a1Srkujawa 		else {
425a1ee30a1Srkujawa 			x = ri->ri_xorigin;
426a1ee30a1Srkujawa 			y = ri->ri_yorigin + ri->ri_font->fontheight * row;
427a1ee30a1Srkujawa 			wi = ri->ri_emuwidth;
428a1ee30a1Srkujawa 			he = ri->ri_font->fontheight * nrows;
429a1ee30a1Srkujawa 			mntva_rectfill(sc, x, y, wi, he, ri->ri_devcmap[bg]);
430a1ee30a1Srkujawa 		}
431a1ee30a1Srkujawa 	}
432a1ee30a1Srkujawa }
433a1ee30a1Srkujawa 
434a1ee30a1Srkujawa static void
mntva_copycols(void * cookie,int row,int srccol,int dstcol,int ncols)435a1ee30a1Srkujawa mntva_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
436a1ee30a1Srkujawa {
437a1ee30a1Srkujawa 	struct mntva_softc *sc;
438a1ee30a1Srkujawa 	struct rasops_info *ri;
439a1ee30a1Srkujawa 	struct vcons_screen *scr;
440a1ee30a1Srkujawa 	int xs, xd, y, w, h;
441a1ee30a1Srkujawa 
442a1ee30a1Srkujawa 	ri = cookie;
443a1ee30a1Srkujawa 	scr = ri->ri_hw;
444a1ee30a1Srkujawa 	sc = scr->scr_cookie;
445a1ee30a1Srkujawa 
446a1ee30a1Srkujawa 	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
447a1ee30a1Srkujawa 		xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
448a1ee30a1Srkujawa 		xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
449a1ee30a1Srkujawa 		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
450a1ee30a1Srkujawa 		w = ri->ri_font->fontwidth * ncols;
451a1ee30a1Srkujawa 		h = ri->ri_font->fontheight;
452a1ee30a1Srkujawa 		mntva_bitblt(sc, xs, y, xd, y, w, h);
453a1ee30a1Srkujawa 	}
454a1ee30a1Srkujawa 
455a1ee30a1Srkujawa }
456a1ee30a1Srkujawa 
457a1ee30a1Srkujawa static void
mntva_erasecols(void * cookie,int row,int startcol,int ncols,long fillattr)458a1ee30a1Srkujawa mntva_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
459a1ee30a1Srkujawa {
460a1ee30a1Srkujawa 	struct mntva_softc *sc;
461a1ee30a1Srkujawa 	struct rasops_info *ri;
462a1ee30a1Srkujawa 	struct vcons_screen *scr;
463a1ee30a1Srkujawa 	int x, y, w, h, fg, bg, ul;
464a1ee30a1Srkujawa 
465a1ee30a1Srkujawa 	ri = cookie;
466a1ee30a1Srkujawa 	scr = ri->ri_hw;
467a1ee30a1Srkujawa 	sc = scr->scr_cookie;
468a1ee30a1Srkujawa 
469a1ee30a1Srkujawa 	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
470a1ee30a1Srkujawa 		x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
471a1ee30a1Srkujawa 		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
472a1ee30a1Srkujawa 		w = ri->ri_font->fontwidth * ncols;
473a1ee30a1Srkujawa 		h = ri->ri_font->fontheight;
474a1ee30a1Srkujawa 		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
475a1ee30a1Srkujawa 		mntva_rectfill(sc, x, y, w, h, ri->ri_devcmap[bg & 0xf]);
476a1ee30a1Srkujawa 	}
477a1ee30a1Srkujawa }
478a1ee30a1Srkujawa 
479a1ee30a1Srkujawa static int
mntva_ioctl(void * v,void * vs,u_long cmd,void * data,int flag,struct lwp * l)480a1ee30a1Srkujawa mntva_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
481a1ee30a1Srkujawa {
482a1ee30a1Srkujawa 	struct vcons_data *vd;
483a1ee30a1Srkujawa 	struct mntva_softc *sc;
484a1ee30a1Srkujawa 	struct wsdisplay_fbinfo *wsfbi;
485a1ee30a1Srkujawa 	struct vcons_screen *ms;
486a1ee30a1Srkujawa 	struct wsdisplayio_bus_id *busid;
487a1ee30a1Srkujawa 
488a1ee30a1Srkujawa 	vd = v;
489a1ee30a1Srkujawa 	sc = vd->cookie;
490a1ee30a1Srkujawa 	ms = vd->active;
491a1ee30a1Srkujawa 
492a1ee30a1Srkujawa 	switch (cmd) {
493a1ee30a1Srkujawa 	case WSDISPLAYIO_GTYPE:
494a1ee30a1Srkujawa 		*(u_int *) data = WSDISPLAY_TYPE_UNKNOWN;
495a1ee30a1Srkujawa 		return 0;
496a1ee30a1Srkujawa 
497a1ee30a1Srkujawa 	case WSDISPLAYIO_GET_BUSID:
498a1ee30a1Srkujawa 		busid = data;
499a1ee30a1Srkujawa 		busid->bus_type = WSDISPLAYIO_BUS_SOC;
500a1ee30a1Srkujawa 		return 0;
501a1ee30a1Srkujawa 
502a1ee30a1Srkujawa 	case WSDISPLAYIO_GINFO:
503a1ee30a1Srkujawa 		if (ms == NULL)
504a1ee30a1Srkujawa 			return ENODEV;
505a1ee30a1Srkujawa 
506a1ee30a1Srkujawa 		wsfbi = (void *) data;
507a1ee30a1Srkujawa 		wsfbi->height = ms->scr_ri.ri_height;
508a1ee30a1Srkujawa 		wsfbi->width = ms->scr_ri.ri_width;
509a1ee30a1Srkujawa 		wsfbi->depth = ms->scr_ri.ri_depth;
510a1ee30a1Srkujawa 		wsfbi->cmsize = 256;
511a1ee30a1Srkujawa 		return 0;
512a1ee30a1Srkujawa 
513a1ee30a1Srkujawa 	case WSDISPLAYIO_LINEBYTES:
514a1ee30a1Srkujawa 		*(u_int *) data = sc->sc_linebytes;
515a1ee30a1Srkujawa 		return 0;
516a1ee30a1Srkujawa 
517a1ee30a1Srkujawa 	case WSDISPLAYIO_SMODE:
518a1ee30a1Srkujawa 		{
519a1ee30a1Srkujawa 			int new_mode = *(int *) data;
520a1ee30a1Srkujawa 			if (new_mode != sc->sc_mode) {
521a1ee30a1Srkujawa 				sc->sc_mode = new_mode;
522a1ee30a1Srkujawa 				if (new_mode == WSDISPLAYIO_MODE_EMUL)
523a1ee30a1Srkujawa 					vcons_redraw_screen(ms);
524a1ee30a1Srkujawa 			}
525a1ee30a1Srkujawa 			return 0;
526a1ee30a1Srkujawa 		}
527a1ee30a1Srkujawa 	case WSDISPLAYIO_GET_FBINFO:
528a1ee30a1Srkujawa 		{
529a1ee30a1Srkujawa 			struct wsdisplayio_fbinfo *fbi = data;
530a1ee30a1Srkujawa 			struct rasops_info *ri;
531a1ee30a1Srkujawa 			int ret;
532a1ee30a1Srkujawa 
533a1ee30a1Srkujawa 			ri = &sc->vd.active->scr_ri;
534a1ee30a1Srkujawa 			ret = wsdisplayio_get_fbinfo(ri, fbi);
535a1ee30a1Srkujawa 			return ret;
536a1ee30a1Srkujawa 		}
537a1ee30a1Srkujawa 	}
538a1ee30a1Srkujawa 
539a1ee30a1Srkujawa 	return EPASSTHROUGH;
540a1ee30a1Srkujawa }
541a1ee30a1Srkujawa 
542a1ee30a1Srkujawa #if 0
543a1ee30a1Srkujawa static void
544a1ee30a1Srkujawa mntva_cursor(void *cookie, int on, int row, int col)
545a1ee30a1Srkujawa {
546a1ee30a1Srkujawa 	struct mntva_softc *sc;
547a1ee30a1Srkujawa 	struct rasops_info *ri;
548a1ee30a1Srkujawa 	struct vcons_screen *scr;
549a1ee30a1Srkujawa 	int x, y, wi, he;
550a1ee30a1Srkujawa 
551a1ee30a1Srkujawa 	ri = cookie;
552a1ee30a1Srkujawa 	scr = ri->ri_hw;
553a1ee30a1Srkujawa 	sc = scr->scr_cookie;
554a1ee30a1Srkujawa 
555a1ee30a1Srkujawa 	wi = ri->ri_font->fontwidth;
556a1ee30a1Srkujawa 	he = ri->ri_font->fontheight;
557a1ee30a1Srkujawa 
558a1ee30a1Srkujawa 	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
559a1ee30a1Srkujawa 		x = ri->ri_ccol * wi + ri->ri_xorigin;
560a1ee30a1Srkujawa 		y = ri->ri_crow * he + ri->ri_yorigin;
561a1ee30a1Srkujawa 		if (ri->ri_flg & RI_CURSOR) {
562a1ee30a1Srkujawa 			mntva_bitblt(sc, x, y, x, y, wi, he);
563a1ee30a1Srkujawa 			ri->ri_flg &= ~RI_CURSOR;
564a1ee30a1Srkujawa 		}
565a1ee30a1Srkujawa 		ri->ri_crow = row;
566a1ee30a1Srkujawa 		ri->ri_ccol = col;
567a1ee30a1Srkujawa 		if (on) {
568a1ee30a1Srkujawa 			x = ri->ri_ccol * wi + ri->ri_xorigin;
569a1ee30a1Srkujawa 			y = ri->ri_crow * he + ri->ri_yorigin;
570a1ee30a1Srkujawa 			mntva_bitblt(sc, x, y, x, y, wi, he);
571a1ee30a1Srkujawa 			ri->ri_flg |= RI_CURSOR;
572a1ee30a1Srkujawa 		}
573a1ee30a1Srkujawa 	} else {
574a1ee30a1Srkujawa 		scr->scr_ri.ri_crow = row;
575a1ee30a1Srkujawa 		scr->scr_ri.ri_ccol = col;
576a1ee30a1Srkujawa 		scr->scr_ri.ri_flg &= ~RI_CURSOR;
577a1ee30a1Srkujawa 	}
578a1ee30a1Srkujawa }
579a1ee30a1Srkujawa #endif
580a1ee30a1Srkujawa 
581a1ee30a1Srkujawa static paddr_t
mntva_mmap(void * v,void * vs,off_t offset,int prot)582a1ee30a1Srkujawa mntva_mmap(void *v, void *vs, off_t offset, int prot)
583a1ee30a1Srkujawa {
584a1ee30a1Srkujawa 	struct vcons_data *vd;
585a1ee30a1Srkujawa 	struct mntva_softc *sc;
586a1ee30a1Srkujawa 	paddr_t pa;
587a1ee30a1Srkujawa 
588a1ee30a1Srkujawa 	vd = v;
589a1ee30a1Srkujawa 	sc = vd->cookie;
590a1ee30a1Srkujawa 
591a1ee30a1Srkujawa 	if (offset >= 0 && offset < sc->sc_memsize) {
592a1ee30a1Srkujawa 		pa = bus_space_mmap(sc->sc_iot, sc->sc_fbpa, offset, prot,
593a1ee30a1Srkujawa 		     BUS_SPACE_MAP_LINEAR);
594a1ee30a1Srkujawa 		return pa;
595a1ee30a1Srkujawa 	}
596a1ee30a1Srkujawa 
597a1ee30a1Srkujawa 	return -1;
598a1ee30a1Srkujawa }
599a1ee30a1Srkujawa 
600a1ee30a1Srkujawa void
mntvacninit(struct consdev * cd)601a1ee30a1Srkujawa mntvacninit(struct consdev *cd)
602a1ee30a1Srkujawa {
603a1ee30a1Srkujawa 	/*wsdisplay_preattach(sc->sc_defaultscreen, ri, 0, 0, defattr);*/
604a1ee30a1Srkujawa }
605a1ee30a1Srkujawa 
606a1ee30a1Srkujawa void
mntvacnprobe(struct consdev * cd)607a1ee30a1Srkujawa mntvacnprobe(struct consdev *cd)
608a1ee30a1Srkujawa {
609a985706bSphx #ifdef MNTVA_CONSOLE
610a1ee30a1Srkujawa 	/*
611a1ee30a1Srkujawa 	 * This isn't exactly true, but cons.h does not define anything
612a1ee30a1Srkujawa 	 * that would fit our case exactly.
613a1ee30a1Srkujawa 	 */
614a1ee30a1Srkujawa 	cd->cn_pri = CN_INTERNAL;
615a1ee30a1Srkujawa 
616a1ee30a1Srkujawa 	cd->cn_dev = NODEV; /* Filled later by wscons. */
617a985706bSphx #endif /* MNTVA_CONSOLE */
618a1ee30a1Srkujawa }
619a1ee30a1Srkujawa 
620a1ee30a1Srkujawa /* ARGSUSED */
621a1ee30a1Srkujawa void
mntvacnputc(dev_t cd,int ch)622a1ee30a1Srkujawa mntvacnputc(dev_t cd, int ch)
623a1ee30a1Srkujawa {
624a1ee30a1Srkujawa }
625a1ee30a1Srkujawa 
626a1ee30a1Srkujawa /* ARGSUSED */
627a1ee30a1Srkujawa int
mntvacngetc(dev_t cd)628a1ee30a1Srkujawa mntvacngetc(dev_t cd)
629a1ee30a1Srkujawa {
630a1ee30a1Srkujawa 	return(0);
631a1ee30a1Srkujawa }
632a1ee30a1Srkujawa 
633a1ee30a1Srkujawa /* ARGSUSED */
634a1ee30a1Srkujawa void
mntvacnpollc(dev_t cd,int on)635a1ee30a1Srkujawa mntvacnpollc(dev_t cd, int on)
636a1ee30a1Srkujawa {
637a1ee30a1Srkujawa }
638a1ee30a1Srkujawa 
639