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