2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2012 Robert N. M. Watson
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH research programme.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
39 #include <sys/consio.h>
42 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/mutex.h>
46 #include <sys/module.h>
48 #include <sys/systm.h>
51 #include <machine/bus.h>
52 #include <machine/resource.h>
53 #include <machine/vm.h>
55 #include <dev/fb/fbreg.h>
57 #include <dev/kbd/kbdreg.h>
59 #include <dev/syscons/syscons.h>
61 #include <dev/terasic/mtl/terasic_mtl.h>
64 * Terasic Multitouch LCD (MTL) syscons driver. Implement syscons(4)'s
65 * video_switch_t KPI using MTL's text frame buffer. In principle, we could
66 * actually implement sc_rndr_sw_t, since the MTL text frame buffer implements
67 * a VGA-like memory mapping. However, this requires a lot more book-keeping
68 * with only minor performance improvements (avoiding indirection), as well as
69 * introducing potential endianness issues. Instead we accept one additional
70 * memory copy between a software frame buffer and the hardware frame buffer
71 * and the generic frame buffer (gfb) framework.
74 MALLOC_DEFINE(M_TERASIC_MTL, "mtl_syscons", "MTL syscons frame buffer");
77 * Run early so that boot-time console support can be initialised before
78 * newbus gets around to configuring syscons.
80 * XXXRW: We may need to do more here in order to see earlier boot messages.
83 terasic_mtl_syscons_configure(int flags)
86 printf("%s: not yet\n", __func__);
91 terasic_mtl_vidsw_probe(int unit, video_adapter_t **adp, void *args,
95 printf("%s: not yet\n", __func__);
100 terasic_mtl_vidsw_init(int unit, video_adapter_t *adp, int flags)
102 struct terasic_mtl_softc *sc;
105 sc = (struct terasic_mtl_softc *)adp;
108 vid_init_struct(adp, "terasic_mtl_syscons", -1, unit);
110 vi->vi_width = TERASIC_MTL_COLS;
111 if (vi->vi_width > COL)
113 vi->vi_height = TERASIC_MTL_ROWS;
114 if (vi->vi_height > ROW)
118 * XXXRW: It's not quite clear how these should be initialised.
122 vi->vi_flags = V_INFO_COLOR;
123 vi->vi_mem_model = V_INFO_MM_OTHER;
126 * Software text frame buffer from which we update the actual MTL
127 * frame buffer when asked to.
129 adp->va_window = (vm_offset_t)sc->mtl_text_soft;
132 * Declare video adapter capabilities -- at this point, simply color
133 * support, as MTL doesn't support screen borders, font loading, or
136 * XXXRW: It's unclear if V_ADP_INITIALIZED is needed here; other
137 * syscons(4) drivers are inconsistent about this and
140 adp->va_flags |= V_ADP_COLOR | V_ADP_INITIALIZED;
141 if (vid_register(adp) < 0) {
142 device_printf(sc->mtl_dev, "%s: vid_register failed\n",
146 adp->va_flags |= V_ADP_REGISTERED;
151 terasic_mtl_vidsw_get_info(video_adapter_t *adp, int mode, video_info_t *info)
154 bcopy(&adp->va_info, info, sizeof(*info));
159 terasic_mtl_vidsw_query_mode(video_adapter_t *adp, video_info_t *info)
162 printf("%s: not yet\n", __func__);
167 terasic_mtl_vidsw_set_mode(video_adapter_t *adp, int mode)
170 printf("%s: not yet\n", __func__);
175 terasic_mtl_vidsw_save_font(video_adapter_t *adp, int page, int size,
176 int width, u_char *data, int c, int count)
179 printf("%s: not yet\n", __func__);
184 terasic_mtl_vidsw_load_font(video_adapter_t *adp, int page, int size,
185 int width, u_char *data, int c, int count)
188 printf("%s: not yet\n", __func__);
193 terasic_mtl_vidsw_show_font(video_adapter_t *adp, int page)
196 printf("%s: not yet\n", __func__);
201 terasic_mtl_vidsw_save_palette(video_adapter_t *adp, u_char *palette)
204 printf("%s: not yet\n", __func__);
209 terasic_mtl_vidsw_load_palette(video_adapter_t *adp, u_char *palette)
212 printf("%s: not yet\n", __func__);
217 terasic_mtl_vidsw_set_border(video_adapter_t *adp, int border)
220 printf("%s: not yet\n", __func__);
225 terasic_mtl_vidsw_save_state(video_adapter_t *adp, void *p, size_t size)
228 printf("%s: not yet\n", __func__);
233 terasic_mtl_vidsw_load_state(video_adapter_t *adp, void *p)
236 printf("%s: not yet\n", __func__);
241 terasic_mtl_vidsw_set_win_org(video_adapter_t *adp, off_t offset)
244 printf("%s: not yet\n", __func__);
249 terasic_mtl_vidsw_read_hw_cursor(video_adapter_t *adp, int *colp, int *rowp)
251 struct terasic_mtl_softc *sc;
254 sc = (struct terasic_mtl_softc *)adp;
255 terasic_mtl_reg_textcursor_get(sc, &col, &row);
262 terasic_mtl_vidsw_set_hw_cursor(video_adapter_t *adp, int col, int row)
264 struct terasic_mtl_softc *sc;
266 sc = (struct terasic_mtl_softc *)adp;
267 terasic_mtl_reg_textcursor_set(sc, col, row);
272 terasic_mtl_vidsw_set_hw_cursor_shape(video_adapter_t *adp, int base,
273 int height, int celsize, int blink)
276 printf("%s: not yet\n", __func__);
281 terasic_mtl_vidsw_blank_display(video_adapter_t *adp, int mode)
283 struct terasic_mtl_softc *sc;
285 sc = (struct terasic_mtl_softc *)adp;
286 terasic_mtl_reg_blank(sc);
291 terasic_mtl_vidsw_mmap(video_adapter_t *adp, vm_ooffset_t offset,
292 vm_paddr_t *paddr, int prot, vm_memattr_t *memattr)
295 printf("%s: not yet\n", __func__);
300 terasic_mtl_vidsw_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
303 return (fb_commonioctl(adp, cmd, data));
307 terasic_mtl_vidsw_clear(video_adapter_t *adp)
309 struct terasic_mtl_softc *sc;
311 sc = (struct terasic_mtl_softc *)adp;
312 printf("%s: not yet terasic_mtl_io_clear(sc);\n", __func__);
317 terasic_mtl_vidsw_fill_rect(video_adapter_t *adp, int val, int x, int y,
321 printf("%s: not yet\n", __func__);
326 terasic_mtl_vidsw_bitblt(video_adapter_t *adp, ...)
329 printf("%s: not yet\n", __func__);
334 terasic_mtl_vidsw_diag(video_adapter_t *adp, int level)
337 printf("%s: not yet\n", __func__);
342 terasic_mtl_vidsw_save_cursor_palette(video_adapter_t *adp, u_char *palette)
345 printf("%s: not yet\n", __func__);
350 terasic_mtl_vidsw_load_cursor_palette(video_adapter_t *adp, u_char *palette)
353 printf("%s: not yet\n", __func__);
358 terasic_mtl_vidsw_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst,
362 printf("%s: not yet\n", __func__);
367 terasic_mtl_vidsw_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p,
368 uint32_t a, int size, int bpp, int bit_ltor, int byte_ltor)
371 printf("%s: not yet\n", __func__);
376 terasic_mtl_vidsw_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c,
379 struct terasic_mtl_softc *sc;
382 sc = (struct terasic_mtl_softc *)adp;
383 col = (off % adp->va_info.vi_width);
384 row = (off / adp->va_info.vi_width);
385 terasic_mtl_text_putc(sc, col, row, c, a);
390 terasic_mtl_vidsw_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s,
395 for (i = 0; i < len; i++)
396 vidd_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
401 terasic_mtl_vidsw_putm(video_adapter_t *adp, int x, int y,
402 uint8_t *pixel_image, uint32_t pixel_mask, int size, int width)
405 printf("%s: not yet\n", __func__);
410 terasic_mtl_syscons_attach(struct terasic_mtl_softc *sc)
415 malloc(sizeof(uint16_t) * TERASIC_MTL_ROWS * TERASIC_MTL_COLS,
416 M_TERASIC_MTL, M_WAITOK | M_ZERO);
417 error = terasic_mtl_vidsw_init(0, &sc->mtl_va, 0);
420 error = sc_attach_unit(sc->mtl_unit, device_get_flags(sc->mtl_dev) |
423 device_printf(sc->mtl_dev, "%s: sc_attach_unit failed (%d)\n",
427 free(sc->mtl_text_soft, M_TERASIC_MTL);
432 terasic_mtl_syscons_detach(struct terasic_mtl_softc *sc)
435 free(sc->mtl_text_soft, M_TERASIC_MTL);
436 panic("%s: not supported by syscons", __func__);
439 static video_switch_t terasic_mtl_vidsw = {
440 .probe = terasic_mtl_vidsw_probe,
441 .init = terasic_mtl_vidsw_init,
442 .get_info = terasic_mtl_vidsw_get_info,
443 .query_mode = terasic_mtl_vidsw_query_mode,
444 .set_mode = terasic_mtl_vidsw_set_mode,
445 .save_font = terasic_mtl_vidsw_save_font,
446 .load_font = terasic_mtl_vidsw_load_font,
447 .show_font = terasic_mtl_vidsw_show_font,
448 .save_palette = terasic_mtl_vidsw_save_palette,
449 .load_palette = terasic_mtl_vidsw_load_palette,
450 .set_border = terasic_mtl_vidsw_set_border,
451 .save_state = terasic_mtl_vidsw_save_state,
452 .load_state = terasic_mtl_vidsw_load_state,
453 .set_win_org = terasic_mtl_vidsw_set_win_org,
454 .read_hw_cursor = terasic_mtl_vidsw_read_hw_cursor,
455 .set_hw_cursor = terasic_mtl_vidsw_set_hw_cursor,
456 .set_hw_cursor_shape = terasic_mtl_vidsw_set_hw_cursor_shape,
457 .blank_display = terasic_mtl_vidsw_blank_display,
458 .mmap = terasic_mtl_vidsw_mmap,
459 .ioctl = terasic_mtl_vidsw_ioctl,
460 .clear = terasic_mtl_vidsw_clear,
461 .fill_rect = terasic_mtl_vidsw_fill_rect,
462 .bitblt = terasic_mtl_vidsw_bitblt,
463 .diag = terasic_mtl_vidsw_diag,
464 .save_cursor_palette = terasic_mtl_vidsw_save_cursor_palette,
465 .load_cursor_palette = terasic_mtl_vidsw_load_cursor_palette,
466 .copy = terasic_mtl_vidsw_copy,
467 .putp = terasic_mtl_vidsw_putp,
468 .putc = terasic_mtl_vidsw_putc,
469 .puts = terasic_mtl_vidsw_puts,
470 .putm = terasic_mtl_vidsw_putm,
472 VIDEO_DRIVER(terasic_mtl_syscons, terasic_mtl_vidsw,
473 terasic_mtl_syscons_configure);
474 extern sc_rndr_sw_t txtrndrsw;
475 RENDERER(terasic_mtl_syscons, 0, txtrndrsw, gfb_set);
476 RENDERER_MODULE(terasic_mtl_syscons, gfb_set);