Home | History | Annotate | Line # | Download | only in pci
      1 /*	$NetBSD: veritefb.c,v 1.2 2026/07/15 20:53:22 rkujawa Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2026 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Radoslaw Kujawa.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 /*
     32  * Rendition Verite V2100/V2200 driver.
     33  *
     34  * Influenced by xf86-video-rendition.
     35  *
     36  * The on-board RISC boots from the card ROM at PCI reset and parks in
     37  * a loop. We reset it and hold before any other access to the card.
     38  * The console runs unaccelerated from autoconf on until 2D microcode is
     39  * loaded.
     40  */
     41 
     42 #include <sys/cdefs.h>
     43 __KERNEL_RCSID(0, "$NetBSD: veritefb.c,v 1.2 2026/07/15 20:53:22 rkujawa Exp $");
     44 
     45 #include <sys/param.h>
     46 #include <sys/systm.h>
     47 #include <sys/kernel.h>
     48 #ifdef VERITEFB_DEBUG
     49 #include <sys/callout.h>
     50 #endif
     51 #include <sys/kmem.h>
     52 #include <sys/device.h>
     53 #include <sys/endian.h>
     54 #include <sys/conf.h>
     55 #include <sys/extent.h>
     56 
     57 #include <sys/exec_elf.h>
     58 
     59 #include <dev/firmload.h>
     60 
     61 #include <dev/pci/pcivar.h>
     62 #include <dev/pci/pcireg.h>
     63 #include <dev/pci/pcidevs.h>
     64 #include <dev/pci/pciio.h>
     65 
     66 #include <dev/pci/veritefbreg.h>
     67 #include <dev/pci/veritefb_ucode.h>
     68 #include <dev/pci/veritefbio.h>
     69 #include <dev/pci/verite3dio.h>
     70 
     71 #include <dev/wscons/wsdisplayvar.h>
     72 #include <dev/wscons/wsconsio.h>
     73 #include <dev/wsfont/wsfont.h>
     74 #include <dev/rasops/rasops.h>
     75 #include <dev/wscons/wsdisplay_vconsvar.h>
     76 #include <dev/wscons/wsdisplay_glyphcachevar.h>
     77 #include <dev/pci/wsdisplay_pci.h>
     78 
     79 #include "opt_wsemul.h"
     80 #include "opt_veritefb.h"
     81 #include "opt_ddb.h"
     82 
     83 #include <dev/videomode/videomode.h>
     84 #include <dev/videomode/edidvar.h>
     85 
     86 #include <dev/i2c/i2cvar.h>
     87 #include <dev/i2c/i2c_bitbang.h>
     88 #include <dev/i2c/ddcvar.h>
     89 
     90 #include <ddb/db_active.h>
     91 #ifdef DDB
     92 #include <machine/db_machdep.h>
     93 #include <ddb/db_command.h>
     94 #include <ddb/db_output.h>
     95 #endif
     96 
     97 #define VFB_MAXPOLL	100000	/* status/hold polls */
     98 #define VFB_VSYNCPOLL	40000	/* vsync wait, ~2 frames in us */
     99 #define VFB_SHORTPOLL	100	/* polls in the RISC debug port */
    100 #define VFB_FIFOPOLL	100000	/* FIFO waits, us */
    101 #define VFB_DRAINPOLL	10000	/* output FIFO drains */
    102 #define VFB_LAZY_LIMIT	16	/* queued ops between forced syncs */
    103 
    104 #define VFB_LAZY_AREA	307200	/* fill at the engine's pixel rate */
    105 
    106 #define VFB_PROBE_PATTERN	0xf5faaf5fU
    107 #define VFB_PROBE_START		0x12345678U
    108 #define VFB_MAXVRAM		(16 * 1024 * 1024)
    109 #define VFB_MAXUCODE		(1024 * 1024)	/* sanity cap for firmware */
    110 
    111 #define VFB_PLL_REF		1431818	/* 14.31818 MHz in units of 10 Hz */
    112 
    113 #define VFB_FIRMWARE_NAME	"v20002d.uc"
    114 
    115 #define VFB_GC_GAP		5	/* scanlines between fb and glyph cache */
    116 #define VFB_UNDERLINE_OFF	2	/* underline offset from cell bottom */
    117 #define VFB_GETPIXEL_PATTERN	0x5a5a5a5aU /* handshake test pixels */
    118 #define VFB_CMD_BOGUS		50	/* unassigned cmd for fault injection */
    119 
    120 #define VFB_ACCEL_OFF	0	/* no microcode loaded */
    121 #define VFB_ACCEL_SW	1	/* degraded after a fault; never retried */
    122 #define VFB_ACCEL_ON	2	/* RISC running, handshake passed */
    123 
    124 #define VFB_OWNER_CONSOLE	VERITEFB_OWNER_CONSOLE
    125 #define VFB_OWNER_PARKED	VERITEFB_OWNER_PARKED
    126 #define VFB_OWNER_FOREIGN	VERITEFB_OWNER_FOREIGN
    127 
    128 struct veritefb_softc {
    129 	device_t		sc_dev;
    130 	pci_chipset_tag_t	sc_pc;
    131 	pcitag_t		sc_pcitag;
    132 
    133 	bus_space_tag_t		sc_iot;		/* I/O registers (BAR1) */
    134 	bus_space_handle_t	sc_ioh;
    135 	bus_addr_t		sc_io_paddr;
    136 	bus_size_t		sc_ios;
    137 	bus_space_tag_t		sc_mmiot;	/* MMIO registers (BAR2) */
    138 	bus_space_handle_t	sc_mmioh;
    139 	bus_addr_t		sc_mmio_paddr;
    140 	bus_size_t		sc_mmios;
    141 
    142 	bus_space_tag_t		sc_regt;
    143 	bus_space_handle_t	sc_regh;
    144 	bus_size_t		sc_regoff;
    145 	bus_space_tag_t		sc_memt;	/* fb aperture (BAR0) */
    146 	bus_space_handle_t	sc_memh;
    147 	bus_addr_t		sc_fb_paddr;
    148 	bus_size_t		sc_apsize;	/* mapped aperture size */
    149 	bus_size_t		sc_memsize;	/* probed VRAM size */
    150 	bus_size_t		sc_fb_offset;	/* fb start (microcode area) */
    151 
    152 	/* RISC / acceleration state */
    153 	int			sc_accel;	/* VFB_ACCEL_* */
    154 	int			sc_risc_owner;	/* VFB_OWNER_* */
    155 	int			sc_unsynced;	/* ops queued since last sync */
    156 	uint32_t		sc_unsynced_area; /* pixels queued likewise */
    157 	uint32_t		sc_ucode_entry;
    158 	uint8_t			*sc_ucode;	/* firmware image copy */
    159 	size_t			sc_ucode_size;
    160 
    161 	glyphcache		sc_gc;		/* VRAM glyph cache */
    162 	bool			sc_gc_initted;
    163 	/* bus-master FIFO feed (descriptor list page + bounce buffer) */
    164 #define VFB_DMA_BOUNCE		65536
    165 #define VFB_DMA_TIMEOUT_US	200000
    166 	bus_dma_tag_t		sc_dmat;
    167 	bus_dmamap_t		sc_dma_list_map;
    168 	bus_dmamap_t		sc_dma_buf_map;
    169 	bus_dma_segment_t	sc_dma_list_seg;
    170 	bus_dma_segment_t	sc_dma_buf_seg;
    171 	uint32_t		*sc_dma_list;	/* data entry + stop entry */
    172 	uint8_t			*sc_dma_buf;
    173 	/*
    174 	 * Async submit
    175 	 */
    176 	bool			sc_dma_pending;
    177 	bus_dmamap_t		sc_dma_pending_map; /* owed POSTWRITE */
    178 	uint32_t		sc_dma_pending_len;
    179 
    180 	/*
    181 	 * Vblank-queued flip
    182 	 */
    183 	void			*sc_ih;
    184 	bool			sc_flip_intr_ok;
    185 	volatile bool		sc_flip_pending;
    186 	volatile uint32_t	sc_flip_base;
    187 
    188 	/* /dev/verite3d: exclusive 3D client state */
    189 	bool			sc_v3d_open;
    190 	bool			sc_v3d_dead;	/* EIO until close */
    191 	bool			sc_v3d_inited;	/* client ucode running */
    192 	struct extent		*sc_v3d_ext;	/* VRAM pool */
    193 	uint32_t		sc_v3d_pool_base;
    194 #define V3D_MAX_REGIONS	1024
    195 	struct {
    196 		uint32_t	addr;
    197 		uint32_t	size;
    198 	}			*sc_v3d_reg;	/* live allocations */
    199 	int			sc_v3d_nreg;
    200 	bus_dmamap_t		sc_v3d_slot_map[V3D_RING_SLOTS];
    201 	bus_dma_segment_t	sc_v3d_slot_seg[V3D_RING_SLOTS];
    202 	uint8_t			*sc_v3d_slot[V3D_RING_SLOTS];
    203 
    204 #ifdef VERITEFB_DEBUG
    205 	/* last words written to the input FIFO */
    206 #define VFB_RING_SIZE	128		/* power of two */
    207 	uint32_t		sc_ring[VFB_RING_SIZE];
    208 	unsigned		sc_ring_count;
    209 	struct veritefb_dbg_stats sc_stats;
    210 
    211 	/* RISC PC sampling profiler (veritefb_pcsample_tick) */
    212 	struct callout		sc_pcsample_ch;
    213 	bool			sc_pcsample_on;
    214 	uint32_t		sc_pcsample_hz;
    215 	uint32_t		sc_pchist_base;
    216 	uint32_t		sc_pchist_shift;
    217 	uint32_t		sc_pchist_min;
    218 	uint32_t		sc_pchist_max;
    219 	uint64_t		sc_pchist_samples;
    220 	uint64_t		sc_pchist_missed;
    221 	uint32_t		sc_pchist[VFB_PCHIST_BUCKETS];
    222 #endif
    223 
    224 	/* software rendering ops, the permanent fallback */
    225 	void (*sc_orig_eraserows)(void *, int, int, long);
    226 	void (*sc_orig_erasecols)(void *, int, int, int, long);
    227 	void (*sc_orig_copyrows)(void *, int, int, int);
    228 	void (*sc_orig_copycols)(void *, int, int, int, int);
    229 	void (*sc_orig_putchar)(void *, int, int, u_int, long);
    230 
    231 	int			sc_width;
    232 	int			sc_height;
    233 	int			sc_depth;
    234 	int			sc_linebytes;
    235 	uint8_t			sc_stride0;	/* pixel engine stride */
    236 	uint8_t			sc_stride1;
    237 	const struct videomode	*sc_videomode;	/* the mode in use */
    238 
    239 	/* DDC/EDID */
    240 	struct i2c_controller	sc_i2c;
    241 	uint32_t		sc_ddc_base;	/* CRTCCTL sans DDC bits */
    242 	uint8_t			sc_edid[128];
    243 	struct edid_info	sc_ei;
    244 	bool			sc_edid_valid;
    245 
    246 	int			sc_mode;	/* WSDISPLAYIO_MODE_* */
    247 	struct vcons_data	vd;
    248 	struct vcons_screen	sc_console_screen;
    249 	struct wsscreen_descr	sc_defaultscreen_descr;
    250 	const struct wsscreen_descr *sc_screens[1];
    251 	struct wsscreen_list	sc_screenlist;
    252 	u_char			sc_cmap_red[256];
    253 	u_char			sc_cmap_green[256];
    254 	u_char			sc_cmap_blue[256];
    255 };
    256 
    257 static const struct veritefb_stride {
    258 	uint16_t linebytes;
    259 	uint8_t stride0, stride1;
    260 } veritefb_stride_table[] = {
    261 	{  640, 2, 4 },
    262 	{  704, 6, 4 },
    263 	{  768, 5, 0 },
    264 	{  784, 5, 1 },
    265 	{  800, 5, 2 },
    266 	{  832, 5, 3 },
    267 	{  896, 5, 4 },
    268 	{ 1024, 3, 0 },
    269 	{ 1040, 3, 1 },
    270 	{ 1056, 3, 2 },
    271 	{ 1088, 3, 3 },
    272 	{ 1152, 3, 4 },
    273 	{ 1168, 7, 1 },
    274 	{ 1184, 7, 2 },
    275 	{ 1216, 7, 3 },
    276 	{ 1280, 1, 5 },
    277 	{ 1536, 2, 5 },
    278 	{ 1600, 6, 5 },
    279 	{ 1792, 5, 5 },
    280 	{ 2048, 0, 6 },
    281 	{ 0, 0, 0 }
    282 };
    283 
    284 static int	veritefb_match(device_t, cfdata_t, void *);
    285 static void	veritefb_attach(device_t, device_t, void *);
    286 
    287 static void	veritefb_risc_softreset(struct veritefb_softc *);
    288 static void	veritefb_risc_hold(struct veritefb_softc *);
    289 static void	veritefb_risc_continue(struct veritefb_softc *);
    290 static void	veritefb_risc_forcestep(struct veritefb_softc *, uint32_t);
    291 static void	veritefb_risc_writerf(struct veritefb_softc *, uint8_t,
    292 		    uint32_t);
    293 static uint32_t	veritefb_risc_readrf(struct veritefb_softc *, uint8_t);
    294 static uint32_t	veritefb_risc_readmem(struct veritefb_softc *, uint32_t);
    295 static void	veritefb_risc_writemem(struct veritefb_softc *, uint32_t,
    296 		    uint32_t);
    297 static void	veritefb_risc_flushicache(struct veritefb_softc *);
    298 static void	veritefb_risc_start(struct veritefb_softc *, uint32_t);
    299 
    300 static uint32_t	veritefb_risc_samplepc(struct veritefb_softc *);
    301 #ifdef VERITEFB_DEBUG
    302 static void	veritefb_pcsample_tick(void *);
    303 #endif
    304 static void	veritefb_accel_fail(struct veritefb_softc *, const char *);
    305 static int	veritefb_waitfifo(struct veritefb_softc *, int);
    306 static int	veritefb_drain_outfifo(struct veritefb_softc *);
    307 static int	veritefb_read_outfifo(struct veritefb_softc *, uint32_t *);
    308 static void	veritefb_load_firmware(device_t);
    309 static bool	veritefb_ucode_load(struct veritefb_softc *, const uint8_t *,
    310 		    size_t, uint32_t, uint32_t, bool, uint32_t *);
    311 static bool	veritefb_2d_handshake(struct veritefb_softc *);
    312 static int	veritefb_waitfifo_raw(struct veritefb_softc *, int, uint32_t);
    313 static int	veritefb_read_outfifo_raw(struct veritefb_softc *, uint32_t *,
    314 		    uint32_t);
    315 static int	veritefb_suspend2d(struct veritefb_softc *);
    316 static int	veritefb_resume2d(struct veritefb_softc *);
    317 static void	veritefb_mux_redraw(struct veritefb_softc *);
    318 static int	veritefb_set_scan_depth(struct veritefb_softc *, int);
    319 static int	veritefb_dma_alloc(struct veritefb_softc *);
    320 static int	veritefb_dma_drain(struct veritefb_softc *);
    321 static int	veritefb_intr(void *);
    322 static void	veritefb_flip_cancel(struct veritefb_softc *);
    323 static void	veritefb_flip_wait(struct veritefb_softc *);
    324 static int	veritefb_dma_submit(struct veritefb_softc *, bus_dmamap_t,
    325 		    uint32_t, uint32_t);
    326 
    327 dev_type_open(verite3d_open);
    328 dev_type_close(verite3d_close);
    329 dev_type_ioctl(verite3d_ioctl);
    330 dev_type_mmap(verite3d_mmap);
    331 static void	verite3d_teardown(struct veritefb_softc *);
    332 static int	verite3d_ring_alloc(struct veritefb_softc *);
    333 static bool	veritefb_risc_init(struct veritefb_softc *);
    334 static size_t	veritefb_mem_size(struct veritefb_softc *);
    335 
    336 static bool	veritefb_calc_pclk(int, int *, int *, int *);
    337 static const struct veritefb_stride *veritefb_stride_for(int);
    338 static bool	veritefb_set_mode(struct veritefb_softc *,
    339 		    const struct videomode *);
    340 
    341 static void	veritefb_i2cbb_set_bits(void *, uint32_t);
    342 static void	veritefb_i2cbb_set_dir(void *, uint32_t);
    343 static uint32_t	veritefb_i2cbb_read_bits(void *);
    344 static int	veritefb_i2c_send_start(void *, int);
    345 static int	veritefb_i2c_send_stop(void *, int);
    346 static int	veritefb_i2c_initiate_xfer(void *, i2c_addr_t, int);
    347 static int	veritefb_i2c_read_byte(void *, uint8_t *, int);
    348 static int	veritefb_i2c_write_byte(void *, uint8_t, int);
    349 static void	veritefb_ddc_read(struct veritefb_softc *);
    350 static void	veritefb_pick_mode(struct veritefb_softc *);
    351 static void	veritefb_init_dac(struct veritefb_softc *);
    352 static void	veritefb_wait_vsync(struct veritefb_softc *);
    353 static void	veritefb_set_dac_entry(struct veritefb_softc *, int, uint8_t,
    354 		    uint8_t, uint8_t);
    355 static void	veritefb_init_palette(struct veritefb_softc *);
    356 static int	veritefb_getcmap(struct veritefb_softc *,
    357 		    struct wsdisplay_cmap *);
    358 static int	veritefb_putcmap(struct veritefb_softc *,
    359 		    struct wsdisplay_cmap *);
    360 
    361 static void	veritefb_init_screen(void *, struct vcons_screen *, int,
    362 		    long *);
    363 static paddr_t	veritefb_mmap(void *, void *, off_t, int);
    364 static int	veritefb_ioctl(void *, void *, u_long, void *, int,
    365 		    struct lwp *);
    366 
    367 static void	veritefb_sync(struct veritefb_softc *);
    368 static bool	veritefb_rectfill(struct veritefb_softc *, int, int, int,
    369 		    int, uint32_t);
    370 static bool	veritefb_bitblt(struct veritefb_softc *, int, int, int, int,
    371 		    int, int);
    372 static void	veritefb_eraserows(void *, int, int, long);
    373 static void	veritefb_erasecols(void *, int, int, int, long);
    374 static void	veritefb_copyrows(void *, int, int, int);
    375 static void	veritefb_copycols(void *, int, int, int, int);
    376 static void	veritefb_putchar(void *, int, int, u_int, long);
    377 static void	veritefb_gc_bitblt(void *, int, int, int, int, int, int,
    378 		    int);
    379 
    380 #if defined(DDB) && defined(VERITEFB_DEBUG)
    381 static void	veritefb_ddb_attach(struct veritefb_softc *);
    382 #endif
    383 
    384 extern struct cfdriver veritefb_cd;
    385 
    386 CFATTACH_DECL_NEW(veritefb, sizeof(struct veritefb_softc),
    387     veritefb_match, veritefb_attach, NULL, NULL);
    388 
    389 static struct wsdisplay_accessops veritefb_accessops = {
    390 	.ioctl = veritefb_ioctl,
    391 	.mmap = veritefb_mmap,
    392 };
    393 
    394 static inline uint8_t
    395 vfb_read1(struct veritefb_softc *sc, bus_size_t reg)
    396 {
    397 	if (reg >= VFB_IOONLY_BASE)
    398 		return bus_space_read_1(sc->sc_iot, sc->sc_ioh, reg);
    399 	return bus_space_read_1(sc->sc_regt, sc->sc_regh,
    400 	    sc->sc_regoff + reg);
    401 }
    402 
    403 static inline void
    404 vfb_write1(struct veritefb_softc *sc, bus_size_t reg, uint8_t val)
    405 {
    406 	if (reg >= VFB_IOONLY_BASE) {
    407 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val);
    408 		return;
    409 	}
    410 	bus_space_write_1(sc->sc_regt, sc->sc_regh, sc->sc_regoff + reg,
    411 	    val);
    412 }
    413 
    414 static inline uint32_t
    415 vfb_read4(struct veritefb_softc *sc, bus_size_t reg)
    416 {
    417 	if (reg >= VFB_IOONLY_BASE)
    418 		return bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg);
    419 	return bus_space_read_4(sc->sc_regt, sc->sc_regh,
    420 	    sc->sc_regoff + reg);
    421 }
    422 
    423 static inline void
    424 vfb_write4(struct veritefb_softc *sc, bus_size_t reg, uint32_t val)
    425 {
    426 	if (reg >= VFB_IOONLY_BASE) {
    427 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, val);
    428 		return;
    429 	}
    430 	bus_space_write_4(sc->sc_regt, sc->sc_regh, sc->sc_regoff + reg,
    431 	    val);
    432 }
    433 
    434 static inline uint32_t
    435 vfb_fb_read4(struct veritefb_softc *sc, bus_size_t off)
    436 {
    437 	return bus_space_read_4(sc->sc_memt, sc->sc_memh, off);
    438 }
    439 
    440 static inline void
    441 vfb_fb_write4(struct veritefb_softc *sc, bus_size_t off, uint32_t val)
    442 {
    443 	bus_space_write_4(sc->sc_memt, sc->sc_memh, off, val);
    444 }
    445 
    446 /*
    447  * The FIFO window: input FIFO on write, output FIFO on read.
    448  */
    449 static void
    450 vfb_fifo_write(struct veritefb_softc *sc, uint32_t word)
    451 {
    452 #ifdef VERITEFB_DEBUG
    453 	sc->sc_ring[sc->sc_ring_count++ & (VFB_RING_SIZE - 1)] = word;
    454 #endif
    455 	bus_space_write_4(sc->sc_regt, sc->sc_regh, VFB_FIFO_SWAP_NO, word);
    456 }
    457 
    458 static inline uint32_t
    459 vfb_fifo_read(struct veritefb_softc *sc)
    460 {
    461 	return bus_space_read_4(sc->sc_regt, sc->sc_regh, VFB_FIFO_SWAP_NO);
    462 }
    463 
    464 static void
    465 vfb_pacepoll4(struct veritefb_softc *sc, bus_size_t reg, uint32_t data,
    466     uint32_t mask)
    467 {
    468 	int i;
    469 
    470 	for (i = 0; i < VFB_SHORTPOLL; i++)
    471 		if ((vfb_read4(sc, reg) & mask) == (data & mask))
    472 			break;
    473 }
    474 
    475 static void
    476 vfb_pacepoll1(struct veritefb_softc *sc, bus_size_t reg, uint8_t data,
    477     uint8_t mask)
    478 {
    479 	int i;
    480 
    481 	for (i = 0; i < VFB_SHORTPOLL; i++)
    482 		if ((vfb_read1(sc, reg) & mask) == (data & mask))
    483 			break;
    484 }
    485 
    486 static int
    487 veritefb_match(device_t parent, cfdata_t match, void *aux)
    488 {
    489 	const struct pci_attach_args *pa = aux;
    490 
    491 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RENDITION &&
    492 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RENDITION_V2X00)
    493 		return 100;	/* ahead of genfb(4) */
    494 
    495 	return 0;
    496 }
    497 
    498 static void
    499 veritefb_attach(device_t parent, device_t self, void *aux)
    500 {
    501 	struct veritefb_softc *sc = device_private(self);
    502 	struct wsemuldisplaydev_attach_args ws_aa;
    503 	struct rasops_info *ri;
    504 	const struct pci_attach_args *pa = aux;
    505 	pcireg_t screg;
    506 	bool console;
    507 	long defattr;
    508 
    509 #ifdef VERITEFB_CONSOLE
    510 	console = true;
    511 #else
    512 	console = false;
    513 	prop_dictionary_get_bool(device_properties(self), "is_console",
    514 	    &console);
    515 #endif
    516 
    517 	sc->sc_dev = self;
    518 	sc->sc_pc = pa->pa_pc;
    519 	sc->sc_pcitag = pa->pa_tag;
    520 	sc->sc_dmat = pa->pa_dmat;
    521 
    522 	screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
    523 	    PCI_COMMAND_STATUS_REG);
    524 	screg |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
    525 	pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG,
    526 	    screg);
    527 
    528 	pci_aprint_devinfo(pa, NULL);
    529 
    530 	if (pci_mapreg_map(pa, VFB_IO_BAR, PCI_MAPREG_TYPE_IO, 0,
    531 	    &sc->sc_iot, &sc->sc_ioh, &sc->sc_io_paddr, &sc->sc_ios) != 0) {
    532 		aprint_error_dev(sc->sc_dev, "unable to map I/O registers\n");
    533 		return;
    534 	}
    535 	sc->sc_regt = sc->sc_iot;
    536 	sc->sc_regh = sc->sc_ioh;
    537 	sc->sc_regoff = 0;
    538 
    539 	/*
    540 	 * Reset and hold it the RISC before touching the rest of the card.
    541 	 */
    542 	veritefb_risc_softreset(sc);
    543 	veritefb_risc_hold(sc);
    544 
    545 	if (pci_mapreg_map(pa, VFB_MMIO_BAR, PCI_MAPREG_TYPE_MEM, 0,
    546 	    &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmio_paddr,
    547 	    &sc->sc_mmios) == 0) {
    548 		sc->sc_regt = sc->sc_mmiot;
    549 		sc->sc_regh = sc->sc_mmioh;
    550 		sc->sc_regoff = VFB_MMIO_REG_BASE;
    551 	} else {
    552 		aprint_normal_dev(sc->sc_dev,
    553 		    "MMIO BAR unmappable, all registers via I/O\n");
    554 	}
    555 
    556 	if (pci_mapreg_map(pa, VFB_FB_BAR, PCI_MAPREG_TYPE_MEM,
    557 	    BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
    558 	    &sc->sc_fb_paddr, &sc->sc_apsize) != 0) {
    559 		aprint_error_dev(sc->sc_dev,
    560 		    "unable to map framebuffer aperture\n");
    561 		return;
    562 	}
    563 
    564 	if (sc->sc_regoff != 0)
    565 		aprint_normal_dev(sc->sc_dev,
    566 		    "fb at 0x%08x, MMIO registers at 0x%08x, "
    567 		    "I/O registers at 0x%04x\n",
    568 		    (uint32_t)sc->sc_fb_paddr, (uint32_t)sc->sc_mmio_paddr,
    569 		    (uint32_t)sc->sc_io_paddr);
    570 	else
    571 		aprint_normal_dev(sc->sc_dev,
    572 		    "fb at 0x%08x, I/O registers at 0x%04x\n",
    573 		    (uint32_t)sc->sc_fb_paddr, (uint32_t)sc->sc_io_paddr);
    574 
    575 	sc->sc_memsize = veritefb_mem_size(sc);
    576 	if (sc->sc_memsize == 0) {
    577 		aprint_error_dev(sc->sc_dev, "VRAM probe failed\n");
    578 		return;
    579 	}
    580 
    581 	aprint_normal_dev(sc->sc_dev, "%zu MB video memory present\n",
    582 	    sc->sc_memsize / 1024 / 1024);
    583 
    584 	/*
    585 	 * The first VFB_MC_SIZE bytes of VRAM are reserved for the 2D
    586 	 * microcode, the framebuffer lives above it.
    587 	 */
    588 	sc->sc_fb_offset = VFB_MC_SIZE;
    589 	sc->sc_accel = VFB_ACCEL_OFF;
    590 	sc->sc_risc_owner = VFB_OWNER_CONSOLE;
    591 #ifdef VERITEFB_DEBUG
    592 	callout_init(&sc->sc_pcsample_ch, 0);
    593 	callout_setfunc(&sc->sc_pcsample_ch, veritefb_pcsample_tick, sc);
    594 #endif
    595 
    596 	veritefb_ddc_read(sc);
    597 	veritefb_pick_mode(sc);
    598 
    599 	sc->sc_width = sc->sc_videomode->hdisplay;
    600 	sc->sc_height = sc->sc_videomode->vdisplay;
    601 	sc->sc_depth = 8;
    602 
    603 	{
    604 		const struct veritefb_stride *st;
    605 
    606 		st = veritefb_stride_for(sc->sc_width * (sc->sc_depth / 8));
    607 		if (st == NULL) {
    608 			aprint_error_dev(sc->sc_dev,
    609 			    "no stride encoding for %d bytes/line\n",
    610 			    sc->sc_width * (sc->sc_depth / 8));
    611 			return;
    612 		}
    613 		sc->sc_linebytes = st->linebytes;
    614 		sc->sc_stride0 = st->stride0;
    615 		sc->sc_stride1 = st->stride1;
    616 	}
    617 
    618 	aprint_normal_dev(sc->sc_dev, "setting %dx%d %d bpp resolution\n",
    619 	    sc->sc_width, sc->sc_height, sc->sc_depth);
    620 
    621 	if (!veritefb_set_mode(sc, sc->sc_videomode)) {
    622 		aprint_error_dev(sc->sc_dev, "mode set failed\n");
    623 		return;
    624 	}
    625 
    626 	bus_space_set_region_4(sc->sc_memt, sc->sc_memh, sc->sc_fb_offset, 0,
    627 	    (sc->sc_linebytes * sc->sc_height) / 4);
    628 
    629 	veritefb_init_palette(sc);
    630 
    631 	sc->sc_defaultscreen_descr = (struct wsscreen_descr){
    632 		"default",
    633 		0, 0,
    634 		NULL,
    635 		8, 16,
    636 		WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    637 		NULL
    638 	};
    639 	sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
    640 	sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
    641 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
    642 
    643 	vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
    644 	    &veritefb_accessops);
    645 	sc->vd.init_screen = veritefb_init_screen;
    646 
    647 	/* Glyph cache in the VRAM above the visible framebuffer. */
    648 	sc->sc_gc.gc_bitblt = veritefb_gc_bitblt;
    649 	sc->sc_gc.gc_rectfill = NULL;
    650 	sc->sc_gc.gc_blitcookie = sc;
    651 	sc->sc_gc.gc_rop = VFB_ROP_COPY;
    652 	sc->vd.show_screen_cookie = &sc->sc_gc;
    653 	sc->vd.show_screen_cb = glyphcache_adapt;
    654 
    655 	ri = &sc->sc_console_screen.scr_ri;
    656 
    657 	vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr);
    658 	sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
    659 
    660 	sc->sc_gc_initted = glyphcache_init(&sc->sc_gc,
    661 	    sc->sc_height + VFB_GC_GAP,
    662 	    (int)((sc->sc_memsize - sc->sc_fb_offset) / sc->sc_linebytes) -
    663 		sc->sc_height - VFB_GC_GAP,
    664 	    sc->sc_width,
    665 	    ri->ri_font->fontwidth,
    666 	    ri->ri_font->fontheight,
    667 	    defattr) == 0;
    668 	if (!sc->sc_gc_initted)
    669 		aprint_error_dev(sc->sc_dev, "glyph cache init failed\n");
    670 
    671 	sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
    672 	sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
    673 	sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
    674 	sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
    675 
    676 	vcons_redraw_screen(&sc->sc_console_screen);
    677 
    678 	if (console) {
    679 		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
    680 		    defattr);
    681 		vcons_replay_msgbuf(&sc->sc_console_screen);
    682 	}
    683 
    684 	/*
    685 	 * Interrupt for the vblank flip.
    686 	 */
    687 	{
    688 		pci_intr_handle_t ih;
    689 		char intrbuf[PCI_INTRSTR_LEN];
    690 		const char *intrstr;
    691 
    692 		vfb_write1(sc, VFB_INTREN, 0);
    693 		vfb_write1(sc, VFB_INTR, 0xff);
    694 		if (pci_intr_map(pa, &ih) == 0) {
    695 			intrstr = pci_intr_string(sc->sc_pc, ih, intrbuf,
    696 			    sizeof(intrbuf));
    697 			sc->sc_ih = pci_intr_establish_xname(sc->sc_pc, ih,
    698 			    IPL_VM, veritefb_intr, sc,
    699 			    device_xname(sc->sc_dev));
    700 			if (sc->sc_ih != NULL) {
    701 				sc->sc_flip_intr_ok = true;
    702 				aprint_normal_dev(sc->sc_dev,
    703 				    "interrupting at %s\n", intrstr);
    704 			}
    705 		}
    706 		if (!sc->sc_flip_intr_ok)
    707 			aprint_normal_dev(sc->sc_dev,
    708 			    "no interrupt, flips will poll\n");
    709 	}
    710 
    711 	ws_aa.console = console;
    712 	ws_aa.scrdata = &sc->sc_screenlist;
    713 	ws_aa.accessops = &veritefb_accessops;
    714 	ws_aa.accesscookie = &sc->vd;
    715 
    716 	config_found(sc->sc_dev, &ws_aa, wsemuldisplaydevprint, CFARGS_NONE);
    717 
    718 #if defined(DDB) && defined(VERITEFB_DEBUG)
    719 	veritefb_ddb_attach(sc);
    720 #endif
    721 
    722 	/* Firmware needs a mounted root filesystem. */
    723 	config_mountroot(self, veritefb_load_firmware);
    724 }
    725 
    726 /*
    727  * Reset the chip, leaving the RISC held.
    728  */
    729 static void
    730 veritefb_risc_softreset(struct veritefb_softc *sc)
    731 {
    732 	int i;
    733 
    734 	vfb_write1(sc, VFB_DEBUG, VFB_DEBUG_SOFTRESET | VFB_DEBUG_HOLDRISC);
    735 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC);
    736 	for (i = 0; i < 3; i++)
    737 		(void)vfb_read4(sc, VFB_STATEDATA);
    738 
    739 	vfb_write1(sc, VFB_DEBUG, VFB_DEBUG_HOLDRISC);
    740 	for (i = 0; i < 3; i++)
    741 		(void)vfb_read4(sc, VFB_STATEDATA);
    742 
    743 	/* Clear any pending interrupts, no byte swapping. */
    744 	vfb_write1(sc, VFB_INTR, 0xff);
    745 	vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
    746 }
    747 
    748 /*
    749  * Make sure the RISC is held.
    750  */
    751 static void
    752 veritefb_risc_hold(struct veritefb_softc *sc)
    753 {
    754 	uint8_t debugreg;
    755 	int i;
    756 
    757 	for (i = 0; i < VFB_MAXPOLL; i++) {
    758 		if ((vfb_read1(sc, VFB_STATUS) & VFB_STATUS_HOLD_MASK) ==
    759 		    VFB_STATUS_HOLD_MASK)
    760 			break;
    761 		delay(1);
    762 	}
    763 	if (i == VFB_MAXPOLL)
    764 		aprint_debug_dev(sc->sc_dev,
    765 		    "timeout waiting for idle status before hold\n");
    766 
    767 	debugreg = vfb_read1(sc, VFB_DEBUG);
    768 	vfb_write1(sc, VFB_DEBUG, debugreg | VFB_DEBUG_HOLDRISC);
    769 
    770 	for (i = 0; i < VFB_MAXPOLL; i++) {
    771 		if (vfb_read1(sc, VFB_STATUS) & VFB_STATUS_HELD)
    772 			break;
    773 		delay(1);
    774 	}
    775 	if (i == VFB_MAXPOLL)
    776 		aprint_debug_dev(sc->sc_dev,
    777 		    "timeout waiting for hold confirmation\n");
    778 }
    779 
    780 /*
    781  * Probe the amount of VRAM by write/readback at 1 MB steps...
    782  */
    783 static size_t
    784 veritefb_mem_size(struct veritefb_softc *sc)
    785 {
    786 	const bus_size_t onemeg = 1024 * 1024;
    787 	bus_size_t offset, maxvram;
    788 	uint32_t pattern, start;
    789 	uint8_t modereg, memendian;
    790 	size_t memsize;
    791 
    792 	maxvram = MIN(VFB_MAXVRAM, sc->sc_apsize);
    793 
    794 	modereg = vfb_read1(sc, VFB_MODE);
    795 	vfb_write1(sc, VFB_MODE, VFB_MODE_NATIVE);
    796 	memendian = vfb_read1(sc, VFB_MEMENDIAN);
    797 	vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
    798 
    799 	start = vfb_fb_read4(sc, 0);
    800 	vfb_fb_write4(sc, 0, VFB_PROBE_START);
    801 	for (offset = onemeg; offset < maxvram; offset += onemeg) {
    802 		pattern = vfb_fb_read4(sc, offset);
    803 		if (pattern == VFB_PROBE_START)
    804 			break;	/* wrapped around, back at offset 0 */
    805 
    806 		pattern ^= VFB_PROBE_PATTERN;
    807 		vfb_fb_write4(sc, offset, pattern);
    808 		if (vfb_fb_read4(sc, offset) != pattern) {
    809 			offset -= onemeg;
    810 			break;
    811 		}
    812 		vfb_fb_write4(sc, offset, pattern ^ VFB_PROBE_PATTERN);
    813 	}
    814 	vfb_fb_write4(sc, 0, start);
    815 
    816 	if (offset >= maxvram)
    817 		memsize = 4 * onemeg;
    818 	else
    819 		memsize = offset;
    820 
    821 	vfb_write1(sc, VFB_MEMENDIAN, memendian);
    822 	vfb_write1(sc, VFB_MODE, modereg);
    823 
    824 	return memsize;
    825 }
    826 
    827 /*
    828  * Find PLL parameters for the requested pixel clock
    829  */
    830 static bool
    831 veritefb_calc_pclk(int kHz, int *m, int *n, int *p)
    832 {
    833 	int64_t target, vco, pcf, freq, diff, mindiff;
    834 	int mm, nn, pp;
    835 
    836 	target = (int64_t)kHz * 100;
    837 	mindiff = INT64_MAX;
    838 	*m = *n = *p = 0;
    839 
    840 	for (pp = 1; pp <= VFB_PLL_P_MAX; pp++) {
    841 		for (nn = 1; nn <= VFB_PLL_N_MAX; nn++) {
    842 			pcf = VFB_PLL_REF / nn;
    843 			if (pcf < VFB_PLL_PCF_MIN || pcf > VFB_PLL_PCF_MAX)
    844 				continue;
    845 			for (mm = 1; mm <= VFB_PLL_M_MAX; mm++) {
    846 				vco = (int64_t)VFB_PLL_REF * mm / nn;
    847 				if (vco < VFB_PLL_VCO_MIN ||
    848 				    vco > VFB_PLL_VCO_MAX)
    849 					continue;
    850 				freq = vco / pp;
    851 				diff = freq > target ?
    852 				    freq - target : target - freq;
    853 				if (diff < mindiff) {
    854 					*m = mm;
    855 					*n = nn;
    856 					*p = pp;
    857 					mindiff = diff;
    858 				}
    859 			}
    860 		}
    861 	}
    862 
    863 	return *m != 0;
    864 }
    865 
    866 /*
    867  * Smallest pixel-engine stride encoding that fits a line of the given
    868  * width... widths with no dense encoding get a padded framebuffer.
    869  */
    870 static const struct veritefb_stride *
    871 veritefb_stride_for(int linebytes)
    872 {
    873 	const struct veritefb_stride *st;
    874 
    875 	for (st = veritefb_stride_table; st->linebytes != 0; st++)
    876 		if (st->linebytes >= linebytes)
    877 			return st;
    878 	return NULL;
    879 }
    880 
    881 /*
    882  * Program a native (non-VGA) mode: memory/system clocks, pixel clock
    883  * PLL, RAMDAC, CRTC timing, frame base and stride, then enable video.
    884  */
    885 static bool
    886 veritefb_set_mode(struct veritefb_softc *sc, const struct videomode *vm)
    887 {
    888 	uint32_t memctl, crtcctl, offset, screenwidth;
    889 	int m, n, p;
    890 
    891 	if (!veritefb_calc_pclk(vm->dot_clock, &m, &n, &p)) {
    892 		aprint_error_dev(sc->sc_dev, "no PLL solution for %d kHz\n",
    893 		    vm->dot_clock);
    894 		return false;
    895 	}
    896 	aprint_debug_dev(sc->sc_dev, "PLL M=%d N=%d P=%d for %d kHz\n",
    897 	    m, n, p, vm->dot_clock);
    898 
    899 	/* Leave VGA emulation; no legacy 0xA0000 window. */
    900 	vfb_write1(sc, VFB_MODE, VFB_MODE_NATIVE);
    901 
    902 	/*
    903 	 * 8bpp this does not matter...
    904 	 * TODO: Revisit for 16/32bpp.
    905 	 */
    906 	switch (sc->sc_depth) {
    907 	case 8:
    908 		vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_END);
    909 		break;
    910 	case 16:
    911 		vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_HW);
    912 		break;
    913 	case 32:
    914 		vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
    915 		break;
    916 	}
    917 
    918 	/* System/memory clock: MClk 110 MHz, SClk 55 MHz. */
    919 	vfb_write4(sc, VFB_SCLKPLL, VFB_SCLKPLL_DEFAULT);
    920 	delay(VFB_PLL_STABILIZE_US);
    921 
    922 	/* Resume memory refresh, default write refresh period. */
    923 	memctl = vfb_read4(sc, VFB_MEMCTL) & ~VFB_MEMCTL_HOLDREFRESH;
    924 	vfb_write4(sc, VFB_MEMCTL, memctl | VFB_MEMCTL_WREFRESH_DEFAULT);
    925 
    926 	/* Native mode wants swizzled memory addressing. */
    927 	memctl = vfb_read4(sc, VFB_MEMCTL) & ~VFB_MEMCTL_ADRSWIZZLE_MASK;
    928 	vfb_write4(sc, VFB_MEMCTL, memctl);
    929 
    930 	vfb_write4(sc, VFB_PCLKPLL,
    931 	    __SHIFTIN((uint32_t)n, VFB_PCLKPLL_N_MASK) |
    932 	    __SHIFTIN((uint32_t)p, VFB_PCLKPLL_P_MASK) |
    933 	    __SHIFTIN((uint32_t)m, VFB_PCLKPLL_M_MASK));
    934 	delay(VFB_PLL_STABILIZE_US);
    935 
    936 	veritefb_init_dac(sc);
    937 
    938 	vfb_write4(sc, VFB_CRTCHORZ,
    939 	    __SHIFTIN((uint32_t)(vm->hsync_start - vm->hdisplay) / 8 - 1,
    940 		VFB_CRTCHORZ_FRONTPORCH_MASK) |
    941 	    __SHIFTIN((uint32_t)(vm->hsync_end - vm->hsync_start) / 8 - 1,
    942 		VFB_CRTCHORZ_SYNC_MASK) |
    943 	    __SHIFTIN((uint32_t)(vm->htotal - vm->hsync_end) / 8 - 1,
    944 		VFB_CRTCHORZ_BACKPORCH_MASK) |
    945 	    __SHIFTIN((uint32_t)vm->hdisplay / 8 - 1,
    946 		VFB_CRTCHORZ_ACTIVE_MASK));
    947 	vfb_write4(sc, VFB_CRTCVERT,
    948 	    __SHIFTIN((uint32_t)(vm->vsync_start - vm->vdisplay) - 1,
    949 		VFB_CRTCVERT_FRONTPORCH_MASK) |
    950 	    __SHIFTIN((uint32_t)(vm->vsync_end - vm->vsync_start) - 1,
    951 		VFB_CRTCVERT_SYNC_MASK) |
    952 	    __SHIFTIN((uint32_t)(vm->vtotal - vm->vsync_end) - 1,
    953 		VFB_CRTCVERT_BACKPORCH_MASK) |
    954 	    __SHIFTIN((uint32_t)vm->vdisplay - 1,
    955 		VFB_CRTCVERT_ACTIVE_MASK));
    956 
    957 	screenwidth = (uint32_t)sc->sc_width * (sc->sc_depth / 8);
    958 	offset = sc->sc_linebytes - screenwidth +
    959 	    screenwidth % VFB_VIDEOFIFO_BYTES;
    960 	if (screenwidth % VFB_VIDEOFIFO_BYTES == 0)
    961 		offset += VFB_VIDEOFIFO_BYTES;
    962 	vfb_write4(sc, VFB_FRAMEBASEA, (uint32_t)sc->sc_fb_offset);
    963 	vfb_write4(sc, VFB_CRTCOFFSET, offset & VFB_CRTCOFFSET_MASK);
    964 
    965 	crtcctl = (sc->sc_depth == 16 ? VFB_PIXFMT_565 : VFB_PIXFMT_8I) |
    966 	    VFB_CRTCCTL_VIDEOFIFOSIZE128 |
    967 	    ((vm->flags & VID_PHSYNC) ? VFB_CRTCCTL_HSYNCHI : 0) |
    968 	    ((vm->flags & VID_PVSYNC) ? VFB_CRTCCTL_VSYNCHI : 0) |
    969 	    VFB_CRTCCTL_HSYNCENABLE |
    970 	    VFB_CRTCCTL_VSYNCENABLE |
    971 	    VFB_CRTCCTL_VIDEOENABLE;
    972 	vfb_write4(sc, VFB_CRTCCTL, crtcctl);
    973 
    974 	return true;
    975 }
    976 
    977 #define VFB_DDC_PACE_US		5	/* between line transitions */
    978 #define VFB_DDC_STRETCH_US	1000	/* max tolerated clock stretch */
    979 
    980 static const struct i2c_bitbang_ops veritefb_i2cbb_ops = {
    981 	veritefb_i2cbb_set_bits,
    982 	veritefb_i2cbb_set_dir,
    983 	veritefb_i2cbb_read_bits,
    984 	{
    985 		VFB_CRTCCTL_DDCDATA,	/* SDA */
    986 		VFB_CRTCCTL_DDCOUTPUT,	/* SCL */
    987 		0,			/* open-drain: no direction flip */
    988 		0
    989 	}
    990 };
    991 
    992 /*
    993  * SDA in output mode is push-pull, so open-drain is emulated
    994  */
    995 static void
    996 veritefb_i2cbb_set_bits(void *cookie, uint32_t bits)
    997 {
    998 	struct veritefb_softc *sc = cookie;
    999 	uint32_t v;
   1000 
   1001 	v = sc->sc_ddc_base & ~(VFB_CRTCCTL_DDCDATA |
   1002 	    VFB_CRTCCTL_DDCOUTPUT | VFB_CRTCCTL_ENABLEDDC);
   1003 	if (bits & VFB_CRTCCTL_DDCOUTPUT)
   1004 		v |= VFB_CRTCCTL_DDCOUTPUT;	/* SCL: release */
   1005 	if (bits & VFB_CRTCCTL_DDCDATA)
   1006 		v |= VFB_CRTCCTL_DDCDATA;	/* SDA high: mirror to latch */
   1007 	else
   1008 		v |= VFB_CRTCCTL_ENABLEDDC;	/* SDA: drive low (b7=0) */
   1009 
   1010 	sc->sc_ddc_base = v;
   1011 	vfb_write4(sc, VFB_CRTCCTL, v);
   1012 	delay(VFB_DDC_PACE_US);
   1013 }
   1014 
   1015 static void
   1016 veritefb_i2cbb_set_dir(void *cookie, uint32_t dir)
   1017 {
   1018 	/* open-drain emulation: direction is part of set_bits */
   1019 }
   1020 
   1021 static uint32_t
   1022 veritefb_i2cbb_read_bits(void *cookie)
   1023 {
   1024 	struct veritefb_softc *sc = cookie;
   1025 
   1026 	return vfb_read4(sc, VFB_CRTCCTL);
   1027 }
   1028 
   1029 /*
   1030  * I2C START, including a properly shaped repeated START.
   1031  */
   1032 static int
   1033 veritefb_i2c_send_start(void *cookie, int flags)
   1034 {
   1035 	struct veritefb_softc *sc = cookie;
   1036 	int bail;
   1037 
   1038 	if ((veritefb_i2cbb_read_bits(sc) & VFB_CRTCCTL_DDCOUTPUT) == 0) {
   1039 		veritefb_i2cbb_set_bits(sc, VFB_CRTCCTL_DDCDATA);
   1040 		delay(VFB_DDC_PACE_US);	/* SDA settle while SCL still low */
   1041 		veritefb_i2cbb_set_bits(sc,
   1042 		    VFB_CRTCCTL_DDCDATA | VFB_CRTCCTL_DDCOUTPUT);
   1043 		for (bail = 0; bail < VFB_DDC_STRETCH_US; bail++) {
   1044 			if (veritefb_i2cbb_read_bits(sc) &
   1045 			    VFB_CRTCCTL_DDCOUTPUT)
   1046 				break;
   1047 			delay(1);
   1048 		}
   1049 		delay(VFB_DDC_PACE_US);	/* START setup time (4.7 us) */
   1050 	}
   1051 	return i2c_bitbang_send_start(cookie, flags, &veritefb_i2cbb_ops);
   1052 }
   1053 
   1054 static int
   1055 veritefb_i2c_send_stop(void *cookie, int flags)
   1056 {
   1057 	return i2c_bitbang_send_stop(cookie, flags, &veritefb_i2cbb_ops);
   1058 }
   1059 
   1060 static int
   1061 veritefb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
   1062 {
   1063 	return i2c_bitbang_initiate_xfer(cookie, addr, flags,
   1064 	    &veritefb_i2cbb_ops);
   1065 }
   1066 
   1067 static int
   1068 veritefb_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
   1069 {
   1070 	return i2c_bitbang_read_byte(cookie, valp, flags,
   1071 	    &veritefb_i2cbb_ops);
   1072 }
   1073 
   1074 static int
   1075 veritefb_i2c_write_byte(void *cookie, uint8_t val, int flags)
   1076 {
   1077 	return i2c_bitbang_write_byte(cookie, val, flags,
   1078 	    &veritefb_i2cbb_ops);
   1079 }
   1080 
   1081 static void
   1082 veritefb_ddc_read(struct veritefb_softc *sc)
   1083 {
   1084 	int i;
   1085 
   1086 	/*
   1087 	 * Release both lines (SDA as input, SCL high-Z) before
   1088 	 * starting the controller.
   1089 	 */
   1090 	sc->sc_ddc_base = vfb_read4(sc, VFB_CRTCCTL) &
   1091 	    ~(VFB_CRTCCTL_DDCDATA | VFB_CRTCCTL_DDCOUTPUT |
   1092 	      VFB_CRTCCTL_ENABLEDDC);
   1093 	vfb_write4(sc, VFB_CRTCCTL,
   1094 	    sc->sc_ddc_base | VFB_CRTCCTL_DDCOUTPUT);
   1095 	sc->sc_ddc_base |= VFB_CRTCCTL_DDCOUTPUT;
   1096 
   1097 	iic_tag_init(&sc->sc_i2c);
   1098 	sc->sc_i2c.ic_cookie = sc;
   1099 	sc->sc_i2c.ic_send_start = veritefb_i2c_send_start;
   1100 	sc->sc_i2c.ic_send_stop = veritefb_i2c_send_stop;
   1101 	sc->sc_i2c.ic_initiate_xfer = veritefb_i2c_initiate_xfer;
   1102 	sc->sc_i2c.ic_read_byte = veritefb_i2c_read_byte;
   1103 	sc->sc_i2c.ic_write_byte = veritefb_i2c_write_byte;
   1104 
   1105 	/* Some monitors do not respond on the first attempt. */
   1106 	sc->sc_edid_valid = false;
   1107 	memset(sc->sc_edid, 0, sizeof(sc->sc_edid));
   1108 	for (i = 0; i < 3; i++) {
   1109 		if (ddc_read_edid(&sc->sc_i2c, sc->sc_edid,
   1110 		    sizeof(sc->sc_edid)) == 0 && sc->sc_edid[1] != 0)
   1111 			break;
   1112 		memset(sc->sc_edid, 0, sizeof(sc->sc_edid));
   1113 	}
   1114 
   1115 	if (sc->sc_edid[1] == 0) {
   1116 		aprint_normal_dev(sc->sc_dev, "DDC: no EDID response\n");
   1117 		return;
   1118 	}
   1119 
   1120 	if (edid_parse(sc->sc_edid, &sc->sc_ei) != 0) {
   1121 		aprint_error_dev(sc->sc_dev, "DDC: EDID parse failed\n");
   1122 		return;
   1123 	}
   1124 	sc->sc_edid_valid = true;
   1125 #ifdef VERITEFB_DEBUG
   1126 	edid_print(&sc->sc_ei);
   1127 #endif
   1128 }
   1129 
   1130 /*
   1131  * Can the hardware and this driver do the given mode?
   1132  */
   1133 static bool
   1134 veritefb_mode_usable(struct veritefb_softc *sc, const struct videomode *m)
   1135 {
   1136 	const struct veritefb_stride *st;
   1137 
   1138 	if (m->dot_clock > 170000)
   1139 		return false;
   1140 	if (m->flags & (VID_INTERLACE | VID_DBLSCAN))
   1141 		return false;
   1142 	if (m->hdisplay > 2048 || (m->hdisplay & 7) != 0 ||
   1143 	    m->vdisplay > 2047)
   1144 		return false;
   1145 	if ((m->hsync_start - m->hdisplay) / 8 - 1 > 0x7 ||
   1146 	    (m->hsync_end - m->hsync_start) / 8 - 1 > 0x1f ||
   1147 	    (m->htotal - m->hsync_end) / 8 - 1 > 0x3f ||
   1148 	    ((m->hsync_start - m->hdisplay) & 7) != 0 ||
   1149 	    ((m->hsync_end - m->hsync_start) & 7) != 0 ||
   1150 	    ((m->htotal - m->hsync_end) & 7) != 0)
   1151 		return false;
   1152 	if (m->vsync_start - m->vdisplay < 1 ||
   1153 	    m->vsync_start - m->vdisplay - 1 > 0x3f ||
   1154 	    m->vsync_end - m->vsync_start - 1 > 0x7 ||
   1155 	    m->vtotal - m->vsync_end - 1 > 0x3f)
   1156 		return false;
   1157 	/* one byte per pixel at 8bpp, the stride may be padded */
   1158 	st = veritefb_stride_for(m->hdisplay);
   1159 	if (st == NULL)
   1160 		return false;
   1161 	if ((bus_size_t)st->linebytes * m->vdisplay >
   1162 	    sc->sc_memsize - sc->sc_fb_offset)
   1163 		return false;
   1164 	return true;
   1165 }
   1166 
   1167 /*
   1168  * Choose the mode: the monitor's EDID preferred mode when usable,
   1169  * 640x480@60 from the modes database otherwise.
   1170  */
   1171 static void
   1172 veritefb_pick_mode(struct veritefb_softc *sc)
   1173 {
   1174 	const struct videomode *m;
   1175 
   1176 	sc->sc_videomode = pick_mode_by_ref(640, 480, 60);
   1177 	KASSERT(sc->sc_videomode != NULL);
   1178 
   1179 	if (!sc->sc_edid_valid || sc->sc_ei.edid_preferred_mode == NULL)
   1180 		return;
   1181 
   1182 	m = sc->sc_ei.edid_preferred_mode;
   1183 	if (!veritefb_mode_usable(sc, m)) {
   1184 		aprint_normal_dev(sc->sc_dev,
   1185 		    "EDID preferred mode %dx%d (%d kHz) not usable, "
   1186 		    "using default\n",
   1187 		    m->hdisplay, m->vdisplay, m->dot_clock);
   1188 		return;
   1189 	}
   1190 
   1191 	aprint_normal_dev(sc->sc_dev, "using EDID mode %dx%d (%d kHz)\n",
   1192 	    m->hdisplay, m->vdisplay, m->dot_clock);
   1193 	sc->sc_videomode = m;
   1194 }
   1195 
   1196 /*
   1197  * Initialize the Bt485-compatible RAMDAC core
   1198  */
   1199 static void
   1200 veritefb_init_dac(struct veritefb_softc *sc)
   1201 {
   1202 	uint8_t cmd1;
   1203 
   1204 	if (sc->sc_depth == 16)
   1205 		cmd1 = VFB_DACCMD1_16BPP | VFB_DACCMD1_BYPASS_CLUT |
   1206 		    VFB_DACCMD1_565 | VFB_DACCMD1_PORT_AB;
   1207 	else
   1208 		cmd1 = VFB_DACCMD1_8BPP | VFB_DACCMD1_PORT_AB;
   1209 
   1210 	vfb_write1(sc, VFB_DACCOMMAND0,
   1211 	    VFB_DACCMD0_EXTENDED | VFB_DACCMD0_8BITDAC);
   1212 	vfb_write1(sc, VFB_DACCOMMAND1, cmd1);
   1213 	vfb_write1(sc, VFB_DACCOMMAND2,
   1214 	    VFB_DACCMD2_PIXEL_INPUT_GATE | VFB_DACCMD2_DISABLE_CURSOR);
   1215 
   1216 	/* Command register 3 is indexed through the write address. */
   1217 	vfb_write1(sc, VFB_DACRAMWRITEADR, VFB_DACCMD3_INDEX);
   1218 	vfb_write1(sc, VFB_DACCOMMAND3, 0);
   1219 
   1220 	vfb_write1(sc, VFB_DACPIXELMSK, 0xff);
   1221 }
   1222 
   1223 /*
   1224  * Wait for vertical sync so palette updates do not tear.
   1225  */
   1226 static void
   1227 veritefb_wait_vsync(struct veritefb_softc *sc)
   1228 {
   1229 	int i;
   1230 
   1231 	for (i = 0; i < VFB_VSYNCPOLL; i++) {
   1232 		if ((vfb_read4(sc, VFB_CRTCSTATUS) &
   1233 		    VFB_CRTCSTATUS_VERT_MASK) == VFB_CRTCSTATUS_VERT_SYNC)
   1234 			break;
   1235 		delay(1);
   1236 	}
   1237 }
   1238 
   1239 static void
   1240 veritefb_set_dac_entry(struct veritefb_softc *sc, int index,
   1241     uint8_t r, uint8_t g, uint8_t b)
   1242 {
   1243 	vfb_write1(sc, VFB_DACRAMWRITEADR, index);
   1244 	vfb_write1(sc, VFB_DACRAMDATA, r);
   1245 	vfb_write1(sc, VFB_DACRAMDATA, g);
   1246 	vfb_write1(sc, VFB_DACRAMDATA, b);
   1247 }
   1248 
   1249 static void
   1250 veritefb_init_palette(struct veritefb_softc *sc)
   1251 {
   1252 	int i, j;
   1253 
   1254 	j = 0;
   1255 	veritefb_wait_vsync(sc);
   1256 	for (i = 0; i < 256; i++) {
   1257 		sc->sc_cmap_red[i] = rasops_cmap[j];
   1258 		sc->sc_cmap_green[i] = rasops_cmap[j + 1];
   1259 		sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
   1260 		veritefb_set_dac_entry(sc, i, rasops_cmap[j],
   1261 		    rasops_cmap[j + 1], rasops_cmap[j + 2]);
   1262 		j += 3;
   1263 	}
   1264 }
   1265 
   1266 static int
   1267 veritefb_getcmap(struct veritefb_softc *sc, struct wsdisplay_cmap *cm)
   1268 {
   1269 	u_int index = cm->index;
   1270 	u_int count = cm->count;
   1271 	int error;
   1272 
   1273 	if (index >= 256 || count > 256 || index + count > 256)
   1274 		return EINVAL;
   1275 
   1276 	error = copyout(&sc->sc_cmap_red[index], cm->red, count);
   1277 	if (error)
   1278 		return error;
   1279 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
   1280 	if (error)
   1281 		return error;
   1282 	error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
   1283 	if (error)
   1284 		return error;
   1285 
   1286 	return 0;
   1287 }
   1288 
   1289 static int
   1290 veritefb_putcmap(struct veritefb_softc *sc, struct wsdisplay_cmap *cm)
   1291 {
   1292 	u_char rbuf[256], gbuf[256], bbuf[256];
   1293 	u_int index = cm->index;
   1294 	u_int count = cm->count;
   1295 	int i, error;
   1296 
   1297 	if (index >= 256 || count > 256 || index + count > 256)
   1298 		return EINVAL;
   1299 
   1300 	error = copyin(cm->red, &rbuf[index], count);
   1301 	if (error)
   1302 		return error;
   1303 	error = copyin(cm->green, &gbuf[index], count);
   1304 	if (error)
   1305 		return error;
   1306 	error = copyin(cm->blue, &bbuf[index], count);
   1307 	if (error)
   1308 		return error;
   1309 
   1310 	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
   1311 	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
   1312 	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
   1313 
   1314 	veritefb_wait_vsync(sc);
   1315 	for (i = index; i < index + count; i++)
   1316 		veritefb_set_dac_entry(sc, i, sc->sc_cmap_red[i],
   1317 		    sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
   1318 
   1319 	return 0;
   1320 }
   1321 
   1322 static void
   1323 veritefb_init_screen(void *cookie, struct vcons_screen *scr, int existing,
   1324     long *defattr)
   1325 {
   1326 	struct veritefb_softc *sc = cookie;
   1327 	struct rasops_info *ri = &scr->scr_ri;
   1328 
   1329 	wsfont_init();
   1330 
   1331 	ri->ri_depth = sc->sc_depth;
   1332 	ri->ri_width = sc->sc_width;
   1333 	ri->ri_height = sc->sc_height;
   1334 	ri->ri_stride = sc->sc_linebytes;
   1335 	ri->ri_flg = RI_CENTER;
   1336 
   1337 	ri->ri_bits = (char *)bus_space_vaddr(sc->sc_memt, sc->sc_memh) +
   1338 	    sc->sc_fb_offset;
   1339 
   1340 	scr->scr_flags |= VCONS_NO_CURSOR;
   1341 
   1342 	rasops_init(ri, 0, 0);
   1343 	ri->ri_caps = WSSCREEN_WSCOLORS;
   1344 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
   1345 	    sc->sc_width / ri->ri_font->fontwidth);
   1346 
   1347 	ri->ri_hw = scr;
   1348 
   1349 	sc->sc_orig_eraserows = ri->ri_ops.eraserows;
   1350 	sc->sc_orig_erasecols = ri->ri_ops.erasecols;
   1351 	sc->sc_orig_copyrows = ri->ri_ops.copyrows;
   1352 	sc->sc_orig_copycols = ri->ri_ops.copycols;
   1353 	sc->sc_orig_putchar = ri->ri_ops.putchar;
   1354 	ri->ri_ops.eraserows = veritefb_eraserows;
   1355 	ri->ri_ops.erasecols = veritefb_erasecols;
   1356 	ri->ri_ops.copyrows = veritefb_copyrows;
   1357 	ri->ri_ops.copycols = veritefb_copycols;
   1358 	ri->ri_ops.putchar = veritefb_putchar;
   1359 }
   1360 
   1361 static int
   1362 veritefb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
   1363     struct lwp *l)
   1364 {
   1365 	struct vcons_data *vd;
   1366 	struct veritefb_softc *sc;
   1367 	struct wsdisplay_fbinfo *wsfbi;
   1368 	struct vcons_screen *ms;
   1369 
   1370 	vd = v;
   1371 	sc = vd->cookie;
   1372 	ms = vd->active;
   1373 
   1374 	switch (cmd) {
   1375 	case WSDISPLAYIO_GTYPE:
   1376 		*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
   1377 		return 0;
   1378 
   1379 	case PCI_IOC_CFGREAD:
   1380 	case PCI_IOC_CFGWRITE:
   1381 		return pci_devioctl(sc->sc_pc, sc->sc_pcitag,
   1382 		    cmd, data, flag, l);
   1383 
   1384 	case WSDISPLAYIO_GET_BUSID:
   1385 		return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc,
   1386 		    sc->sc_pcitag, data);
   1387 
   1388 	case WSDISPLAYIO_GINFO:
   1389 		if (ms == NULL)
   1390 			return ENODEV;
   1391 
   1392 		wsfbi = (void *)data;
   1393 		wsfbi->height = ms->scr_ri.ri_height;
   1394 		wsfbi->width = ms->scr_ri.ri_width;
   1395 		wsfbi->depth = ms->scr_ri.ri_depth;
   1396 		wsfbi->cmsize = 256;
   1397 		return 0;
   1398 
   1399 	case WSDISPLAYIO_LINEBYTES:
   1400 		*(u_int *)data = sc->sc_linebytes;
   1401 		return 0;
   1402 
   1403 	case WSDISPLAYIO_GETCMAP:
   1404 		return veritefb_getcmap(sc, (struct wsdisplay_cmap *)data);
   1405 
   1406 	case WSDISPLAYIO_PUTCMAP:
   1407 		return veritefb_putcmap(sc, (struct wsdisplay_cmap *)data);
   1408 
   1409 	case WSDISPLAYIO_SMODE:
   1410 		{
   1411 			int new_mode = *(int *)data;
   1412 
   1413 			/* sync/hold/reload flows below PIO the FIFO */
   1414 			(void)veritefb_dma_drain(sc);
   1415 			if (new_mode != sc->sc_mode) {
   1416 				sc->sc_mode = new_mode;
   1417 				if (new_mode == WSDISPLAYIO_MODE_EMUL) {
   1418 					/*
   1419 					 * reload and restart the microcode
   1420 					 */
   1421 					if (sc->sc_accel == VFB_ACCEL_ON ||
   1422 					    (sc->sc_accel == VFB_ACCEL_OFF &&
   1423 					     sc->sc_ucode != NULL))
   1424 						(void)veritefb_risc_init(sc);
   1425 					if (sc->sc_gc_initted)
   1426 						glyphcache_wipe(&sc->sc_gc);
   1427 					veritefb_init_palette(sc);
   1428 					vcons_redraw_screen(ms);
   1429 				} else {
   1430 					if (sc->sc_accel == VFB_ACCEL_ON) {
   1431 						veritefb_sync(sc);
   1432 						(void)veritefb_drain_outfifo(
   1433 						    sc);
   1434 						veritefb_risc_hold(sc);
   1435 						sc->sc_accel = VFB_ACCEL_OFF;
   1436 					} else if (sc->sc_risc_owner !=
   1437 					    VFB_OWNER_CONSOLE) {
   1438 						veritefb_risc_hold(sc);
   1439 						sc->sc_risc_owner =
   1440 						    VFB_OWNER_CONSOLE;
   1441 					}
   1442 				}
   1443 			}
   1444 			return 0;
   1445 		}
   1446 
   1447 	case WSDISPLAYIO_GET_FBINFO:
   1448 		{
   1449 			struct wsdisplayio_fbinfo *fbi = data;
   1450 			struct rasops_info *ri;
   1451 
   1452 			ri = &sc->vd.active->scr_ri;
   1453 			return wsdisplayio_get_fbinfo(ri, fbi);
   1454 		}
   1455 
   1456 #ifdef VERITEFB_DEBUG
   1457 	/* RISC debug surface, VERITEFB_DEBUG kernels only. */
   1458 	case VERITEFB_DBG_DIAG:
   1459 		{
   1460 			struct veritefb_dbg_diag *dd = data;
   1461 			unsigned i, n;
   1462 
   1463 			dd->vd_accel = sc->sc_accel;
   1464 			dd->vd_owner = sc->sc_risc_owner;
   1465 			dd->vd_pc = veritefb_risc_samplepc(sc);
   1466 			dd->vd_fifoinfree = vfb_read1(sc, VFB_FIFOINFREE) &
   1467 			    VFB_FIFOINFREE_MASK;
   1468 			dd->vd_fifooutvalid = vfb_read1(sc,
   1469 			    VFB_FIFOOUTVALID) & VFB_FIFOOUTVALID_MASK;
   1470 			dd->vd_debugreg = vfb_read1(sc, VFB_DEBUG);
   1471 			dd->vd_ringcount = sc->sc_ring_count;
   1472 			n = MIN(sc->sc_ring_count, VERITEFB_DIAG_RING);
   1473 			memset(dd->vd_ring, 0, sizeof(dd->vd_ring));
   1474 			for (i = 0; i < n; i++)
   1475 				dd->vd_ring[VERITEFB_DIAG_RING - n + i] =
   1476 				    sc->sc_ring[(sc->sc_ring_count - n + i) &
   1477 				    (VFB_RING_SIZE - 1)];
   1478 
   1479 			dd->vd_heartbeat = 1;
   1480 			if (sc->sc_accel == VFB_ACCEL_ON) {
   1481 				uint32_t word = 0;
   1482 
   1483 				veritefb_sync(sc);
   1484 				dd->vd_heartbeat = 2;
   1485 				for (i = 0; i < VFB_DRAINPOLL; i++) {
   1486 					if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   1487 					    VFB_FIFOOUTVALID_MASK) == 0)
   1488 						break;
   1489 					(void)vfb_fifo_read(sc);
   1490 				}
   1491 				if ((vfb_read1(sc, VFB_FIFOINFREE) &
   1492 				    VFB_FIFOINFREE_MASK) >= 1) {
   1493 					vfb_fifo_write(sc,
   1494 					    VFB_CMDW(0, VCMD_PIXENGSYNC));
   1495 					for (i = 0; i < VFB_FIFOPOLL; i++) {
   1496 						if ((vfb_read1(sc,
   1497 						    VFB_FIFOOUTVALID) &
   1498 						    VFB_FIFOOUTVALID_MASK)
   1499 						    != 0) {
   1500 							word =
   1501 							    vfb_fifo_read(sc);
   1502 							break;
   1503 						}
   1504 						delay(1);
   1505 					}
   1506 					if (word == VFB_SYNC_TOKEN)
   1507 						dd->vd_heartbeat = 0;
   1508 				}
   1509 			} else if (sc->sc_risc_owner == VFB_OWNER_PARKED) {
   1510 				uint32_t word;
   1511 
   1512 				/*
   1513 				 * XXX: foreign microcode would eat the ping
   1514 				 * as a command!
   1515 				 */
   1516 				(void)veritefb_dma_drain(sc);
   1517 				dd->vd_heartbeat = 2;
   1518 				if (veritefb_drain_outfifo(sc) == 0 &&
   1519 				    veritefb_waitfifo_raw(sc, 1,
   1520 				      VFB_FIFOPOLL) == 0) {
   1521 					vfb_fifo_write(sc, VFB_CSUCODE_PING);
   1522 					if (veritefb_read_outfifo_raw(sc,
   1523 					      &word, VFB_FIFOPOLL) == 0 &&
   1524 					    word == VFB_CSUCODE_PING)
   1525 						dd->vd_heartbeat = 0;
   1526 				}
   1527 			}
   1528 			return 0;
   1529 		}
   1530 
   1531 	case VERITEFB_DBG_HOLD:
   1532 		veritefb_risc_hold(sc);
   1533 		return 0;
   1534 
   1535 	case VERITEFB_DBG_CONT:
   1536 		veritefb_risc_continue(sc);
   1537 		return 0;
   1538 
   1539 	case VERITEFB_DBG_RDREG:
   1540 		{
   1541 			struct veritefb_dbg_rw *vr = data;
   1542 
   1543 			if ((vfb_read1(sc, VFB_DEBUG) &
   1544 			    VFB_DEBUG_HOLDRISC) == 0)
   1545 				return EBUSY;	/* hold first */
   1546 			if (vr->vr_addr > 255)
   1547 				return EINVAL;
   1548 			vr->vr_val = veritefb_risc_readrf(sc, vr->vr_addr);
   1549 			return 0;
   1550 		}
   1551 
   1552 	case VERITEFB_DBG_RDMEM:
   1553 		{
   1554 			struct veritefb_dbg_rw *vr = data;
   1555 
   1556 			if ((vfb_read1(sc, VFB_DEBUG) &
   1557 			    VFB_DEBUG_HOLDRISC) == 0)
   1558 				return EBUSY;	/* hold first */
   1559 			vr->vr_val = veritefb_risc_readmem(sc, vr->vr_addr);
   1560 			return 0;
   1561 		}
   1562 
   1563 	case VERITEFB_DBG_FAULT:
   1564 		/*
   1565 		 * Only against the 2D loop
   1566 		 */
   1567 		if (sc->sc_risc_owner != VFB_OWNER_CONSOLE)
   1568 			return EBUSY;
   1569 		aprint_normal_dev(sc->sc_dev,
   1570 		    "debug: deliberately sending an invalid command\n");
   1571 		vfb_fifo_write(sc, VFB_CMDW(0, VFB_CMD_BOGUS));
   1572 		return 0;
   1573 
   1574 	case VERITEFB_DBG_RESET:
   1575 		/* Full recovery includes the console scanout mode. */
   1576 		if (sc->sc_depth != 8)
   1577 			(void)veritefb_set_scan_depth(sc, 8);
   1578 		*(int *)data = veritefb_risc_init(sc) ? 1 : 0;
   1579 		return 0;
   1580 
   1581 	case VERITEFB_DBG_STATS:
   1582 		memcpy(data, &sc->sc_stats, sizeof(sc->sc_stats));
   1583 		return 0;
   1584 
   1585 	case VERITEFB_DBG_STATCLR:
   1586 		memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
   1587 		return 0;
   1588 
   1589 	case VERITEFB_DBG_PCSAMPLE:
   1590 		{
   1591 			struct veritefb_dbg_pcsample *ps = data;
   1592 
   1593 			if (ps->vp_shift >= 32)
   1594 				return EINVAL;
   1595 			sc->sc_pcsample_on = false;
   1596 			callout_stop(&sc->sc_pcsample_ch);
   1597 			/* reset the histogram on every (re)arm */
   1598 			memset(sc->sc_pchist, 0, sizeof(sc->sc_pchist));
   1599 			sc->sc_pchist_samples = 0;
   1600 			sc->sc_pchist_missed = 0;
   1601 			sc->sc_pchist_min = ~0u;
   1602 			sc->sc_pchist_max = 0;
   1603 			if (ps->vp_hz == 0)
   1604 				return 0;	/* stop only */
   1605 			sc->sc_pchist_base = ps->vp_base;
   1606 			sc->sc_pchist_shift = ps->vp_shift;
   1607 			sc->sc_pcsample_hz = ps->vp_hz > (uint32_t)hz ?
   1608 			    (uint32_t)hz : ps->vp_hz;
   1609 			sc->sc_pcsample_on = true;
   1610 			callout_schedule(&sc->sc_pcsample_ch, 1);
   1611 			return 0;
   1612 		}
   1613 
   1614 	case VERITEFB_DBG_PCHIST:
   1615 		{
   1616 			struct veritefb_dbg_pchist *ph = data;
   1617 
   1618 			ph->vp_samples = sc->sc_pchist_samples;
   1619 			ph->vp_missed = sc->sc_pchist_missed;
   1620 			ph->vp_base = sc->sc_pchist_base;
   1621 			ph->vp_shift = sc->sc_pchist_shift;
   1622 			ph->vp_min = sc->sc_pchist_min;
   1623 			ph->vp_max = sc->sc_pchist_max;
   1624 			memcpy(ph->vp_hist, sc->sc_pchist,
   1625 			    sizeof(ph->vp_hist));
   1626 			return 0;
   1627 		}
   1628 
   1629 	case VERITEFB_DBG_RDIO:
   1630 		{
   1631 			struct veritefb_dbg_rw *vr = data;
   1632 
   1633 			if ((vr->vr_addr &
   1634 			    ~(uint32_t)VERITEFB_DBG_IO_IOSPACE) > 0xff)
   1635 				return EINVAL;
   1636 			if (vr->vr_addr & VERITEFB_DBG_IO_IOSPACE)
   1637 				vr->vr_val = bus_space_read_1(sc->sc_iot,
   1638 				    sc->sc_ioh, vr->vr_addr & 0xff);
   1639 			else
   1640 				vr->vr_val = vfb_read1(sc, vr->vr_addr);
   1641 			return 0;
   1642 		}
   1643 
   1644 	case VERITEFB_DBG_WRIO:
   1645 		{
   1646 			struct veritefb_dbg_rw *vr = data;
   1647 
   1648 			if ((vr->vr_addr &
   1649 			    ~(uint32_t)VERITEFB_DBG_IO_IOSPACE) > 0xff)
   1650 				return EINVAL;
   1651 			if (vr->vr_addr & VERITEFB_DBG_IO_IOSPACE)
   1652 				bus_space_write_1(sc->sc_iot, sc->sc_ioh,
   1653 				    vr->vr_addr & 0xff, vr->vr_val);
   1654 			else
   1655 				vfb_write1(sc, vr->vr_addr, vr->vr_val);
   1656 			return 0;
   1657 		}
   1658 
   1659 	/* RISC multiplexing experiment. */
   1660 	case VERITEFB_DBG_SUSPEND2D:
   1661 		if (sc->sc_v3d_open)
   1662 			return EBUSY;	/* /dev/verite3d owns the mux */
   1663 		return veritefb_suspend2d(sc);
   1664 
   1665 	case VERITEFB_DBG_RESUME2D:
   1666 		if (sc->sc_v3d_open)
   1667 			return EBUSY;
   1668 		return veritefb_resume2d(sc);
   1669 
   1670 	case VERITEFB_DBG_UCLOAD:
   1671 		{
   1672 			struct veritefb_dbg_ucload *vu = data;
   1673 			uint8_t *img;
   1674 			uint32_t entry;
   1675 			int error;
   1676 			bool loaded;
   1677 
   1678 			if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL ||
   1679 			    sc->sc_ucode == NULL)
   1680 				return EBUSY;
   1681 			if (vu->vu_size < sizeof(Elf32_Ehdr) ||
   1682 			    vu->vu_size > VFB_MAXUCODE)
   1683 				return EINVAL;
   1684 
   1685 			/* All user-memory access before any hw touch. */
   1686 			img = kmem_alloc(vu->vu_size, KM_SLEEP);
   1687 			error = copyin(vu->vu_data, img, vu->vu_size);
   1688 			if (error != 0) {
   1689 				kmem_free(img, vu->vu_size);
   1690 				return error;
   1691 			}
   1692 
   1693 			/*
   1694 			 * Write the image while the 2D blob still runs
   1695 			 */
   1696 			loaded = veritefb_ucode_load(sc, img, vu->vu_size,
   1697 			    VFB_UCF_BASE, VFB_UCF_END, false, &entry);
   1698 			kmem_free(img, vu->vu_size);
   1699 			if (!loaded)
   1700 				return EINVAL;
   1701 			if (!veritefb_risc_init(sc))
   1702 				return EIO;
   1703 			vu->vu_entry = entry;
   1704 			return 0;
   1705 		}
   1706 
   1707 	case VERITEFB_DBG_FIFOWR:
   1708 		{
   1709 			struct veritefb_dbg_fifowr *vf = data;
   1710 			uint32_t i;
   1711 			int error;
   1712 
   1713 			if (sc->sc_risc_owner == VFB_OWNER_CONSOLE ||
   1714 			    sc->sc_accel == VFB_ACCEL_SW)
   1715 				return EBUSY;
   1716 			if (vf->vf_count < 1 ||
   1717 			    vf->vf_count > VFB_DBG_FIFO_MAX)
   1718 				return EINVAL;
   1719 			if (vf->vf_setowner != VERITEFB_SETOWNER_KEEP &&
   1720 			    vf->vf_setowner != VFB_OWNER_PARKED &&
   1721 			    vf->vf_setowner != VFB_OWNER_FOREIGN)
   1722 				return EINVAL;
   1723 
   1724 			/* PIO into the FIFO: settle any DBG DMA first */
   1725 			(void)veritefb_dma_drain(sc);
   1726 			error = veritefb_waitfifo_raw(sc, vf->vf_count,
   1727 			    VFB_FIFOPOLL);
   1728 			if (error != 0)
   1729 				return error;
   1730 			for (i = 0; i < vf->vf_count; i++)
   1731 				vfb_fifo_write(sc, vf->vf_words[i]);
   1732 			if (vf->vf_setowner != VERITEFB_SETOWNER_KEEP)
   1733 				sc->sc_risc_owner = vf->vf_setowner;
   1734 			return 0;
   1735 		}
   1736 
   1737 	case VERITEFB_DBG_FIFORD:
   1738 		{
   1739 			struct veritefb_dbg_fiford *vf = data;
   1740 
   1741 			if (sc->sc_risc_owner == VFB_OWNER_CONSOLE)
   1742 				return EBUSY;
   1743 			return veritefb_read_outfifo_raw(sc, &vf->vf_word,
   1744 			    MIN(vf->vf_timo_us, VFB_FIFOPOLL));
   1745 		}
   1746 
   1747 	case VERITEFB_DBG_SETDEPTH:
   1748 		/* Never yank the scanout under the live console. */
   1749 		if (sc->sc_risc_owner == VFB_OWNER_CONSOLE ||
   1750 		    sc->sc_v3d_open)
   1751 			return EBUSY;
   1752 		return veritefb_set_scan_depth(sc,
   1753 		    (int)*(const uint32_t *)data);
   1754 
   1755 	case VERITEFB_DBG_DMASUBMIT:
   1756 		{
   1757 			struct veritefb_dbg_dma *vdd = data;
   1758 			int error;
   1759 
   1760 			/* exclusion rule: no console PIO while DMABusy */
   1761 			if (sc->sc_risc_owner == VFB_OWNER_CONSOLE ||
   1762 			    sc->sc_v3d_open)
   1763 				return EBUSY;
   1764 			if (vdd->vd_len == 0 ||
   1765 			    vdd->vd_len > VFB_DMA_BOUNCE ||
   1766 			    (vdd->vd_len & 3) != 0 || vdd->vd_swap > 3)
   1767 				return EINVAL;
   1768 			error = veritefb_dma_alloc(sc);
   1769 			if (error)
   1770 				return error;
   1771 			error = copyin((const void *)(uintptr_t)vdd->vd_buf,
   1772 			    sc->sc_dma_buf, vdd->vd_len);
   1773 			if (error)
   1774 				return error;
   1775 			return veritefb_dma_submit(sc, sc->sc_dma_buf_map,
   1776 			    vdd->vd_len, vdd->vd_swap);
   1777 		}
   1778 
   1779 	case VERITEFB_DBG_RDVRAM:
   1780 		{
   1781 			struct veritefb_dbg_rw *vr = data;
   1782 			uint8_t memendian;
   1783 
   1784 			if (vr->vr_addr >= VFB_MC_SIZE ||
   1785 			    (vr->vr_addr & 3) != 0)
   1786 				return EINVAL;
   1787 			memendian = vfb_read1(sc, VFB_MEMENDIAN);
   1788 			vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
   1789 			vr->vr_val = vfb_fb_read4(sc, vr->vr_addr);
   1790 			vfb_write1(sc, VFB_MEMENDIAN, memendian);
   1791 			return 0;
   1792 		}
   1793 
   1794 #endif /* VERITEFB_DEBUG */
   1795 	}
   1796 	return EPASSTHROUGH;
   1797 }
   1798 
   1799 static paddr_t
   1800 veritefb_mmap(void *v, void *vs, off_t offset, int prot)
   1801 {
   1802 	struct vcons_data *vd;
   1803 	struct veritefb_softc *sc;
   1804 
   1805 	vd = v;
   1806 	sc = vd->cookie;
   1807 
   1808 	if (offset >= 0 && offset < sc->sc_memsize - sc->sc_fb_offset)
   1809 		return bus_space_mmap(sc->sc_memt,
   1810 		    sc->sc_fb_paddr + sc->sc_fb_offset + offset,
   1811 		    0, prot, BUS_SPACE_MAP_LINEAR);
   1812 
   1813 	return -1;
   1814 }
   1815 
   1816 static void
   1817 veritefb_risc_continue(struct veritefb_softc *sc)
   1818 {
   1819 	uint8_t debugreg;
   1820 
   1821 	debugreg = vfb_read1(sc, VFB_DEBUG);
   1822 	vfb_write1(sc, VFB_DEBUG, debugreg & ~VFB_DEBUG_HOLDRISC);
   1823 	vfb_pacepoll4(sc, VFB_STATEDATA, 0, 0);
   1824 }
   1825 
   1826 /*
   1827  * Force one instruction into the RISC decoder and single-step it
   1828  */
   1829 static void
   1830 veritefb_risc_forcestep(struct veritefb_softc *sc, uint32_t insn)
   1831 {
   1832 	uint8_t debugreg, stateindex;
   1833 	int i;
   1834 
   1835 	debugreg = vfb_read1(sc, VFB_DEBUG);
   1836 	stateindex = vfb_read1(sc, VFB_STATEINDEX);
   1837 
   1838 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_IR);
   1839 	vfb_pacepoll1(sc, VFB_STATEINDEX, VFB_STATEINDEX_IR, 0xff);
   1840 	vfb_write4(sc, VFB_STATEDATA, insn);
   1841 	vfb_pacepoll4(sc, VFB_STATEDATA, insn, 0xffffffff);
   1842 	vfb_write1(sc, VFB_DEBUG,
   1843 	    debugreg | VFB_DEBUG_HOLDRISC | VFB_DEBUG_STEPRISC);
   1844 	vfb_pacepoll4(sc, VFB_STATEDATA, 0, 0);
   1845 
   1846 	for (i = 0; i < VFB_SHORTPOLL; i++)
   1847 		if ((vfb_read1(sc, VFB_DEBUG) &
   1848 		    (VFB_DEBUG_HOLDRISC | VFB_DEBUG_STEPRISC)) ==
   1849 		    VFB_DEBUG_HOLDRISC)
   1850 			break;
   1851 
   1852 	vfb_write1(sc, VFB_STATEINDEX, stateindex);
   1853 }
   1854 
   1855 /*
   1856  * Set a register-file entry by force-feeding load-immediate sequences
   1857  */
   1858 static void
   1859 veritefb_risc_writerf(struct veritefb_softc *sc, uint8_t idx, uint32_t data)
   1860 {
   1861 	uint8_t special = 0;
   1862 
   1863 	if (idx < 64) {
   1864 		special = idx;
   1865 		idx = VRISC_SP;
   1866 	}
   1867 
   1868 	if ((data & 0xff000000) == 0) {
   1869 		veritefb_risc_forcestep(sc,
   1870 		    VRISC_LI(VRISC_LI_OP, idx, data & 0xffff));
   1871 		if (data & 0x00ff0000)
   1872 			veritefb_risc_forcestep(sc,
   1873 			    VRISC_INT(VRISC_ADDIFI_OP, idx, idx, data >> 16));
   1874 	} else {
   1875 		veritefb_risc_forcestep(sc,
   1876 		    VRISC_LI(VRISC_LUI_OP, idx, data >> 16));
   1877 		veritefb_risc_forcestep(sc,
   1878 		    VRISC_INT(VRISC_ADDSL8_OP, idx, idx, (data >> 8) & 0xff));
   1879 		veritefb_risc_forcestep(sc,
   1880 		    VRISC_INT(VRISC_ADDI_OP, idx, idx, data & 0xff));
   1881 	}
   1882 
   1883 	if (special) {
   1884 		veritefb_risc_forcestep(sc,
   1885 		    VRISC_INT(VRISC_ADD_OP, special, 0, VRISC_SP));
   1886 		veritefb_risc_forcestep(sc, VRISC_NOP);
   1887 		veritefb_risc_forcestep(sc, VRISC_NOP);
   1888 		veritefb_risc_forcestep(sc, VRISC_NOP);
   1889 	}
   1890 }
   1891 
   1892 /* Read a register-file entry through the S1 operand bus */
   1893 static uint32_t
   1894 veritefb_risc_readrf(struct veritefb_softc *sc, uint8_t idx)
   1895 {
   1896 	uint32_t data, insn;
   1897 	uint8_t debugreg, stateindex;
   1898 
   1899 	debugreg = vfb_read1(sc, VFB_DEBUG);
   1900 	stateindex = vfb_read1(sc, VFB_STATEINDEX);
   1901 
   1902 	vfb_write1(sc, VFB_DEBUG, debugreg | VFB_DEBUG_HOLDRISC);
   1903 
   1904 	/* add zero, zero, idx: puts RF[idx] on the S1 bus, no step needed */
   1905 	insn = VRISC_INT(VRISC_ADD_OP, 0, 0, idx);
   1906 	vfb_write4(sc, VFB_STATEDATA, insn);
   1907 
   1908 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_IR);
   1909 	vfb_pacepoll4(sc, VFB_STATEDATA, insn, 0xffffffff);
   1910 
   1911 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_S1);
   1912 	vfb_pacepoll4(sc, VFB_STATEINDEX, 0, 0);
   1913 	data = vfb_read4(sc, VFB_STATEDATA);
   1914 
   1915 	vfb_write1(sc, VFB_STATEINDEX, stateindex);
   1916 	vfb_write1(sc, VFB_DEBUG, debugreg);
   1917 
   1918 	return data;
   1919 }
   1920 
   1921 /* Word read/write through the RISC's own address space, RISC held. */
   1922 static uint32_t
   1923 veritefb_risc_readmem(struct veritefb_softc *sc, uint32_t addr)
   1924 {
   1925 	veritefb_risc_writerf(sc, VRISC_RA, addr);
   1926 	veritefb_risc_forcestep(sc, VRISC_LD(VRISC_LW_OP, VRISC_SP, 0,
   1927 	    VRISC_RA));
   1928 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1929 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1930 	return veritefb_risc_readrf(sc, VRISC_SP);
   1931 }
   1932 
   1933 static void
   1934 veritefb_risc_writemem(struct veritefb_softc *sc, uint32_t addr,
   1935     uint32_t data)
   1936 {
   1937 	veritefb_risc_writerf(sc, VRISC_RA, addr);
   1938 	veritefb_risc_writerf(sc, VRISC_FP, data);
   1939 	veritefb_risc_forcestep(sc, VRISC_ST(VRISC_SW_OP, 0, VRISC_FP,
   1940 	    VRISC_RA));
   1941 }
   1942 
   1943 /*
   1944  * Flush the icache (and the pixel-engine line buffers in the
   1945  * dcache), returns with the icache enabled.
   1946  */
   1947 static void
   1948 veritefb_risc_flushicache(struct veritefb_softc *sc)
   1949 {
   1950 	uint32_t c, p1, p2;
   1951 
   1952 	/* flush store accumulation buffers */
   1953 	p1 = veritefb_risc_readmem(sc, 0);
   1954 	p2 = veritefb_risc_readmem(sc, 8);
   1955 	veritefb_risc_writemem(sc, 0, p1);
   1956 	veritefb_risc_writemem(sc, 8, p2);
   1957 	(void)veritefb_risc_readmem(sc, 0);
   1958 	(void)veritefb_risc_readmem(sc, 8);
   1959 
   1960 	/* spri Sync, zero: flush pixel-engine line buffers */
   1961 	veritefb_risc_forcestep(sc, VRISC_INT(VRISC_SPRI_OP, 0, 0, 31));
   1962 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1963 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1964 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1965 
   1966 	/* set icache-off bits in the flag register */
   1967 	veritefb_risc_writerf(sc, VRISC_RA, VRISC_ICACHE_ONOFF_MASK);
   1968 	veritefb_risc_forcestep(sc,
   1969 	    VRISC_INT(VRISC_OR_OP, VRISC_FLAG, VRISC_FLAG, VRISC_RA));
   1970 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1971 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1972 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1973 
   1974 	/* jump through two icache's worth of lines to flush it */
   1975 	for (c = 0; c < VRISC_ICACHESIZE * 2; c += VRISC_ICACHELINESIZE)
   1976 		veritefb_risc_forcestep(sc, VRISC_JMP(c >> 2));
   1977 
   1978 	/* clear the icache-off bits again */
   1979 	veritefb_risc_writerf(sc, VRISC_RA, VRISC_ICACHE_ONOFF_MASK);
   1980 	veritefb_risc_forcestep(sc,
   1981 	    VRISC_INT(VRISC_ANDN_OP, VRISC_FLAG, VRISC_FLAG, VRISC_RA));
   1982 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1983 	veritefb_risc_forcestep(sc, VRISC_JMP(0));
   1984 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1985 }
   1986 
   1987 /*
   1988  * Start the RISC at pc: hold it, force-feed a jump (with NOPs for the
   1989  * pipeline and the delay slot), release.
   1990  */
   1991 static void
   1992 veritefb_risc_start(struct veritefb_softc *sc, uint32_t pc)
   1993 {
   1994 	veritefb_risc_hold(sc);
   1995 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1996 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1997 	veritefb_risc_forcestep(sc, VRISC_NOP);
   1998 	veritefb_risc_forcestep(sc, VRISC_JMP(pc >> 2));
   1999 	veritefb_risc_forcestep(sc, VRISC_NOP);
   2000 	veritefb_risc_continue(sc);
   2001 }
   2002 
   2003 /*
   2004  * Sample the RISC program counter.
   2005  */
   2006 static uint32_t
   2007 veritefb_risc_samplepc(struct veritefb_softc *sc)
   2008 {
   2009 	uint32_t pc;
   2010 	uint8_t debugreg, stateindex;
   2011 	bool washeld;
   2012 
   2013 	debugreg = vfb_read1(sc, VFB_DEBUG);
   2014 	washeld = (debugreg & VFB_DEBUG_HOLDRISC) != 0;
   2015 	if (!washeld)
   2016 		veritefb_risc_hold(sc);
   2017 
   2018 	stateindex = vfb_read1(sc, VFB_STATEINDEX);
   2019 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC);
   2020 	vfb_pacepoll1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC, 0xff);
   2021 	pc = vfb_read4(sc, VFB_STATEDATA);
   2022 	vfb_write1(sc, VFB_STATEINDEX, stateindex);
   2023 
   2024 	if (!washeld)
   2025 		veritefb_risc_continue(sc);
   2026 	return pc;
   2027 }
   2028 
   2029 #ifdef VERITEFB_DEBUG
   2030 #define VFB_PCSAMPLE_POLL	200	/* us budget to confirm a sampling hold */
   2031 /*
   2032  * Lightweight PC sampler for the profiler callout.
   2033  */
   2034 static bool
   2035 veritefb_risc_samplepc_fast(struct veritefb_softc *sc, uint32_t *pcp)
   2036 {
   2037 	uint8_t debugreg, stateindex;
   2038 	bool washeld;
   2039 	int i;
   2040 
   2041 	debugreg = vfb_read1(sc, VFB_DEBUG);
   2042 	washeld = (debugreg & VFB_DEBUG_HOLDRISC) != 0;
   2043 	if (!washeld) {
   2044 		vfb_write1(sc, VFB_DEBUG, debugreg | VFB_DEBUG_HOLDRISC);
   2045 		for (i = 0; i < VFB_PCSAMPLE_POLL; i++) {
   2046 			if (vfb_read1(sc, VFB_STATUS) & VFB_STATUS_HELD)
   2047 				break;
   2048 			delay(1);
   2049 		}
   2050 		if (i == VFB_PCSAMPLE_POLL) {
   2051 			veritefb_risc_continue(sc);	/* did not halt - skip */
   2052 			return false;
   2053 		}
   2054 	}
   2055 
   2056 	stateindex = vfb_read1(sc, VFB_STATEINDEX);
   2057 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC);
   2058 	vfb_pacepoll1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC, 0xff);
   2059 	*pcp = vfb_read4(sc, VFB_STATEDATA);
   2060 	vfb_write1(sc, VFB_STATEINDEX, stateindex);
   2061 
   2062 	if (!washeld)
   2063 		veritefb_risc_continue(sc);
   2064 	return true;
   2065 }
   2066 
   2067 /*
   2068  * RISC PC sampling profiler callout.
   2069  */
   2070 static void
   2071 veritefb_pcsample_tick(void *arg)
   2072 {
   2073 	struct veritefb_softc *sc = arg;
   2074 	uint32_t pc;
   2075 	int ticks;
   2076 
   2077 	if (!sc->sc_pcsample_on)
   2078 		return;
   2079 	if (sc->sc_risc_owner == VFB_OWNER_FOREIGN && sc->sc_v3d_open &&
   2080 	    veritefb_risc_samplepc_fast(sc, &pc)) {
   2081 		sc->sc_pchist_samples++;
   2082 		if (pc < sc->sc_pchist_min)
   2083 			sc->sc_pchist_min = pc;
   2084 		if (pc > sc->sc_pchist_max)
   2085 			sc->sc_pchist_max = pc;
   2086 		if (pc >= sc->sc_pchist_base) {
   2087 			uint32_t b = (pc - sc->sc_pchist_base) >>
   2088 			    sc->sc_pchist_shift;
   2089 
   2090 			if (b < VFB_PCHIST_BUCKETS)
   2091 				sc->sc_pchist[b]++;
   2092 			else
   2093 				sc->sc_pchist_missed++;
   2094 		} else
   2095 			sc->sc_pchist_missed++;
   2096 	}
   2097 
   2098 	ticks = hz / sc->sc_pcsample_hz;
   2099 	if (ticks < 1)
   2100 		ticks = 1;
   2101 	callout_schedule(&sc->sc_pcsample_ch, ticks);
   2102 }
   2103 #endif /* VERITEFB_DEBUG */
   2104 
   2105 /*
   2106  * The hang-signature catalog: classify a sampled PC against the known
   2107  * layout of the V2x00 2D blob (loaded at its link address).
   2108  */
   2109 static const char *
   2110 veritefb_pc_signature(uint32_t pc)
   2111 {
   2112 	if (pc >= VFB_UC_TRAP && pc < VFB_UC_TRAP_END)
   2113 		return "invalid-command trap (host sent a bad command or "
   2114 		    "the stream desynced)";
   2115 	if (pc >= VFB_UC_BASE && pc <= VFB_UC_DISPATCH_END)
   2116 		return "dispatch loop (idle, waiting for commands)";
   2117 	if (pc >= VFB_CSUCODE_BASE && pc < VFB_UC_BASE)
   2118 		return "csucode monitor (parked/suspended)";
   2119 	if (pc >= VFB_UC_BASE && pc < VFB_UC_END)
   2120 		return "inside a command handler";
   2121 	if (pc >= VFB_UCF_BASE && pc < VFB_UCF_END)
   2122 		return "foreign ucode region";
   2123 	if (pc >= VFB_RISC_ROM_BASE)
   2124 		return "boot ROM region";
   2125 	return "unknown region";
   2126 }
   2127 
   2128 /*
   2129  * Permanently degrade to software rendering, duh.
   2130  */
   2131 static void
   2132 veritefb_accel_fail(struct veritefb_softc *sc, const char *what)
   2133 {
   2134 	uint32_t pc;
   2135 #ifdef VERITEFB_DEBUG
   2136 	unsigned i, n;
   2137 #endif
   2138 
   2139 	if (sc->sc_accel == VFB_ACCEL_SW)
   2140 		return;
   2141 
   2142 	/* never hold the RISC mid-DMA */
   2143 	(void)veritefb_dma_drain(sc);
   2144 
   2145 	sc->sc_accel = VFB_ACCEL_SW;
   2146 	sc->sc_unsynced = 0;
   2147 	sc->sc_unsynced_area = 0;
   2148 	pc = veritefb_risc_samplepc(sc);
   2149 	aprint_error_dev(sc->sc_dev,
   2150 	    "%s; disabling acceleration until reboot\n", what);
   2151 	aprint_error_dev(sc->sc_dev, "RISC PC 0x%08x: %s\n", pc,
   2152 	    veritefb_pc_signature(pc));
   2153 
   2154 #ifdef VERITEFB_DEBUG
   2155 	n = MIN(sc->sc_ring_count, 8);
   2156 	for (i = 0; i < n; i++)
   2157 		aprint_error_dev(sc->sc_dev, "  fifo[-%u] = 0x%08x\n",
   2158 		    n - i, sc->sc_ring[(sc->sc_ring_count - n + i) &
   2159 		    (VFB_RING_SIZE - 1)]);
   2160 #endif
   2161 
   2162 	veritefb_risc_hold(sc);
   2163 }
   2164 
   2165 /* wait for n free input FIFO entries */
   2166 static int
   2167 veritefb_waitfifo(struct veritefb_softc *sc, int n)
   2168 {
   2169 	int i;
   2170 
   2171 	for (i = 0; i < VFB_FIFOPOLL; i++) {
   2172 		if ((vfb_read1(sc, VFB_FIFOINFREE) & VFB_FIFOINFREE_MASK) >=
   2173 		    n)
   2174 			return 0;
   2175 		delay(1);
   2176 	}
   2177 	veritefb_accel_fail(sc, "input FIFO timeout");
   2178 	return EBUSY;
   2179 }
   2180 
   2181 /* Discard stale output FIFO words. */
   2182 static int
   2183 veritefb_drain_outfifo(struct veritefb_softc *sc)
   2184 {
   2185 	int i;
   2186 
   2187 	for (i = 0; i < VFB_FIFOPOLL; i++) {
   2188 		if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   2189 		    VFB_FIFOOUTVALID_MASK) == 0)
   2190 			return 0;
   2191 		(void)vfb_fifo_read(sc);
   2192 	}
   2193 	veritefb_accel_fail(sc, "output FIFO never drained");
   2194 	return EBUSY;
   2195 }
   2196 
   2197 /* Wait for one word from the output FIFO. */
   2198 static int
   2199 veritefb_read_outfifo(struct veritefb_softc *sc, uint32_t *wordp)
   2200 {
   2201 	int i;
   2202 
   2203 	for (i = 0; i < VFB_FIFOPOLL; i++) {
   2204 		if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   2205 		    VFB_FIFOOUTVALID_MASK) != 0) {
   2206 			*wordp = vfb_fifo_read(sc);
   2207 			return 0;
   2208 		}
   2209 		delay(1);
   2210 	}
   2211 	veritefb_accel_fail(sc, "output FIFO timeout");
   2212 	return EBUSY;
   2213 }
   2214 
   2215 /*
   2216  * Copy an ELF microcode image into its VRAM slot
   2217  */
   2218 static bool
   2219 veritefb_ucode_load(struct veritefb_softc *sc, const uint8_t *u,
   2220     size_t size, uint32_t lo, uint32_t hi, bool install_csucode,
   2221     uint32_t *entryp)
   2222 {
   2223 	uint32_t entry, phoff, filesz, memsz, off, paddr, word;
   2224 	uint16_t phentsize, phnum, ph;
   2225 	uint8_t memendian;
   2226 	size_t i;
   2227 
   2228 	if (size < sizeof(Elf32_Ehdr) ||
   2229 	    memcmp(u, ELFMAG, SELFMAG) != 0 ||
   2230 	    u[EI_CLASS] != ELFCLASS32 || u[EI_DATA] != ELFDATA2MSB) {
   2231 		aprint_error_dev(sc->sc_dev, "microcode is not a "
   2232 		    "big-endian ELF32 image\n");
   2233 		return false;
   2234 	}
   2235 
   2236 	entry = be32dec(u + offsetof(Elf32_Ehdr, e_entry));
   2237 	phoff = be32dec(u + offsetof(Elf32_Ehdr, e_phoff));
   2238 	phentsize = be16dec(u + offsetof(Elf32_Ehdr, e_phentsize));
   2239 	phnum = be16dec(u + offsetof(Elf32_Ehdr, e_phnum));
   2240 
   2241 	if (phnum == 0 || phentsize < sizeof(Elf32_Phdr) ||
   2242 	    (uint64_t)phoff + (uint64_t)phnum * phentsize > size) {
   2243 		aprint_error_dev(sc->sc_dev,
   2244 		    "microcode program headers out of bounds\n");
   2245 		return false;
   2246 	}
   2247 
   2248 	if (entry < lo || entry >= hi) {
   2249 		aprint_error_dev(sc->sc_dev,
   2250 		    "microcode entry 0x%x outside slot [0x%x, 0x%x)\n",
   2251 		    entry, lo, hi);
   2252 		return false;
   2253 	}
   2254 
   2255 	memendian = vfb_read1(sc, VFB_MEMENDIAN);
   2256 	vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
   2257 
   2258 	if (install_csucode) {
   2259 		/* Context-switch monitor and its semaphores. */
   2260 		for (i = 0; i < __arraycount(veritefb_csucode); i++)
   2261 			vfb_fb_write4(sc, VFB_CSUCODE_BASE + i * 4,
   2262 			    veritefb_csucode[i]);
   2263 		vfb_fb_write4(sc, VFB_CSUCODE_SEM0, 0);
   2264 		vfb_fb_write4(sc, VFB_CSUCODE_SEM1, 0);
   2265 	}
   2266 
   2267 	for (ph = 0; ph < phnum; ph++) {
   2268 		const uint8_t *p = u + phoff + (uint32_t)ph * phentsize;
   2269 
   2270 		if (be32dec(p + offsetof(Elf32_Phdr, p_type)) != PT_LOAD)
   2271 			continue;
   2272 		off = be32dec(p + offsetof(Elf32_Phdr, p_offset));
   2273 		filesz = be32dec(p + offsetof(Elf32_Phdr, p_filesz));
   2274 		memsz = be32dec(p + offsetof(Elf32_Phdr, p_memsz));
   2275 		paddr = be32dec(p + offsetof(Elf32_Phdr, p_paddr));
   2276 
   2277 		if (memsz < filesz ||
   2278 		    (uint64_t)off + filesz > size ||
   2279 		    paddr < lo || (paddr & 3) != 0 ||
   2280 		    (uint64_t)paddr + roundup(memsz, 4) > hi) {
   2281 			aprint_error_dev(sc->sc_dev,
   2282 			    "microcode segment out of bounds "
   2283 			    "(paddr 0x%x filesz 0x%x memsz 0x%x)\n",
   2284 			    paddr, filesz, memsz);
   2285 			vfb_write1(sc, VFB_MEMENDIAN, memendian);
   2286 			return false;
   2287 		}
   2288 
   2289 		for (i = 0; i + 4 <= filesz; i += 4)
   2290 			vfb_fb_write4(sc, paddr + i, be32dec(u + off + i));
   2291 		if (i < filesz) {
   2292 			word = 0;
   2293 			for (; i < filesz; i++)
   2294 				word = (word << 8) | u[off + i];
   2295 			word <<= 8 * (4 - (filesz & 3));
   2296 			vfb_fb_write4(sc, paddr + (filesz & ~3U), word);
   2297 			i = (filesz & ~3U) + 4;
   2298 		}
   2299 		/* Zero the bss tail. */
   2300 		for (; i < memsz; i += 4)
   2301 			vfb_fb_write4(sc, paddr + i, 0);
   2302 	}
   2303 
   2304 	vfb_write1(sc, VFB_MEMENDIAN, memendian);
   2305 	*entryp = entry;
   2306 	return true;
   2307 }
   2308 
   2309 /*
   2310  * Full RISC bring-up:
   2311  * - load microcode
   2312  * - start the csucode monitor
   2313  * - feed it the init sequence
   2314  * - validate the command protocol
   2315  */
   2316 static bool
   2317 veritefb_risc_init(struct veritefb_softc *sc)
   2318 {
   2319 
   2320 	/*
   2321 	 * Settle any in-flight DMA first!
   2322 	 */
   2323 	(void)veritefb_dma_drain(sc);
   2324 
   2325 	if (sc->sc_ucode == NULL)
   2326 		return false;
   2327 
   2328 	sc->sc_accel = VFB_ACCEL_OFF;
   2329 	sc->sc_risc_owner = VFB_OWNER_CONSOLE;
   2330 
   2331 	veritefb_risc_hold(sc);
   2332 	if (!veritefb_ucode_load(sc, sc->sc_ucode, sc->sc_ucode_size,
   2333 	    VFB_UC2D_LO, VFB_UC2D_HI, true, &sc->sc_ucode_entry))
   2334 		return false;
   2335 
   2336 	/*
   2337 	 * same VRAM words read through the host aperture and through
   2338 	 * injected RISC loads must agree
   2339 	 */
   2340 	{
   2341 		static const uint32_t testaddr[] =
   2342 		    { VFB_UC_BASE, VFB_CSUCODE_BASE };
   2343 		uint32_t hostv, riscv;
   2344 		uint8_t memendian;
   2345 		size_t t;
   2346 
   2347 		memendian = vfb_read1(sc, VFB_MEMENDIAN);
   2348 		vfb_write1(sc, VFB_MEMENDIAN, VFB_MEMENDIAN_NO);
   2349 		for (t = 0; t < __arraycount(testaddr); t++) {
   2350 			hostv = vfb_fb_read4(sc, testaddr[t]);
   2351 			riscv = veritefb_risc_readmem(sc, testaddr[t]);
   2352 			if (hostv != riscv) {
   2353 				vfb_write1(sc, VFB_MEMENDIAN, memendian);
   2354 				aprint_error_dev(sc->sc_dev,
   2355 				    "dual-view self-test failed @0x%x: "
   2356 				    "host 0x%08x vs RISC 0x%08x\n",
   2357 				    testaddr[t], hostv, riscv);
   2358 				return false;
   2359 			}
   2360 		}
   2361 		vfb_write1(sc, VFB_MEMENDIAN, memendian);
   2362 		aprint_debug_dev(sc->sc_dev, "dual-view self-test passed\n");
   2363 	}
   2364 
   2365 	veritefb_risc_flushicache(sc);
   2366 	veritefb_risc_start(sc, VFB_CSUCODE_BASE);
   2367 
   2368 	if (veritefb_waitfifo(sc, 4) != 0)
   2369 		return false;
   2370 	vfb_fifo_write(sc, VFB_CSUCODE_INIT);
   2371 	vfb_fifo_write(sc, 0);		/* context store area */
   2372 	vfb_fifo_write(sc, 0);
   2373 	vfb_fifo_write(sc, sc->sc_ucode_entry);
   2374 
   2375 	if (!veritefb_2d_handshake(sc))
   2376 		return false;
   2377 
   2378 	aprint_normal_dev(sc->sc_dev,
   2379 	    "RISC running 2D microcode (entry 0x%x), handshake passed\n",
   2380 	    sc->sc_ucode_entry);
   2381 	return true;
   2382 }
   2383 
   2384 /*
   2385  * Post-start validation and pixel-engine setup
   2386  */
   2387 static bool
   2388 veritefb_2d_handshake(struct veritefb_softc *sc)
   2389 {
   2390 	uint32_t word, saved;
   2391 
   2392 	if (veritefb_drain_outfifo(sc) != 0)
   2393 		return false;
   2394 	if (veritefb_waitfifo(sc, 1) != 0)
   2395 		return false;
   2396 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_PIXENGSYNC));
   2397 	if (veritefb_read_outfifo(sc, &word) != 0)
   2398 		return false;
   2399 	if (word != VFB_SYNC_TOKEN) {
   2400 		veritefb_accel_fail(sc, "bad sync token from microcode");
   2401 		return false;
   2402 	}
   2403 
   2404 	if (veritefb_waitfifo(sc, 6) != 0)
   2405 		return false;
   2406 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_SETUP));
   2407 	/*
   2408 	 * Word 1 programs the pixel-engine scissor.
   2409 	 * It MUST span the whole VRAM working area.
   2410 	 */
   2411 	vfb_fifo_write(sc, VFB_P2(sc->sc_width,
   2412 	    (sc->sc_memsize - sc->sc_fb_offset) / sc->sc_linebytes));
   2413 	vfb_fifo_write(sc, VFB_P2(sc->sc_depth, VFB_PIXFMT_8I));
   2414 	vfb_fifo_write(sc, (uint32_t)sc->sc_fb_offset);
   2415 	vfb_fifo_write(sc, sc->sc_linebytes);
   2416 	vfb_fifo_write(sc, ((uint32_t)sc->sc_stride1 << 12) |
   2417 	    ((uint32_t)sc->sc_stride0 << 8));
   2418 
   2419 	/* Second sync proves Setup consumed exactly six words. */
   2420 	if (veritefb_waitfifo(sc, 1) != 0)
   2421 		return false;
   2422 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_PIXENGSYNC));
   2423 	if (veritefb_read_outfifo(sc, &word) != 0)
   2424 		return false;
   2425 	if (word != VFB_SYNC_TOKEN) {
   2426 		veritefb_accel_fail(sc, "FIFO desync after Setup");
   2427 		return false;
   2428 	}
   2429 
   2430 	/*
   2431 	 * GetPixel round-trip: place the same magic byte in the first
   2432 	 * four framebuffer pixels through the aperture (immune to the
   2433 	 * MEMENDIAN byte-lane setting) and ask the RISC for pixel (0,0).
   2434 	 */
   2435 	saved = vfb_fb_read4(sc, sc->sc_fb_offset);
   2436 	vfb_fb_write4(sc, sc->sc_fb_offset, VFB_GETPIXEL_PATTERN);
   2437 	if (veritefb_waitfifo(sc, 2) != 0)
   2438 		return false;
   2439 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_GETPIXEL));
   2440 	vfb_fifo_write(sc, VFB_P2(0, 0));
   2441 	if (veritefb_read_outfifo(sc, &word) != 0)
   2442 		return false;
   2443 	vfb_fb_write4(sc, sc->sc_fb_offset, saved);
   2444 	if ((word & 0xff) != (VFB_GETPIXEL_PATTERN & 0xff)) {
   2445 		veritefb_accel_fail(sc, "GetPixel round-trip mismatch");
   2446 		return false;
   2447 	}
   2448 
   2449 	sc->sc_accel = VFB_ACCEL_ON;
   2450 	sc->sc_unsynced = 0;
   2451 	sc->sc_unsynced_area = 0;
   2452 	return true;
   2453 }
   2454 
   2455 static int
   2456 veritefb_waitfifo_raw(struct veritefb_softc *sc, int n, uint32_t timo_us)
   2457 {
   2458 	uint32_t i;
   2459 
   2460 	for (i = 0; i < timo_us; i++) {
   2461 		if ((vfb_read1(sc, VFB_FIFOINFREE) & VFB_FIFOINFREE_MASK) >=
   2462 		    n)
   2463 			return 0;
   2464 		delay(1);
   2465 	}
   2466 	return ETIMEDOUT;
   2467 }
   2468 
   2469 static int
   2470 veritefb_read_outfifo_raw(struct veritefb_softc *sc, uint32_t *wordp,
   2471     uint32_t timo_us)
   2472 {
   2473 	uint32_t i;
   2474 
   2475 	for (i = 0; i < timo_us; i++) {
   2476 		if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   2477 		    VFB_FIFOOUTVALID_MASK) != 0) {
   2478 			*wordp = vfb_fifo_read(sc);
   2479 			return 0;
   2480 		}
   2481 		delay(1);
   2482 	}
   2483 	return ETIMEDOUT;
   2484 }
   2485 
   2486 /* Park the 2D microcode in the csucode monitor. */
   2487 static int
   2488 veritefb_suspend2d(struct veritefb_softc *sc)
   2489 {
   2490 	uint32_t word;
   2491 
   2492 	if (sc->sc_accel != VFB_ACCEL_ON ||
   2493 	    sc->sc_mode != WSDISPLAYIO_MODE_EMUL ||
   2494 	    sc->sc_risc_owner != VFB_OWNER_CONSOLE)
   2495 		return EBUSY;
   2496 
   2497 	/* PIO FIFO words follow */
   2498 	(void)veritefb_dma_drain(sc);
   2499 
   2500 	/*
   2501 	 * Console text ops fall back to software from here on
   2502 	 */
   2503 	sc->sc_accel = VFB_ACCEL_OFF;
   2504 	sc->sc_risc_owner = VFB_OWNER_PARKED;
   2505 	sc->sc_unsynced = 0;
   2506 	sc->sc_unsynced_area = 0;
   2507 
   2508 	/*
   2509 	 * Pixel engine MUST be idle before another microcode
   2510 	 * takes over...
   2511 	 */
   2512 	if (veritefb_drain_outfifo(sc) != 0 ||
   2513 	    veritefb_waitfifo(sc, 2) != 0)
   2514 		goto fail;
   2515 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_PIXENGSYNC));
   2516 	if (veritefb_read_outfifo(sc, &word) != 0 ||
   2517 	    word != VFB_SYNC_TOKEN)
   2518 		goto fail;
   2519 
   2520 	/* Blob saves its state and parks. */
   2521 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_SUSPEND));
   2522 
   2523 	/* Only the monitor echoes pings */
   2524 	if (veritefb_waitfifo(sc, 1) != 0)
   2525 		goto fail;
   2526 	vfb_fifo_write(sc, VFB_CSUCODE_PING);
   2527 	if (veritefb_read_outfifo(sc, &word) != 0 ||
   2528 	    word != VFB_CSUCODE_PING)
   2529 		goto fail;
   2530 
   2531 	aprint_debug_dev(sc->sc_dev, "2D microcode parked\n");
   2532 	return 0;
   2533 fail:
   2534 	aprint_error_dev(sc->sc_dev, "2D suspend failed, reloading\n");
   2535 	(void)veritefb_risc_init(sc);
   2536 	return EIO;
   2537 }
   2538 
   2539 /*
   2540  * DMA engine pulls a word stream into the same input FIFO PIO writes
   2541  * feed.
   2542  */
   2543 static int
   2544 veritefb_dma_alloc(struct veritefb_softc *sc)
   2545 {
   2546 	int nsegs, error;
   2547 
   2548 	if (sc->sc_dma_buf != NULL)
   2549 		return 0;
   2550 
   2551 	/* descriptor block: one page satisfies the 16KB-block rule */
   2552 	error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
   2553 	    &sc->sc_dma_list_seg, 1, &nsegs, BUS_DMA_WAITOK);
   2554 	if (error)
   2555 		return error;
   2556 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_list_seg, 1,
   2557 	    PAGE_SIZE, (void **)&sc->sc_dma_list, BUS_DMA_WAITOK);
   2558 	if (error)
   2559 		goto fail;
   2560 	error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
   2561 	    BUS_DMA_WAITOK, &sc->sc_dma_list_map);
   2562 	if (error)
   2563 		goto fail;
   2564 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_list_map,
   2565 	    sc->sc_dma_list, PAGE_SIZE, NULL, BUS_DMA_WAITOK);
   2566 	if (error)
   2567 		goto fail;
   2568 
   2569 	error = bus_dmamem_alloc(sc->sc_dmat, VFB_DMA_BOUNCE, PAGE_SIZE, 0,
   2570 	    &sc->sc_dma_buf_seg, 1, &nsegs, BUS_DMA_WAITOK);
   2571 	if (error)
   2572 		goto fail;
   2573 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_buf_seg, 1,
   2574 	    VFB_DMA_BOUNCE, (void **)&sc->sc_dma_buf, BUS_DMA_WAITOK);
   2575 	if (error)
   2576 		goto fail;
   2577 	error = bus_dmamap_create(sc->sc_dmat, VFB_DMA_BOUNCE, 1,
   2578 	    VFB_DMA_BOUNCE, 0, BUS_DMA_WAITOK, &sc->sc_dma_buf_map);
   2579 	if (error)
   2580 		goto fail;
   2581 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_buf_map,
   2582 	    sc->sc_dma_buf, VFB_DMA_BOUNCE, NULL, BUS_DMA_WAITOK);
   2583 	if (error)
   2584 		goto fail;
   2585 
   2586 	aprint_debug_dev(sc->sc_dev, "DMA bounce %u bytes at pa 0x%lx, "
   2587 	    "list at pa 0x%lx\n", VFB_DMA_BOUNCE,
   2588 	    (u_long)sc->sc_dma_buf_map->dm_segs[0].ds_addr,
   2589 	    (u_long)sc->sc_dma_list_map->dm_segs[0].ds_addr);
   2590 	return 0;
   2591 fail:
   2592 	/* one-shot lazy init */
   2593 	aprint_error_dev(sc->sc_dev, "DMA setup failed: %d\n", error);
   2594 	sc->sc_dma_buf = NULL;
   2595 	return error;
   2596 }
   2597 
   2598 #ifdef VERITEFB_DEBUG
   2599 static void
   2600 vfb_stat(struct veritefb_softc *sc, int idx, const struct timeval *t0)
   2601 {
   2602 	struct timeval t1;
   2603 
   2604 	microuptime(&t1);
   2605 	sc->sc_stats.vs_count[idx]++;
   2606 	sc->sc_stats.vs_us[idx] +=
   2607 	    (uint64_t)(t1.tv_sec - t0->tv_sec) * 1000000 +
   2608 	    (t1.tv_usec - t0->tv_usec);
   2609 }
   2610 #define VFB_T0()	struct timeval t0_; microuptime(&t0_)
   2611 #define VFB_STAT(sc, idx)	vfb_stat(sc, idx, &t0_)
   2612 #else
   2613 #define VFB_T0()	do { } while (0)
   2614 #define VFB_STAT(sc, idx)	do { } while (0)
   2615 #endif
   2616 
   2617 /*
   2618  * Settle the in-flight descriptor DMA
   2619  */
   2620 static int
   2621 veritefb_dma_drain(struct veritefb_softc *sc)
   2622 {
   2623 	uint32_t i;
   2624 	VFB_T0();
   2625 
   2626 	if (!sc->sc_dma_pending)
   2627 		return 0;
   2628 
   2629 #ifdef VERITEFB_DEBUG
   2630 	/* overlap metric: did the engine finish during CPU build? */
   2631 	sc->sc_stats.vs_count[
   2632 	    (vfb_read4(sc, VFB_DMACMDPTR) & VFB_DMACMDPTR_BUSY) != 0 ?
   2633 	    VFB_STAT_V3D_DRAIN_BUSY : VFB_STAT_V3D_DRAIN_IDLE]++;
   2634 #endif
   2635 	for (i = 0; i < VFB_DMA_TIMEOUT_US; i++) {
   2636 		if ((vfb_read4(sc, VFB_DMACMDPTR) & VFB_DMACMDPTR_BUSY) == 0)
   2637 			break;
   2638 		delay(1);
   2639 	}
   2640 	VFB_STAT(sc, VFB_STAT_V3D_SPIN);
   2641 
   2642 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_pending_map, 0,
   2643 	    sc->sc_dma_pending_len, BUS_DMASYNC_POSTWRITE);
   2644 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_list_map, 0, 16,
   2645 	    BUS_DMASYNC_POSTWRITE);
   2646 	sc->sc_dma_pending = false;
   2647 
   2648 	if (i == VFB_DMA_TIMEOUT_US) {
   2649 		/* stop a wedged master before it holds the bus forever */
   2650 		vfb_write1(sc, VFB_MODE, VFB_MODE_NATIVE);
   2651 		aprint_error_dev(sc->sc_dev,
   2652 		    "DMA drain timeout, engine off\n");
   2653 		return EIO;
   2654 	}
   2655 	return 0;
   2656 }
   2657 
   2658 static int
   2659 veritefb_intr(void *arg)
   2660 {
   2661 	struct veritefb_softc *sc = arg;
   2662 	uint8_t st;
   2663 
   2664 	st = vfb_read1(sc, VFB_INTR);
   2665 	if (st == 0)
   2666 		return 0;
   2667 	vfb_write1(sc, VFB_INTR, st);		/* W1C ack */
   2668 	if ((st & VFB_INTR_VERT) != 0 && sc->sc_flip_pending) {
   2669 		vfb_write4(sc, VFB_FRAMEBASEA, sc->sc_flip_base);
   2670 		sc->sc_flip_pending = false;
   2671 		vfb_write1(sc, VFB_INTREN, 0);
   2672 	}
   2673 	return 1;
   2674 }
   2675 
   2676 /* Abandon a queued flip (teardown/modeset take scanout over). */
   2677 static void
   2678 veritefb_flip_cancel(struct veritefb_softc *sc)
   2679 {
   2680 
   2681 	if (!sc->sc_flip_intr_ok)
   2682 		return;
   2683 	sc->sc_flip_pending = false;
   2684 	vfb_write1(sc, VFB_INTREN, 0);
   2685 }
   2686 
   2687 static void
   2688 veritefb_flip_wait(struct veritefb_softc *sc)
   2689 {
   2690 	uint32_t i;
   2691 
   2692 	if (!sc->sc_flip_pending)
   2693 		return;
   2694 	for (i = 0; i < 2 * VFB_VSYNCPOLL; i++) {
   2695 		if (!sc->sc_flip_pending)
   2696 			return;
   2697 		delay(1);
   2698 	}
   2699 	vfb_write4(sc, VFB_FRAMEBASEA, sc->sc_flip_base);
   2700 	sc->sc_flip_pending = false;
   2701 	vfb_write1(sc, VFB_INTREN, 0);
   2702 	aprint_error_dev(sc->sc_dev, "queued flip lost, forced\n");
   2703 }
   2704 
   2705 static int
   2706 veritefb_dma_submit(struct veritefb_softc *sc, bus_dmamap_t map,
   2707     uint32_t len, uint32_t swap)
   2708 {
   2709 	uint32_t *dl = sc->sc_dma_list;
   2710 	int error;
   2711 	VFB_T0();
   2712 
   2713 	/* queued flip MUST retire before commands can exec */
   2714 	veritefb_flip_wait(sc);
   2715 
   2716 	/* never kick (or rewrite Mode) while the master runs */
   2717 	error = veritefb_dma_drain(sc);
   2718 	if (error)
   2719 		return error;
   2720 
   2721 	/* data entry: len is a byte count = (words << 2) at b23:2 */
   2722 	dl[0] = htole32((uint32_t)map->dm_segs[0].ds_addr);
   2723 	dl[1] = htole32(len | swap);
   2724 	/* stop-DMA entry: link flag with a null address */
   2725 	dl[2] = htole32(0);
   2726 	dl[3] = htole32(VFB_DMALEN_LINK);
   2727 
   2728 	bus_dmamap_sync(sc->sc_dmat, map, 0, len,
   2729 	    BUS_DMASYNC_PREWRITE);
   2730 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_list_map, 0, 16,
   2731 	    BUS_DMASYNC_PREWRITE);
   2732 
   2733 	vfb_write1(sc, VFB_LOWWATERMARK, VFB_DMA_LOWWATER);
   2734 	vfb_write1(sc, VFB_MODE, VFB_MODE_NATIVE | VFB_MODE_DMAEN);
   2735 	vfb_write4(sc, VFB_DMACMDPTR,
   2736 	    (uint32_t)sc->sc_dma_list_map->dm_segs[0].ds_addr);
   2737 
   2738 	/* async: the drain (here or at any drain point) settles it */
   2739 	sc->sc_dma_pending = true;
   2740 	sc->sc_dma_pending_map = map;
   2741 	sc->sc_dma_pending_len = len;
   2742 
   2743 	VFB_STAT(sc, VFB_STAT_V3D_SUBMIT);
   2744 #ifdef VERITEFB_DEBUG
   2745 	sc->sc_stats.vs_count[VFB_STAT_V3D_BYTES] += len;
   2746 #endif
   2747 	return 0;
   2748 }
   2749 
   2750 /*
   2751  * TODO: Consider WSDISPLAYIO_SET_MODE in the future
   2752  */
   2753 static int
   2754 veritefb_set_scan_depth(struct veritefb_softc *sc, int depth)
   2755 {
   2756 	const struct veritefb_stride *st;
   2757 
   2758 	if (depth != 8 && depth != 16)
   2759 		return EINVAL;
   2760 	if (depth == sc->sc_depth)
   2761 		return 0;
   2762 	st = veritefb_stride_for(sc->sc_width * (depth / 8));
   2763 	if (st == NULL)
   2764 		return EINVAL;
   2765 	/* the modeset rewrites Mode, which would abort a live master */
   2766 	(void)veritefb_dma_drain(sc);
   2767 	veritefb_flip_cancel(sc);
   2768 	sc->sc_depth = depth;
   2769 	sc->sc_linebytes = st->linebytes;
   2770 	return veritefb_set_mode(sc, sc->sc_videomode) ? 0 : EIO;
   2771 }
   2772 
   2773 /* Resume the parked 2D microcode from the csucode monitor. */
   2774 static int
   2775 veritefb_resume2d(struct veritefb_softc *sc)
   2776 {
   2777 	uint32_t word;
   2778 
   2779 	if (sc->sc_risc_owner == VFB_OWNER_CONSOLE ||
   2780 	    sc->sc_mode != WSDISPLAYIO_MODE_EMUL ||
   2781 	    sc->sc_ucode == NULL)
   2782 		return EBUSY;
   2783 
   2784 	/* modeset + PIO FIFO words follow */
   2785 	(void)veritefb_dma_drain(sc);
   2786 
   2787 	if (sc->sc_depth != 8)
   2788 		(void)veritefb_set_scan_depth(sc, 8);
   2789 	vfb_write4(sc, VFB_FRAMEBASEA, (uint32_t)sc->sc_fb_offset);
   2790 
   2791 	if (veritefb_drain_outfifo(sc) != 0 ||
   2792 	    veritefb_waitfifo(sc, 1) != 0)
   2793 		goto fail;
   2794 	vfb_fifo_write(sc, VFB_CSUCODE_PING);
   2795 	if (veritefb_read_outfifo(sc, &word) != 0 ||
   2796 	    word != VFB_CSUCODE_PING)
   2797 		goto fail;
   2798 
   2799 	if (veritefb_waitfifo(sc, 4) != 0)
   2800 		goto fail;
   2801 	vfb_fifo_write(sc, VFB_CSUCODE_RESUME);
   2802 	vfb_fifo_write(sc, 0);		/* context store area */
   2803 	vfb_fifo_write(sc, 0);
   2804 	vfb_fifo_write(sc, sc->sc_ucode_entry);
   2805 
   2806 	/* PE state did not survive; the handshake replays Setup. */
   2807 	if (!veritefb_2d_handshake(sc))
   2808 		goto fail;
   2809 	sc->sc_risc_owner = VFB_OWNER_CONSOLE;
   2810 
   2811 	if (sc->sc_gc_initted)
   2812 		glyphcache_wipe(&sc->sc_gc);
   2813 	veritefb_mux_redraw(sc);
   2814 
   2815 	aprint_debug_dev(sc->sc_dev, "2D microcode resumed\n");
   2816 	return 0;
   2817 fail:
   2818 	aprint_error_dev(sc->sc_dev, "2D resume failed, reloading\n");
   2819 	if (veritefb_risc_init(sc)) {
   2820 		if (sc->sc_gc_initted)
   2821 			glyphcache_wipe(&sc->sc_gc);
   2822 		veritefb_mux_redraw(sc);
   2823 	}
   2824 	return EIO;
   2825 }
   2826 
   2827 /*
   2828  * Full-screen redraw after a resume
   2829  */
   2830 static void
   2831 veritefb_mux_redraw(struct veritefb_softc *sc)
   2832 {
   2833 
   2834 	if (db_active)
   2835 		return;
   2836 	if (sc->vd.active != NULL)
   2837 		vcons_redraw_screen(sc->vd.active);
   2838 }
   2839 
   2840 /*
   2841  * /dev/verite3d  exclusive 3D client interface
   2842  */
   2843 
   2844 const struct cdevsw verite3d_cdevsw = {
   2845 	.d_open = verite3d_open,
   2846 	.d_close = verite3d_close,
   2847 	.d_read = noread,
   2848 	.d_write = nowrite,
   2849 	.d_ioctl = verite3d_ioctl,
   2850 	.d_stop = nostop,
   2851 	.d_tty = notty,
   2852 	.d_poll = nopoll,
   2853 	.d_mmap = verite3d_mmap,
   2854 	.d_kqfilter = nokqfilter,
   2855 	.d_discard = nodiscard,
   2856 	.d_flag = D_OTHER
   2857 };
   2858 
   2859 static int
   2860 verite3d_ring_alloc(struct veritefb_softc *sc)
   2861 {
   2862 	int s, nsegs, error;
   2863 
   2864 	if (sc->sc_v3d_slot[0] != NULL)
   2865 		return 0;
   2866 	for (s = 0; s < V3D_RING_SLOTS; s++) {
   2867 		error = bus_dmamem_alloc(sc->sc_dmat, V3D_SLOT_SIZE,
   2868 		    PAGE_SIZE, 0, &sc->sc_v3d_slot_seg[s], 1, &nsegs,
   2869 		    BUS_DMA_WAITOK);
   2870 		if (error)
   2871 			return error;
   2872 		error = bus_dmamem_map(sc->sc_dmat, &sc->sc_v3d_slot_seg[s],
   2873 		    1, V3D_SLOT_SIZE, (void **)&sc->sc_v3d_slot[s],
   2874 		    BUS_DMA_WAITOK);
   2875 		if (error)
   2876 			return error;
   2877 		error = bus_dmamap_create(sc->sc_dmat, V3D_SLOT_SIZE, 1,
   2878 		    V3D_SLOT_SIZE, 0, BUS_DMA_WAITOK,
   2879 		    &sc->sc_v3d_slot_map[s]);
   2880 		if (error)
   2881 			return error;
   2882 		error = bus_dmamap_load(sc->sc_dmat, sc->sc_v3d_slot_map[s],
   2883 		    sc->sc_v3d_slot[s], V3D_SLOT_SIZE, NULL, BUS_DMA_WAITOK);
   2884 		if (error)
   2885 			return error;
   2886 	}
   2887 	return 0;
   2888 }
   2889 
   2890 int
   2891 verite3d_open(dev_t dev, int flags, int mode, struct lwp *l)
   2892 {
   2893 	struct veritefb_softc *sc;
   2894 	int error;
   2895 
   2896 	sc = device_lookup_private(&veritefb_cd, minor(dev));
   2897 	if (sc == NULL)
   2898 		return ENXIO;
   2899 	if (sc->sc_v3d_open)
   2900 		return EBUSY;
   2901 
   2902 	/* console must be healthy and in EMUL; parking happens at INIT */
   2903 	if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL || sc->sc_ucode == NULL ||
   2904 	    sc->sc_risc_owner != VFB_OWNER_CONSOLE)
   2905 		return EBUSY;
   2906 
   2907 	error = veritefb_dma_alloc(sc);	/* descriptor list page */
   2908 	if (error)
   2909 		return error;
   2910 	error = verite3d_ring_alloc(sc);
   2911 	if (error)
   2912 		return error;
   2913 
   2914 	if (sc->sc_v3d_ext == NULL) {
   2915 		sc->sc_v3d_pool_base = (uint32_t)(sc->sc_fb_offset +
   2916 		    (bus_size_t)sc->sc_linebytes * sc->sc_height);
   2917 		sc->sc_v3d_ext = extent_create("verite3d",
   2918 		    sc->sc_v3d_pool_base, sc->sc_memsize - 1, NULL, 0,
   2919 		    EX_WAITOK);
   2920 	}
   2921 	if (sc->sc_v3d_reg == NULL)
   2922 		sc->sc_v3d_reg = kmem_zalloc(V3D_MAX_REGIONS *
   2923 		    sizeof(sc->sc_v3d_reg[0]), KM_SLEEP);
   2924 	sc->sc_v3d_nreg = 0;
   2925 
   2926 	sc->sc_v3d_open = true;
   2927 	sc->sc_v3d_dead = false;
   2928 	sc->sc_v3d_inited = false;
   2929 	return 0;
   2930 }
   2931 
   2932 /* Everything back to the console, whatever the client left behind. */
   2933 static void
   2934 verite3d_teardown(struct veritefb_softc *sc)
   2935 {
   2936 
   2937 	(void)veritefb_dma_drain(sc);
   2938 	veritefb_flip_cancel(sc);
   2939 
   2940 	if (sc->sc_v3d_dead || sc->sc_v3d_inited) {
   2941 		/*
   2942 		 * full reload is the only safe route back
   2943 		 */
   2944 		if (sc->sc_depth != 8)
   2945 			(void)veritefb_set_scan_depth(sc, 8);
   2946 		vfb_write4(sc, VFB_FRAMEBASEA, (uint32_t)sc->sc_fb_offset);
   2947 		if (veritefb_risc_init(sc)) {
   2948 			if (sc->sc_gc_initted)
   2949 				glyphcache_wipe(&sc->sc_gc);
   2950 			veritefb_mux_redraw(sc);
   2951 		}
   2952 	}
   2953 	/* else: INIT never ran, the console was never parked */
   2954 	if (sc->sc_v3d_ext != NULL) {
   2955 		extent_destroy(sc->sc_v3d_ext);
   2956 		sc->sc_v3d_ext = NULL;
   2957 	}
   2958 	sc->sc_v3d_open = false;
   2959 	sc->sc_v3d_dead = false;
   2960 	sc->sc_v3d_inited = false;
   2961 }
   2962 
   2963 int
   2964 verite3d_close(dev_t dev, int flags, int mode, struct lwp *l)
   2965 {
   2966 	struct veritefb_softc *sc;
   2967 
   2968 	sc = device_lookup_private(&veritefb_cd, minor(dev));
   2969 	if (sc == NULL)
   2970 		return ENXIO;
   2971 #ifdef VERITEFB_DEBUG
   2972 	/* the GL client is going away: stop sampling its PC */
   2973 	sc->sc_pcsample_on = false;
   2974 	callout_stop(&sc->sc_pcsample_ch);
   2975 #endif
   2976 	if (sc->sc_v3d_open)
   2977 		verite3d_teardown(sc);
   2978 	return 0;
   2979 }
   2980 
   2981 paddr_t
   2982 verite3d_mmap(dev_t dev, off_t off, int prot)
   2983 {
   2984 	struct veritefb_softc *sc;
   2985 	int s;
   2986 
   2987 	sc = device_lookup_private(&veritefb_cd, minor(dev));
   2988 	if (sc == NULL || !sc->sc_v3d_open)
   2989 		return (paddr_t)-1;
   2990 	if (off < 0)
   2991 		return (paddr_t)-1;
   2992 	if (off >= V3D_VRAM_MMAP_OFF) {
   2993 		off_t voff = off - V3D_VRAM_MMAP_OFF;
   2994 
   2995 		if (voff >= (off_t)sc->sc_memsize)
   2996 			return (paddr_t)-1;
   2997 		return bus_space_mmap(sc->sc_memt, sc->sc_fb_paddr + voff,
   2998 		    0, prot, BUS_SPACE_MAP_LINEAR);
   2999 	}
   3000 	s = (int)(off / V3D_SLOT_SIZE);
   3001 	if (sc->sc_v3d_slot[s] == NULL)
   3002 		return (paddr_t)-1;
   3003 	return bus_dmamem_mmap(sc->sc_dmat, &sc->sc_v3d_slot_seg[s], 1,
   3004 	    off % V3D_SLOT_SIZE, prot, 0);
   3005 }
   3006 
   3007 int
   3008 verite3d_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
   3009 {
   3010 	struct veritefb_softc *sc;
   3011 	int error;
   3012 
   3013 	sc = device_lookup_private(&veritefb_cd, minor(dev));
   3014 	if (sc == NULL)
   3015 		return ENXIO;
   3016 	if (!sc->sc_v3d_open)
   3017 		return EBADF;
   3018 	if (sc->sc_v3d_dead && cmd != V3D_MODE)
   3019 		return EIO;
   3020 
   3021 	switch (cmd) {
   3022 	case V3D_INIT:
   3023 		{
   3024 			struct v3d_init *vi = data;
   3025 			uint8_t *img;
   3026 			uint32_t entry;
   3027 			bool ok;
   3028 
   3029 			if (sc->sc_v3d_inited)
   3030 				return EBUSY;
   3031 			if (vi->vi_size < sizeof(Elf32_Ehdr) ||
   3032 			    vi->vi_size > VFB_MAXUCODE)
   3033 				return EINVAL;
   3034 			img = kmem_alloc(vi->vi_size, KM_SLEEP);
   3035 			error = copyin((const void *)(uintptr_t)vi->vi_ucode,
   3036 			    img, vi->vi_size);
   3037 			if (error) {
   3038 				kmem_free(img, vi->vi_size);
   3039 				return error;
   3040 			}
   3041 
   3042 			ok = veritefb_ucode_load(sc, img, vi->vi_size,
   3043 			    VFB_UCF_BASE, VFB_UCF_END, false, &entry);
   3044 			kmem_free(img, vi->vi_size);
   3045 			if (!ok)
   3046 				return EINVAL;
   3047 			if (!veritefb_risc_init(sc))
   3048 				goto dead;
   3049 			error = veritefb_suspend2d(sc);
   3050 			if (error)
   3051 				return error;
   3052 			if (veritefb_waitfifo_raw(sc, 4, 100000) != 0)
   3053 				goto dead;
   3054 			sc->sc_risc_owner = VFB_OWNER_FOREIGN;
   3055 			vfb_fifo_write(sc, VFB_CSUCODE_INIT);
   3056 			vfb_fifo_write(sc, VFB_CTX_BASE);
   3057 			vfb_fifo_write(sc, 0);
   3058 			vfb_fifo_write(sc, entry);
   3059 
   3060 			sc->sc_v3d_inited = true;
   3061 			vi->vi_ctx_base = VFB_CTX_BASE;
   3062 			vi->vi_memsize = (uint32_t)sc->sc_memsize;
   3063 			vi->vi_pool_base = sc->sc_v3d_pool_base;
   3064 			return 0;
   3065 		}
   3066 
   3067 	case V3D_SUBMIT:
   3068 		{
   3069 			struct v3d_submit *vs = data;
   3070 
   3071 			if (!sc->sc_v3d_inited)
   3072 				return EINVAL;
   3073 			if (vs->vs_slot >= V3D_RING_SLOTS ||
   3074 			    vs->vs_len == 0 || vs->vs_len > V3D_SLOT_SIZE ||
   3075 			    (vs->vs_len & 3) != 0 || vs->vs_swap > 3)
   3076 				return EINVAL;
   3077 			error = veritefb_dma_submit(sc,
   3078 			    sc->sc_v3d_slot_map[vs->vs_slot], vs->vs_len,
   3079 			    vs->vs_swap);
   3080 			if (error)
   3081 				goto dead;
   3082 			return 0;
   3083 		}
   3084 
   3085 	case V3D_SYNC:
   3086 		{
   3087 			uint32_t word = *(uint32_t *)data;
   3088 			VFB_T0();
   3089 
   3090 			if (!sc->sc_v3d_inited)
   3091 				return EINVAL;
   3092 
   3093 			if (veritefb_dma_drain(sc) != 0)
   3094 				goto dead;
   3095 #ifdef VERITEFB_DEBUG
   3096 			microuptime(&t0_);	/* round-trip time only */
   3097 #endif
   3098 			if (veritefb_waitfifo_raw(sc, 1, 100000) != 0)
   3099 				goto dead;
   3100 			vfb_fifo_write(sc, word);
   3101 			if (veritefb_read_outfifo_raw(sc, &word,
   3102 			    500000) != 0)
   3103 				goto dead;
   3104 			*(uint32_t *)data = word;
   3105 			VFB_STAT(sc, VFB_STAT_V3D_SYNC);
   3106 			return 0;
   3107 		}
   3108 
   3109 	case V3D_ALLOC:
   3110 		{
   3111 			struct v3d_alloc *va = data;
   3112 			u_long result;
   3113 
   3114 			if (va->va_size == 0 || sc->sc_v3d_ext == NULL ||
   3115 			    sc->sc_v3d_nreg >= V3D_MAX_REGIONS)
   3116 				return EINVAL;
   3117 			error = extent_alloc(sc->sc_v3d_ext, va->va_size,
   3118 			    va->va_align ? va->va_align : 4, 0, EX_NOWAIT,
   3119 			    &result);
   3120 			if (error)
   3121 				return error;
   3122 			sc->sc_v3d_reg[sc->sc_v3d_nreg].addr =
   3123 			    (uint32_t)result;
   3124 			sc->sc_v3d_reg[sc->sc_v3d_nreg].size = va->va_size;
   3125 			sc->sc_v3d_nreg++;
   3126 			va->va_addr = (uint32_t)result;
   3127 			return 0;
   3128 		}
   3129 
   3130 	case V3D_FREE:
   3131 		{
   3132 			uint32_t addr = *(const uint32_t *)data;
   3133 			int i;
   3134 
   3135 			for (i = 0; i < sc->sc_v3d_nreg; i++)
   3136 				if (sc->sc_v3d_reg[i].addr == addr)
   3137 					break;
   3138 			if (i == sc->sc_v3d_nreg)
   3139 				return EINVAL;
   3140 			(void)extent_free(sc->sc_v3d_ext, addr,
   3141 			    sc->sc_v3d_reg[i].size, EX_NOWAIT);
   3142 			sc->sc_v3d_reg[i] =
   3143 			    sc->sc_v3d_reg[--sc->sc_v3d_nreg];
   3144 			return 0;
   3145 		}
   3146 
   3147 	case V3D_MODE:
   3148 		{
   3149 			struct v3d_mode *vm = data;
   3150 			const struct veritefb_stride *st;
   3151 
   3152 			if (vm->vm_depth != 0) {
   3153 				error = veritefb_set_scan_depth(sc,
   3154 				    (int)vm->vm_depth);
   3155 				if (error)
   3156 					return error;
   3157 			}
   3158 			if (vm->vm_frame_base != 0) {
   3159 				veritefb_flip_cancel(sc);
   3160 				veritefb_wait_vsync(sc);
   3161 				vfb_write4(sc, VFB_FRAMEBASEA,
   3162 				    vm->vm_frame_base);
   3163 			}
   3164 			vm->vm_width = (uint32_t)sc->sc_width;
   3165 			vm->vm_height = (uint32_t)sc->sc_height;
   3166 			vm->vm_stride = (uint32_t)sc->sc_linebytes;
   3167 			st = veritefb_stride_for(sc->sc_width *
   3168 			    (sc->sc_depth / 8));
   3169 			vm->vm_pe_stride = st == NULL ? 0 :
   3170 			    ((uint32_t)st->stride1 << 12) |
   3171 			    ((uint32_t)st->stride0 << 8);
   3172 			return 0;
   3173 		}
   3174 
   3175 	case V3D_FLIP:
   3176 		{
   3177 			uint32_t base = *(uint32_t *)data;
   3178 			VFB_T0();
   3179 
   3180 			if ((base & V3D_FLIP_NOWAIT) != 0) {
   3181 				VFB_STAT(sc, VFB_STAT_V3D_FLIP);
   3182 				vfb_write4(sc, VFB_FRAMEBASEA,
   3183 				    base & ~V3D_FLIP_NOWAIT);
   3184 				return 0;
   3185 			}
   3186 			if (sc->sc_flip_intr_ok) {
   3187 				veritefb_flip_wait(sc);
   3188 				sc->sc_flip_base = base;
   3189 				sc->sc_flip_pending = true;
   3190 				/* arm on the NEXT vblank edge only */
   3191 				vfb_write1(sc, VFB_INTR, VFB_INTR_VERT);
   3192 				vfb_write1(sc, VFB_INTREN, VFB_INTR_VERT);
   3193 				VFB_STAT(sc, VFB_STAT_V3D_FLIP);
   3194 				return 0;
   3195 			}
   3196 			veritefb_wait_vsync(sc);
   3197 			VFB_STAT(sc, VFB_STAT_V3D_FLIP);
   3198 			vfb_write4(sc, VFB_FRAMEBASEA, base);
   3199 			return 0;
   3200 		}
   3201 
   3202 	default:
   3203 		return EPASSTHROUGH;
   3204 	}
   3205 
   3206 dead:
   3207 	/*
   3208 	 * The stream or the engine is borked.
   3209 	 */
   3210 	sc->sc_v3d_dead = true;
   3211 	if (sc->sc_depth != 8)
   3212 		(void)veritefb_set_scan_depth(sc, 8);
   3213 	(void)veritefb_risc_init(sc);
   3214 	sc->sc_risc_owner = VFB_OWNER_CONSOLE;
   3215 	return EIO;
   3216 }
   3217 
   3218 /*
   3219  * The microcode ships as a firmware file, so it can only be pulled in
   3220  * once the root filesystem exists.
   3221  */
   3222 static void
   3223 veritefb_load_firmware(device_t self)
   3224 {
   3225 	struct veritefb_softc *sc = device_private(self);
   3226 	firmware_handle_t fh;
   3227 	size_t size;
   3228 	int error;
   3229 
   3230 	error = firmware_open("veritefb", VFB_FIRMWARE_NAME, &fh);
   3231 	if (error != 0) {
   3232 		aprint_normal_dev(sc->sc_dev,
   3233 		    "no microcode (firmware veritefb/%s), "
   3234 		    "running unaccelerated\n", VFB_FIRMWARE_NAME);
   3235 		return;
   3236 	}
   3237 
   3238 	size = firmware_get_size(fh);
   3239 	if (size == 0 || size > VFB_MAXUCODE) {
   3240 		aprint_error_dev(sc->sc_dev,
   3241 		    "implausible microcode size %zu\n", size);
   3242 		firmware_close(fh);
   3243 		return;
   3244 	}
   3245 
   3246 	sc->sc_ucode = firmware_malloc(size);
   3247 	sc->sc_ucode_size = size;
   3248 	error = firmware_read(fh, 0, sc->sc_ucode, size);
   3249 	firmware_close(fh);
   3250 	if (error != 0) {
   3251 		aprint_error_dev(sc->sc_dev, "microcode read failed: %d\n",
   3252 		    error);
   3253 		firmware_free(sc->sc_ucode, size);
   3254 		sc->sc_ucode = NULL;
   3255 		return;
   3256 	}
   3257 
   3258 	(void)veritefb_risc_init(sc);
   3259 }
   3260 
   3261 /*
   3262  * no-op until operations have been queued, then a PixengSync round-trip
   3263  */
   3264 static void
   3265 veritefb_sync(struct veritefb_softc *sc)
   3266 {
   3267 	uint32_t word;
   3268 	VFB_T0();
   3269 
   3270 	if (sc->sc_unsynced == 0)
   3271 		return;
   3272 	sc->sc_unsynced = 0;
   3273 	sc->sc_unsynced_area = 0;
   3274 	if (veritefb_drain_outfifo(sc) != 0)
   3275 		return;
   3276 	if (veritefb_waitfifo(sc, 1) != 0)
   3277 		return;
   3278 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_PIXENGSYNC));
   3279 	if (veritefb_read_outfifo(sc, &word) != 0)
   3280 		return;
   3281 	if (word != VFB_SYNC_TOKEN) {
   3282 		veritefb_accel_fail(sc, "bad sync token after operation");
   3283 		return;
   3284 	}
   3285 	VFB_STAT(sc, VFB_STAT_SYNC);
   3286 }
   3287 
   3288 /* FillRectSolidRop */
   3289 static bool
   3290 veritefb_rectfill(struct veritefb_softc *sc, int x, int y, int w, int h,
   3291     uint32_t color)
   3292 {
   3293 	if (veritefb_waitfifo(sc, 4) != 0)
   3294 		return false;
   3295 	vfb_fifo_write(sc, VFB_CMDW(VFB_ROP_COPY, VCMD_FILLRECTSOLIDROP));
   3296 	vfb_fifo_write(sc, color);
   3297 	vfb_fifo_write(sc, VFB_P2(x, y));
   3298 	vfb_fifo_write(sc, VFB_P2(w, h));
   3299 	sc->sc_unsynced_area += (uint32_t)w * h;
   3300 	if (++sc->sc_unsynced >= VFB_LAZY_LIMIT ||
   3301 	    sc->sc_unsynced_area >= VFB_LAZY_AREA)
   3302 		veritefb_sync(sc);
   3303 	return sc->sc_accel == VFB_ACCEL_ON;
   3304 }
   3305 
   3306 /* ScreenBlt */
   3307 static bool
   3308 veritefb_bitblt(struct veritefb_softc *sc, int sx, int sy, int dx, int dy,
   3309     int w, int h)
   3310 {
   3311 	if (veritefb_waitfifo(sc, 5) != 0)
   3312 		return false;
   3313 	vfb_fifo_write(sc, VFB_CMDW(0, VCMD_SCREENBLT));
   3314 	vfb_fifo_write(sc, VFB_ROP_COPY);
   3315 	vfb_fifo_write(sc, VFB_P2(sx, sy));
   3316 	vfb_fifo_write(sc, VFB_P2(w, h));
   3317 	vfb_fifo_write(sc, VFB_P2(dx, dy));
   3318 	sc->sc_unsynced_area += (uint32_t)w * h;
   3319 	if (++sc->sc_unsynced >= VFB_LAZY_LIMIT ||
   3320 	    sc->sc_unsynced_area >= VFB_LAZY_AREA)
   3321 		veritefb_sync(sc);
   3322 	return sc->sc_accel == VFB_ACCEL_ON;
   3323 }
   3324 
   3325 static inline bool
   3326 veritefb_accel_op_ok(struct veritefb_softc *sc)
   3327 {
   3328 	return sc->sc_accel == VFB_ACCEL_ON &&
   3329 	    sc->sc_mode == WSDISPLAYIO_MODE_EMUL;
   3330 }
   3331 
   3332 static void
   3333 veritefb_eraserows(void *cookie, int row, int nrows, long fillattr)
   3334 {
   3335 	struct rasops_info *ri = cookie;
   3336 	struct vcons_screen *scr = ri->ri_hw;
   3337 	struct veritefb_softc *sc = scr->scr_cookie;
   3338 	int x, y, w, h;
   3339 	VFB_T0();
   3340 
   3341 	if (!veritefb_accel_op_ok(sc)) {
   3342 		sc->sc_orig_eraserows(cookie, row, nrows, fillattr);
   3343 		VFB_STAT(sc, VFB_STAT_FILL);
   3344 		return;
   3345 	}
   3346 
   3347 	if (row == 0 && nrows == ri->ri_rows) {
   3348 		x = y = 0;
   3349 		w = ri->ri_width;
   3350 		h = ri->ri_height;
   3351 	} else {
   3352 		x = ri->ri_xorigin;
   3353 		y = ri->ri_yorigin + row * ri->ri_font->fontheight;
   3354 		w = ri->ri_emuwidth;
   3355 		h = nrows * ri->ri_font->fontheight;
   3356 	}
   3357 	if (!veritefb_rectfill(sc, x, y, w, h,
   3358 	    ri->ri_devcmap[(fillattr >> 16) & 0xf]))
   3359 		sc->sc_orig_eraserows(cookie, row, nrows, fillattr);
   3360 	VFB_STAT(sc, VFB_STAT_FILL);
   3361 }
   3362 
   3363 static void
   3364 veritefb_erasecols(void *cookie, int row, int startcol, int ncols,
   3365     long fillattr)
   3366 {
   3367 	struct rasops_info *ri = cookie;
   3368 	struct vcons_screen *scr = ri->ri_hw;
   3369 	struct veritefb_softc *sc = scr->scr_cookie;
   3370 	int x, y, w, h;
   3371 
   3372 	if (!veritefb_accel_op_ok(sc)) {
   3373 		sc->sc_orig_erasecols(cookie, row, startcol, ncols,
   3374 		    fillattr);
   3375 		return;
   3376 	}
   3377 
   3378 	x = ri->ri_xorigin + startcol * ri->ri_font->fontwidth;
   3379 	y = ri->ri_yorigin + row * ri->ri_font->fontheight;
   3380 	w = ncols * ri->ri_font->fontwidth;
   3381 	h = ri->ri_font->fontheight;
   3382 	if (!veritefb_rectfill(sc, x, y, w, h,
   3383 	    ri->ri_devcmap[(fillattr >> 16) & 0xf]))
   3384 		sc->sc_orig_erasecols(cookie, row, startcol, ncols,
   3385 		    fillattr);
   3386 }
   3387 
   3388 static void
   3389 veritefb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
   3390 {
   3391 	struct rasops_info *ri = cookie;
   3392 	struct vcons_screen *scr = ri->ri_hw;
   3393 	struct veritefb_softc *sc = scr->scr_cookie;
   3394 	int x, sy, dy, w, h;
   3395 	VFB_T0();
   3396 
   3397 	if (!veritefb_accel_op_ok(sc)) {
   3398 		sc->sc_orig_copyrows(cookie, srcrow, dstrow, nrows);
   3399 		VFB_STAT(sc, VFB_STAT_BLT);
   3400 		return;
   3401 	}
   3402 
   3403 	x = ri->ri_xorigin;
   3404 	sy = ri->ri_yorigin + srcrow * ri->ri_font->fontheight;
   3405 	dy = ri->ri_yorigin + dstrow * ri->ri_font->fontheight;
   3406 	w = ri->ri_emuwidth;
   3407 	h = nrows * ri->ri_font->fontheight;
   3408 	if (!veritefb_bitblt(sc, x, sy, x, dy, w, h))
   3409 		sc->sc_orig_copyrows(cookie, srcrow, dstrow, nrows);
   3410 	VFB_STAT(sc, VFB_STAT_BLT);
   3411 }
   3412 
   3413 static void
   3414 veritefb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
   3415 {
   3416 	struct rasops_info *ri = cookie;
   3417 	struct vcons_screen *scr = ri->ri_hw;
   3418 	struct veritefb_softc *sc = scr->scr_cookie;
   3419 	int sx, dx, y, w, h;
   3420 
   3421 	if (!veritefb_accel_op_ok(sc)) {
   3422 		sc->sc_orig_copycols(cookie, row, srccol, dstcol, ncols);
   3423 		return;
   3424 	}
   3425 
   3426 	sx = ri->ri_xorigin + srccol * ri->ri_font->fontwidth;
   3427 	dx = ri->ri_xorigin + dstcol * ri->ri_font->fontwidth;
   3428 	y = ri->ri_yorigin + row * ri->ri_font->fontheight;
   3429 	w = ncols * ri->ri_font->fontwidth;
   3430 	h = ri->ri_font->fontheight;
   3431 	if (!veritefb_bitblt(sc, sx, y, dx, y, w, h))
   3432 		sc->sc_orig_copycols(cookie, row, srccol, dstcol, ncols);
   3433 }
   3434 
   3435 /* Blit-within-VRAM for the glyph cache. */
   3436 static void
   3437 veritefb_gc_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi,
   3438     int he, int rop)
   3439 {
   3440 	struct veritefb_softc *sc = cookie;
   3441 
   3442 	(void)veritefb_bitblt(sc, xs, ys, xd, yd, wi, he);
   3443 }
   3444 
   3445 /*
   3446  * Glyph-cached putchar
   3447  */
   3448 static void
   3449 veritefb_putchar(void *cookie, int row, int col, u_int c, long attr)
   3450 {
   3451 	struct rasops_info *ri = cookie;
   3452 	struct vcons_screen *scr = ri->ri_hw;
   3453 	struct veritefb_softc *sc = scr->scr_cookie;
   3454 	struct wsdisplay_font *font = PICK_FONT(ri, c);
   3455 	uint32_t fg, bg;
   3456 	int x, y, wi, he, rv;
   3457 	VFB_T0();
   3458 
   3459 	/* Anything drawn before firmload lands here. */
   3460 	if (!veritefb_accel_op_ok(sc) || !sc->sc_gc_initted) {
   3461 		veritefb_sync(sc);
   3462 		sc->sc_orig_putchar(cookie, row, col, c, attr);
   3463 		VFB_STAT(sc, VFB_STAT_CHAR_SW);
   3464 		return;
   3465 	}
   3466 
   3467 	if (!CHAR_IN_FONT(c, font))
   3468 		return;
   3469 
   3470 	wi = font->fontwidth;
   3471 	he = font->fontheight;
   3472 	x = ri->ri_xorigin + col * wi;
   3473 	y = ri->ri_yorigin + row * he;
   3474 	fg = ri->ri_devcmap[(attr >> 24) & 0xf];
   3475 	bg = ri->ri_devcmap[(attr >> 16) & 0xf];
   3476 
   3477 	if (c == ' ') {
   3478 		if (!veritefb_rectfill(sc, x, y, wi, he, bg)) {
   3479 			sc->sc_orig_putchar(cookie, row, col, c, attr);
   3480 			return;
   3481 		}
   3482 		if (attr & WSATTR_UNDERLINE)
   3483 			(void)veritefb_rectfill(sc,
   3484 			    x, y + he - VFB_UNDERLINE_OFF, wi, 1, fg);
   3485 		VFB_STAT(sc, VFB_STAT_CHAR_SPACE);
   3486 		return;
   3487 	}
   3488 
   3489 	rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
   3490 	if (rv == GC_OK) {
   3491 		VFB_STAT(sc, VFB_STAT_CHAR_HIT);
   3492 		return;
   3493 	}
   3494 
   3495 	/*
   3496 	 * The engine may still be executing queued operations...
   3497 	 */
   3498 	veritefb_sync(sc);
   3499 	sc->sc_orig_putchar(cookie, row, col, c, attr &
   3500 	    ~(long)(WSATTR_REVERSE | WSATTR_HILIT | WSATTR_BLINK |
   3501 	    WSATTR_UNDERLINE));
   3502 
   3503 	if (rv == GC_ADD) {
   3504 		glyphcache_add(&sc->sc_gc, c, x, y);
   3505 	} else if (attr & WSATTR_UNDERLINE)
   3506 		(void)veritefb_rectfill(sc,
   3507 		    x, y + he - VFB_UNDERLINE_OFF, wi, 1, fg);
   3508 	VFB_STAT(sc, VFB_STAT_CHAR_ADD);
   3509 }
   3510 
   3511 #if defined(DDB) && defined(VERITEFB_DEBUG)
   3512 /*
   3513  * ddb 'verite*' commands, wrappers over the RISC debug port.
   3514  * 'veriteregs' leaves the RISC held and clobbers the decoder IR,
   3515  * resume with 'veritereset', not 'veritecont'.
   3516  */
   3517 
   3518 static struct veritefb_softc *veritefb_ddb_sc;
   3519 
   3520 static const char *
   3521 veritefb_db_regname(int idx)
   3522 {
   3523 	switch (idx) {
   3524 	case VRISC_FLAG:	return "flag";
   3525 	case 176:		return "cmd-param";
   3526 	case 177:		return "cmd-index";
   3527 	case 224:		return "DispatchTable";
   3528 	case 225:		return "code-base";
   3529 	case 227:		return "shadow/fb-base";
   3530 	case 235:		return "load-bias";
   3531 	case VRISC_SP:		return "SP(dbg-scratch)";
   3532 	case VRISC_RA:		return "RA(dbg-scratch)";
   3533 	case VRISC_FP:		return "FP(dbg-scratch)";
   3534 	default:		return NULL;
   3535 	}
   3536 }
   3537 
   3538 static void
   3539 veritefb_db_diag(db_expr_t addr, bool have_addr, db_expr_t count,
   3540     const char *modif)
   3541 {
   3542 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3543 	uint32_t pc, word;
   3544 	unsigned i, n;
   3545 
   3546 	if (sc == NULL) {
   3547 		db_printf("veritefb not attached\n");
   3548 		return;
   3549 	}
   3550 
   3551 	db_printf("accel state: %s, RISC owner: %s\n",
   3552 	    sc->sc_accel == VFB_ACCEL_ON ? "ON" :
   3553 	    sc->sc_accel == VFB_ACCEL_SW ? "SW (degraded)" : "OFF",
   3554 	    sc->sc_risc_owner == VFB_OWNER_CONSOLE ? "console" :
   3555 	    sc->sc_risc_owner == VFB_OWNER_PARKED ? "parked" : "foreign");
   3556 	db_printf("FIFOINFREE %u/31, FIFOOUTVALID %u, DEBUG 0x%02x\n",
   3557 	    vfb_read1(sc, VFB_FIFOINFREE) & VFB_FIFOINFREE_MASK,
   3558 	    vfb_read1(sc, VFB_FIFOOUTVALID) & VFB_FIFOOUTVALID_MASK,
   3559 	    vfb_read1(sc, VFB_DEBUG));
   3560 
   3561 	pc = veritefb_risc_samplepc(sc);
   3562 	db_printf("RISC PC 0x%08x: %s\n", pc, veritefb_pc_signature(pc));
   3563 
   3564 	n = MIN(sc->sc_ring_count, 16);
   3565 	db_printf("last %u FIFO words (oldest first):\n", n);
   3566 	for (i = 0; i < n; i++)
   3567 		db_printf("  [-%2u] 0x%08x\n", n - i,
   3568 		    sc->sc_ring[(sc->sc_ring_count - n + i) &
   3569 		    (VFB_RING_SIZE - 1)]);
   3570 
   3571 	/* Heartbeat, only if we believe the engine is alive. */
   3572 	if (sc->sc_accel == VFB_ACCEL_ON) {
   3573 		for (i = 0; i < VFB_DRAINPOLL; i++) {
   3574 			if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   3575 			    VFB_FIFOOUTVALID_MASK) == 0)
   3576 				break;
   3577 			(void)vfb_fifo_read(sc);
   3578 			delay(1);
   3579 		}
   3580 		if ((vfb_read1(sc, VFB_FIFOINFREE) &
   3581 		    VFB_FIFOINFREE_MASK) < 1) {
   3582 			db_printf("heartbeat: input FIFO full - RISC "
   3583 			    "not consuming (wedged)\n");
   3584 			return;
   3585 		}
   3586 		vfb_fifo_write(sc, VFB_CMDW(0, VCMD_PIXENGSYNC));
   3587 		for (i = 0; i < VFB_FIFOPOLL; i++) {
   3588 			if ((vfb_read1(sc, VFB_FIFOOUTVALID) &
   3589 			    VFB_FIFOOUTVALID_MASK) != 0)
   3590 				break;
   3591 			delay(1);
   3592 		}
   3593 		if (i == VFB_FIFOPOLL) {
   3594 			db_printf("heartbeat: no sync token (RISC or "
   3595 			    "pixel engine wedged)\n");
   3596 		} else {
   3597 			word = vfb_fifo_read(sc);
   3598 			db_printf("heartbeat: token 0x%08x (%s)\n", word,
   3599 			    word == VFB_SYNC_TOKEN ? "healthy" : "BAD");
   3600 		}
   3601 	} else if (sc->sc_risc_owner == VFB_OWNER_PARKED) {
   3602 		/* PARKED = the DBG-DMA configuration; the ping is PIO */
   3603 		(void)veritefb_dma_drain(sc);
   3604 		if (veritefb_drain_outfifo(sc) != 0 ||
   3605 		    veritefb_waitfifo_raw(sc, 1, VFB_FIFOPOLL) != 0) {
   3606 			db_printf("heartbeat: monitor FIFO stuck\n");
   3607 			return;
   3608 		}
   3609 		vfb_fifo_write(sc, VFB_CSUCODE_PING);
   3610 		if (veritefb_read_outfifo_raw(sc, &word, VFB_FIFOPOLL) == 0)
   3611 			db_printf("heartbeat: monitor ping 0x%08x (%s)\n",
   3612 			    word, word == VFB_CSUCODE_PING ?
   3613 			    "parked, healthy" : "BAD");
   3614 		else
   3615 			db_printf("heartbeat: monitor ping timed out\n");
   3616 	}
   3617 }
   3618 
   3619 static void
   3620 veritefb_db_suspend(db_expr_t addr, bool have_addr, db_expr_t count,
   3621     const char *modif)
   3622 {
   3623 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3624 
   3625 	if (sc == NULL) {
   3626 		db_printf("veritefb not attached\n");
   3627 		return;
   3628 	}
   3629 	db_printf("suspend2d: %d\n", veritefb_suspend2d(sc));
   3630 }
   3631 
   3632 static void
   3633 veritefb_db_resume(db_expr_t addr, bool have_addr, db_expr_t count,
   3634     const char *modif)
   3635 {
   3636 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3637 
   3638 	if (sc == NULL) {
   3639 		db_printf("veritefb not attached\n");
   3640 		return;
   3641 	}
   3642 	db_printf("resume2d: %d\n", veritefb_resume2d(sc));
   3643 }
   3644 
   3645 static void
   3646 veritefb_db_regs(db_expr_t addr, bool have_addr, db_expr_t count,
   3647     const char *modif)
   3648 {
   3649 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3650 	const char *name;
   3651 	uint32_t val;
   3652 	int i;
   3653 
   3654 	if (sc == NULL) {
   3655 		db_printf("veritefb not attached\n");
   3656 		return;
   3657 	}
   3658 
   3659 	veritefb_risc_hold(sc);
   3660 	db_printf("register file snapshot (RISC left held; IR clobbered - "
   3661 	    "use veritereset to resume):\n");
   3662 	for (i = 0; i < 256; i++) {
   3663 		val = veritefb_risc_readrf(sc, i);
   3664 		name = veritefb_db_regname(i);
   3665 		db_printf("%%%-3d 0x%08x%s%s%s", i, val,
   3666 		    name ? " (" : "", name ? name : "", name ? ")" : "");
   3667 		db_printf((i & 3) == 3 ? "\n" : "  ");
   3668 	}
   3669 	vfb_write1(sc, VFB_STATEINDEX, VFB_STATEINDEX_PC);
   3670 	db_printf("PC 0x%08x\n", vfb_read4(sc, VFB_STATEDATA));
   3671 }
   3672 
   3673 static void
   3674 veritefb_db_reset(db_expr_t addr, bool have_addr, db_expr_t count,
   3675     const char *modif)
   3676 {
   3677 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3678 
   3679 	if (sc == NULL || sc->sc_ucode == NULL) {
   3680 		db_printf("veritefb not attached or no microcode\n");
   3681 		return;
   3682 	}
   3683 
   3684 	db_printf("reloading microcode and restarting RISC...\n");
   3685 	db_printf("%s\n", veritefb_risc_init(sc) ?
   3686 	    "handshake passed, acceleration restored" :
   3687 	    "bring-up FAILED, staying in software rendering");
   3688 }
   3689 
   3690 static void
   3691 veritefb_db_fault(db_expr_t addr, bool have_addr, db_expr_t count,
   3692     const char *modif)
   3693 {
   3694 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3695 
   3696 	if (sc == NULL) {
   3697 		db_printf("veritefb not attached\n");
   3698 		return;
   3699 	}
   3700 
   3701 	db_printf("deliberately sending an invalid command (trap slot), "
   3702 	    "run veritediag to observe, veritereset to recover\n");
   3703 	(void)veritefb_dma_drain(sc);
   3704 	vfb_fifo_write(sc, VFB_CMDW(0, VFB_CMD_BOGUS));
   3705 }
   3706 
   3707 static void
   3708 veritefb_db_cont(db_expr_t addr, bool have_addr, db_expr_t count,
   3709     const char *modif)
   3710 {
   3711 	struct veritefb_softc *sc = veritefb_ddb_sc;
   3712 
   3713 	if (sc == NULL) {
   3714 		db_printf("veritefb not attached\n");
   3715 		return;
   3716 	}
   3717 	veritefb_risc_continue(sc);
   3718 	db_printf("RISC released\n");
   3719 }
   3720 
   3721 static const struct db_command veritefb_db_commands[] = {
   3722 	{ DDB_ADD_CMD("veritediag", veritefb_db_diag, 0,
   3723 	    "veritefb: PC signature, FIFO gauges, ring, heartbeat",
   3724 	    NULL, NULL) },
   3725 	{ DDB_ADD_CMD("veriteregs", veritefb_db_regs, 0,
   3726 	    "veritefb: RISC register file snapshot (leaves RISC held)",
   3727 	    NULL, NULL) },
   3728 	{ DDB_ADD_CMD("veritereset", veritefb_db_reset, 0,
   3729 	    "veritefb: reload microcode, restart RISC, re-handshake",
   3730 	    NULL, NULL) },
   3731 	{ DDB_ADD_CMD("veritefault", veritefb_db_fault, 0,
   3732 	    "veritefb: deliberately wedge the RISC (recovery test)",
   3733 	    NULL, NULL) },
   3734 	{ DDB_ADD_CMD("veritesuspend", veritefb_db_suspend, 0,
   3735 	    "veritefb: park the 2D microcode in the csucode monitor",
   3736 	    NULL, NULL) },
   3737 	{ DDB_ADD_CMD("veriteresume", veritefb_db_resume, 0,
   3738 	    "veritefb: resume the parked 2D microcode",
   3739 	    NULL, NULL) },
   3740 	{ DDB_ADD_CMD("veritecont", veritefb_db_cont, 0,
   3741 	    "veritefb: release the RISC hold bit",
   3742 	    NULL, NULL) },
   3743 	{ DDB_END_CMD },
   3744 };
   3745 
   3746 static void
   3747 veritefb_ddb_attach(struct veritefb_softc *sc)
   3748 {
   3749 	if (veritefb_ddb_sc != NULL)
   3750 		return;
   3751 	veritefb_ddb_sc = sc;
   3752 	(void)db_register_tbl(DDB_BASE_CMD, veritefb_db_commands);
   3753 }
   3754 #endif /* DDB && VERITEFB_DEBUG */
   3755 
   3756