1239691Srwatson/*- 2239691Srwatson * Copyright (c) 2012 Robert N. M. Watson 3239691Srwatson * All rights reserved. 4239691Srwatson * 5239691Srwatson * This software was developed by SRI International and the University of 6239691Srwatson * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 7239691Srwatson * ("CTSRD"), as part of the DARPA CRASH research programme. 8239691Srwatson * 9239691Srwatson * Redistribution and use in source and binary forms, with or without 10239691Srwatson * modification, are permitted provided that the following conditions 11239691Srwatson * are met: 12239691Srwatson * 1. Redistributions of source code must retain the above copyright 13239691Srwatson * notice, this list of conditions and the following disclaimer. 14239691Srwatson * 2. Redistributions in binary form must reproduce the above copyright 15239691Srwatson * notice, this list of conditions and the following disclaimer in the 16239691Srwatson * documentation and/or other materials provided with the distribution. 17239691Srwatson * 18239691Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19239691Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20239691Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21239691Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22239691Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23239691Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24239691Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25239691Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26239691Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27239691Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28239691Srwatson * SUCH DAMAGE. 29239691Srwatson */ 30239691Srwatson 31239691Srwatson#include <sys/cdefs.h> 32239691Srwatson__FBSDID("$FreeBSD$"); 33239691Srwatson 34239691Srwatson#include <sys/param.h> 35239691Srwatson#include <sys/bus.h> 36239691Srwatson#include <sys/conf.h> 37239691Srwatson#include <sys/consio.h> 38239691Srwatson#include <sys/fbio.h> 39239691Srwatson#include <sys/kbio.h> 40239691Srwatson#include <sys/kernel.h> 41239691Srwatson#include <sys/lock.h> 42239691Srwatson#include <sys/malloc.h> 43239691Srwatson#include <sys/mutex.h> 44239691Srwatson#include <sys/module.h> 45239691Srwatson#include <sys/rman.h> 46239691Srwatson#include <sys/systm.h> 47239691Srwatson#include <sys/uio.h> 48239691Srwatson 49239691Srwatson#include <machine/bus.h> 50239691Srwatson#include <machine/resource.h> 51239691Srwatson#include <machine/vm.h> 52239691Srwatson 53239691Srwatson#include <dev/fb/fbreg.h> 54239691Srwatson 55239691Srwatson#include <dev/kbd/kbdreg.h> 56239691Srwatson 57239691Srwatson#include <dev/syscons/syscons.h> 58239691Srwatson 59239691Srwatson#include <dev/terasic/mtl/terasic_mtl.h> 60239691Srwatson 61239691Srwatson/* 62239691Srwatson * Terasic Multitouch LCD (MTL) syscons driver. Implement syscons(4)'s 63239691Srwatson * video_switch_t KPI using MTL's text frame buffer. In principle, we could 64239691Srwatson * actually implement sc_rndr_sw_t, since the MTL text frame buffer implements 65239691Srwatson * a VGA-like memory mapping. However, this requires a lot more book-keeping 66239691Srwatson * with only minor performance improvements (avoiding indirection), as well as 67239691Srwatson * introducing potential endianness issues. Instead we accept one additional 68239691Srwatson * memory copy between a software frame buffer and the hardware frame buffer 69239691Srwatson * and the generic frame buffer (gfb) framework. 70239691Srwatson */ 71239691Srwatson 72239691SrwatsonMALLOC_DEFINE(M_TERASIC_MTL, "mtl_syscons", "MTL syscons frame buffer"); 73239691Srwatson 74239691Srwatson/* 75239691Srwatson * Run early so that boot-time console support can be initialised before 76239691Srwatson * newbus gets around to configuring syscons. 77239691Srwatson * 78239691Srwatson * XXXRW: We may need to do more here in order to see earlier boot messages. 79239691Srwatson */ 80239691Srwatsonstatic int 81239691Srwatsonterasic_mtl_syscons_configure(int flags) 82239691Srwatson{ 83239691Srwatson 84239691Srwatson printf("%s: not yet\n", __func__); 85239691Srwatson return (0); 86239691Srwatson} 87239691Srwatson 88239691Srwatsonstatic int 89239691Srwatsonterasic_mtl_vidsw_probe(int unit, video_adapter_t **adp, void *args, 90239691Srwatson int flags) 91239691Srwatson{ 92239691Srwatson 93239691Srwatson printf("%s: not yet\n", __func__); 94239691Srwatson return (0); 95239691Srwatson} 96239691Srwatson 97239691Srwatsonstatic int 98239691Srwatsonterasic_mtl_vidsw_init(int unit, video_adapter_t *adp, int flags) 99239691Srwatson{ 100239691Srwatson struct terasic_mtl_softc *sc; 101239691Srwatson video_info_t *vi; 102239691Srwatson 103239691Srwatson sc = (struct terasic_mtl_softc *)adp; 104239691Srwatson 105239691Srwatson vi = &adp->va_info; 106239691Srwatson vid_init_struct(adp, "terasic_mtl_syscons", -1, unit); 107239691Srwatson 108239691Srwatson vi->vi_width = TERASIC_MTL_COLS; 109239691Srwatson if (vi->vi_width > COL) 110239691Srwatson vi->vi_width = COL; 111239691Srwatson vi->vi_height = TERASIC_MTL_ROWS; 112239691Srwatson if (vi->vi_height > ROW) 113239691Srwatson vi->vi_height = ROW; 114239691Srwatson 115239691Srwatson /* 116239691Srwatson * XXXRW: It's not quite clear how these should be initialised. 117239691Srwatson */ 118239691Srwatson vi->vi_cwidth = 0; 119239691Srwatson vi->vi_cheight = 0; 120239691Srwatson vi->vi_flags = V_INFO_COLOR; 121239691Srwatson vi->vi_mem_model = V_INFO_MM_OTHER; 122239691Srwatson 123239691Srwatson /* 124239691Srwatson * Software text frame buffer from which we update the actual MTL 125239691Srwatson * frame buffer when asked to. 126239691Srwatson */ 127239691Srwatson adp->va_window = (vm_offset_t)sc->mtl_text_soft; 128239691Srwatson 129239691Srwatson /* 130239691Srwatson * Declare video adapter capabilities -- at this point, simply color 131239691Srwatson * support, as MTL doesn't support screen borders, font loading, or 132239691Srwatson * mode changes. 133239691Srwatson * 134239691Srwatson * XXXRW: It's unclear if V_ADP_INITIALIZED is needed here; other 135239691Srwatson * syscons(4) drivers are inconsistent about this and 136239691Srwatson * V_ADP_REGISTERED. 137239691Srwatson */ 138239691Srwatson adp->va_flags |= V_ADP_COLOR | V_ADP_INITIALIZED; 139239691Srwatson if (vid_register(adp) < 0) { 140239691Srwatson device_printf(sc->mtl_dev, "%s: vid_register failed\n", 141239691Srwatson __func__); 142239691Srwatson return (ENXIO); 143239691Srwatson } 144239691Srwatson adp->va_flags |= V_ADP_REGISTERED; 145239691Srwatson return (0); 146239691Srwatson} 147239691Srwatson 148239691Srwatsonstatic int 149239691Srwatsonterasic_mtl_vidsw_get_info(video_adapter_t *adp, int mode, video_info_t *info) 150239691Srwatson{ 151239691Srwatson 152239691Srwatson bcopy(&adp->va_info, info, sizeof(*info)); 153239691Srwatson return (0); 154239691Srwatson} 155239691Srwatson 156239691Srwatsonstatic int 157239691Srwatsonterasic_mtl_vidsw_query_mode(video_adapter_t *adp, video_info_t *info) 158239691Srwatson{ 159239691Srwatson 160239691Srwatson printf("%s: not yet\n", __func__); 161239691Srwatson return (ENODEV); 162239691Srwatson} 163239691Srwatson 164239691Srwatsonstatic int 165239691Srwatsonterasic_mtl_vidsw_set_mode(video_adapter_t *adp, int mode) 166239691Srwatson{ 167239691Srwatson 168239691Srwatson printf("%s: not yet\n", __func__); 169239691Srwatson return (ENODEV); 170239691Srwatson} 171239691Srwatson 172239691Srwatsonstatic int 173239691Srwatsonterasic_mtl_vidsw_save_font(video_adapter_t *adp, int page, int size, 174239691Srwatson int width, u_char *data, int c, int count) 175239691Srwatson{ 176239691Srwatson 177239691Srwatson printf("%s: not yet\n", __func__); 178239691Srwatson return (ENODEV); 179239691Srwatson} 180239691Srwatson 181239691Srwatsonstatic int 182239691Srwatsonterasic_mtl_vidsw_load_font(video_adapter_t *adp, int page, int size, 183239691Srwatson int width, u_char *data, int c, int count) 184239691Srwatson{ 185239691Srwatson 186239691Srwatson printf("%s: not yet\n", __func__); 187239691Srwatson return (ENODEV); 188239691Srwatson} 189239691Srwatson 190239691Srwatsonstatic int 191239691Srwatsonterasic_mtl_vidsw_show_font(video_adapter_t *adp, int page) 192239691Srwatson{ 193239691Srwatson 194239691Srwatson printf("%s: not yet\n", __func__); 195239691Srwatson return (ENODEV); 196239691Srwatson} 197239691Srwatson 198239691Srwatsonstatic int 199239691Srwatsonterasic_mtl_vidsw_save_palette(video_adapter_t *adp, u_char *palette) 200239691Srwatson{ 201239691Srwatson 202239691Srwatson printf("%s: not yet\n", __func__); 203239691Srwatson return (ENODEV); 204239691Srwatson} 205239691Srwatson 206239691Srwatsonstatic int 207239691Srwatsonterasic_mtl_vidsw_load_palette(video_adapter_t *adp, u_char *palette) 208239691Srwatson{ 209239691Srwatson 210239691Srwatson printf("%s: not yet\n", __func__); 211239691Srwatson return (ENODEV); 212239691Srwatson} 213239691Srwatson 214239691Srwatsonstatic int 215239691Srwatsonterasic_mtl_vidsw_set_border(video_adapter_t *adp, int border) 216239691Srwatson{ 217239691Srwatson 218239691Srwatson printf("%s: not yet\n", __func__); 219239691Srwatson return (ENODEV); 220239691Srwatson} 221239691Srwatson 222239691Srwatsonstatic int 223239691Srwatsonterasic_mtl_vidsw_save_state(video_adapter_t *adp, void *p, size_t size) 224239691Srwatson{ 225239691Srwatson 226239691Srwatson printf("%s: not yet\n", __func__); 227239691Srwatson return (ENODEV); 228239691Srwatson} 229239691Srwatson 230239691Srwatsonstatic int 231239691Srwatsonterasic_mtl_vidsw_load_state(video_adapter_t *adp, void *p) 232239691Srwatson{ 233239691Srwatson 234239691Srwatson printf("%s: not yet\n", __func__); 235239691Srwatson return (ENODEV); 236239691Srwatson} 237239691Srwatson 238239691Srwatsonstatic int 239239691Srwatsonterasic_mtl_vidsw_set_win_org(video_adapter_t *adp, off_t offset) 240239691Srwatson{ 241239691Srwatson 242239691Srwatson printf("%s: not yet\n", __func__); 243239691Srwatson return (ENODEV); 244239691Srwatson} 245239691Srwatson 246239691Srwatsonstatic int 247239691Srwatsonterasic_mtl_vidsw_read_hw_cursor(video_adapter_t *adp, int *colp, int *rowp) 248239691Srwatson{ 249239691Srwatson struct terasic_mtl_softc *sc; 250239691Srwatson uint8_t col, row; 251239691Srwatson 252239691Srwatson sc = (struct terasic_mtl_softc *)adp; 253239691Srwatson terasic_mtl_reg_textcursor_get(sc, &col, &row); 254239691Srwatson *colp = col; 255239691Srwatson *rowp = row; 256239691Srwatson return (0); 257239691Srwatson} 258239691Srwatson 259239691Srwatsonstatic int 260239691Srwatsonterasic_mtl_vidsw_set_hw_cursor(video_adapter_t *adp, int col, int row) 261239691Srwatson{ 262239691Srwatson struct terasic_mtl_softc *sc; 263239691Srwatson 264239691Srwatson sc = (struct terasic_mtl_softc *)adp; 265239691Srwatson terasic_mtl_reg_textcursor_set(sc, col, row); 266239691Srwatson return (0); 267239691Srwatson} 268239691Srwatson 269239691Srwatsonstatic int 270239691Srwatsonterasic_mtl_vidsw_set_hw_cursor_shape(video_adapter_t *adp, int base, 271239691Srwatson int height, int celsize, int blink) 272239691Srwatson{ 273239691Srwatson 274239691Srwatson printf("%s: not yet\n", __func__); 275239691Srwatson return (ENODEV); 276239691Srwatson} 277239691Srwatson 278239691Srwatsonstatic int 279239691Srwatsonterasic_mtl_vidsw_blank_display(video_adapter_t *adp, int mode) 280239691Srwatson{ 281239691Srwatson struct terasic_mtl_softc *sc; 282239691Srwatson 283239691Srwatson sc = (struct terasic_mtl_softc *)adp; 284239691Srwatson terasic_mtl_reg_blank(sc); 285239691Srwatson return (0); 286239691Srwatson} 287239691Srwatson 288239691Srwatsonstatic int 289239691Srwatsonterasic_mtl_vidsw_mmap(video_adapter_t *adp, vm_ooffset_t offset, 290239691Srwatson vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) 291239691Srwatson{ 292239691Srwatson 293239691Srwatson printf("%s: not yet\n", __func__); 294239691Srwatson return (ENODEV); 295239691Srwatson} 296239691Srwatson 297239691Srwatsonstatic int 298239691Srwatsonterasic_mtl_vidsw_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data) 299239691Srwatson{ 300239691Srwatson 301239691Srwatson return (fb_commonioctl(adp, cmd, data)); 302239691Srwatson} 303239691Srwatson 304239691Srwatsonstatic int 305239691Srwatsonterasic_mtl_vidsw_clear(video_adapter_t *adp) 306239691Srwatson{ 307239691Srwatson struct terasic_mtl_softc *sc; 308239691Srwatson 309239691Srwatson sc = (struct terasic_mtl_softc *)adp; 310239691Srwatson printf("%s: not yet terasic_mtl_io_clear(sc);\n", __func__); 311239691Srwatson return (0); 312239691Srwatson} 313239691Srwatson 314239691Srwatsonstatic int 315239691Srwatsonterasic_mtl_vidsw_fill_rect(video_adapter_t *adp, int val, int x, int y, 316239691Srwatson int cx, int cy) 317239691Srwatson{ 318239691Srwatson 319239691Srwatson printf("%s: not yet\n", __func__); 320239691Srwatson return (ENODEV); 321239691Srwatson} 322239691Srwatson 323239691Srwatsonstatic int 324239691Srwatsonterasic_mtl_vidsw_bitblt(video_adapter_t *adp, ...) 325239691Srwatson{ 326239691Srwatson 327239691Srwatson printf("%s: not yet\n", __func__); 328239691Srwatson return (ENODEV); 329239691Srwatson} 330239691Srwatson 331239691Srwatsonstatic int 332239691Srwatsonterasic_mtl_vidsw_diag(video_adapter_t *adp, int level) 333239691Srwatson{ 334239691Srwatson 335239691Srwatson printf("%s: not yet\n", __func__); 336239691Srwatson return (ENODEV); 337239691Srwatson} 338239691Srwatson 339239691Srwatsonstatic int 340239691Srwatsonterasic_mtl_vidsw_save_cursor_palette(video_adapter_t *adp, u_char *palette) 341239691Srwatson{ 342239691Srwatson 343239691Srwatson printf("%s: not yet\n", __func__); 344239691Srwatson return (ENODEV); 345239691Srwatson} 346239691Srwatson 347239691Srwatsonstatic int 348239691Srwatsonterasic_mtl_vidsw_load_cursor_palette(video_adapter_t *adp, u_char *palette) 349239691Srwatson{ 350239691Srwatson 351239691Srwatson printf("%s: not yet\n", __func__); 352239691Srwatson return (ENODEV); 353239691Srwatson} 354239691Srwatson 355239691Srwatsonstatic int 356239691Srwatsonterasic_mtl_vidsw_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, 357239691Srwatson int n) 358239691Srwatson{ 359239691Srwatson 360239691Srwatson printf("%s: not yet\n", __func__); 361239691Srwatson return (ENODEV); 362239691Srwatson} 363239691Srwatson 364239691Srwatsonstatic int 365239691Srwatsonterasic_mtl_vidsw_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, 366239691Srwatson uint32_t a, int size, int bpp, int bit_ltor, int byte_ltor) 367239691Srwatson{ 368239691Srwatson 369239691Srwatson printf("%s: not yet\n", __func__); 370239691Srwatson return (ENODEV); 371239691Srwatson} 372239691Srwatson 373239691Srwatsonstatic int 374239691Srwatsonterasic_mtl_vidsw_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, 375239691Srwatson uint8_t a) 376239691Srwatson{ 377239691Srwatson struct terasic_mtl_softc *sc; 378239691Srwatson u_int col, row; 379239691Srwatson 380239691Srwatson sc = (struct terasic_mtl_softc *)adp; 381239691Srwatson col = (off % adp->va_info.vi_width); 382239691Srwatson row = (off / adp->va_info.vi_width); 383239691Srwatson terasic_mtl_text_putc(sc, col, row, c, a); 384239691Srwatson return (0); 385239691Srwatson} 386239691Srwatson 387239691Srwatsonstatic int 388239691Srwatsonterasic_mtl_vidsw_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, 389239691Srwatson int len) 390239691Srwatson{ 391239691Srwatson int i; 392239691Srwatson 393239691Srwatson for (i = 0; i < len; i++) 394239691Srwatson vidd_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); 395239691Srwatson return (0); 396239691Srwatson} 397239691Srwatson 398239691Srwatsonstatic int 399239691Srwatsonterasic_mtl_vidsw_putm(video_adapter_t *adp, int x, int y, 400239691Srwatson uint8_t *pixel_image, uint32_t pixel_mask, int size, int width) 401239691Srwatson{ 402239691Srwatson 403239691Srwatson printf("%s: not yet\n", __func__); 404239691Srwatson return (ENODEV); 405239691Srwatson} 406239691Srwatson 407239691Srwatson/* 408239691Srwatson * XXXRW: For historical reasons, syscons can't register video consoles 409239691Srwatson * without a keyboard implementation. Provide a dummy. 410239691Srwatson */ 411239691Srwatsonstatic keyboard_switch_t terasic_mtl_keyboard_switch; 412239691Srwatson 413239691Srwatsonstatic int 414239691Srwatsonterasic_mtl_kbd_configure(int flags) 415239691Srwatson{ 416239691Srwatson 417239691Srwatson return (0); 418239691Srwatson} 419239691Srwatson 420239691SrwatsonKEYBOARD_DRIVER(mtl_kbd, terasic_mtl_keyboard_switch, 421239691Srwatson terasic_mtl_kbd_configure); 422239691Srwatson 423239691Srwatsonint 424239691Srwatsonterasic_mtl_syscons_attach(struct terasic_mtl_softc *sc) 425239691Srwatson{ 426239691Srwatson int error; 427239691Srwatson 428239691Srwatson sc->mtl_text_soft = 429239691Srwatson malloc(sizeof(uint16_t) * TERASIC_MTL_ROWS * TERASIC_MTL_COLS, 430239691Srwatson M_TERASIC_MTL, M_WAITOK | M_ZERO); 431239691Srwatson error = terasic_mtl_vidsw_init(0, &sc->mtl_va, 0); 432239691Srwatson if (error) 433239691Srwatson goto out; 434239691Srwatson error = sc_attach_unit(sc->mtl_unit, device_get_flags(sc->mtl_dev) | 435239691Srwatson SC_AUTODETECT_KBD); 436239691Srwatson if (error) 437239691Srwatson device_printf(sc->mtl_dev, "%s: sc_attach_unit failed (%d)\n", 438239691Srwatson __func__, error); 439239691Srwatsonout: 440239691Srwatson if (error) 441239691Srwatson free(sc->mtl_text_soft, M_TERASIC_MTL); 442239691Srwatson return (error); 443239691Srwatson} 444239691Srwatson 445239691Srwatsonvoid 446239691Srwatsonterasic_mtl_syscons_detach(struct terasic_mtl_softc *sc) 447239691Srwatson{ 448239691Srwatson 449239691Srwatson free(sc->mtl_text_soft, M_TERASIC_MTL); 450239691Srwatson panic("%s: not supported by syscons", __func__); 451239691Srwatson} 452239691Srwatson 453239691Srwatsonstatic video_switch_t terasic_mtl_vidsw = { 454239691Srwatson .probe = terasic_mtl_vidsw_probe, 455239691Srwatson .init = terasic_mtl_vidsw_init, 456239691Srwatson .get_info = terasic_mtl_vidsw_get_info, 457239691Srwatson .query_mode = terasic_mtl_vidsw_query_mode, 458239691Srwatson .set_mode = terasic_mtl_vidsw_set_mode, 459239691Srwatson .save_font = terasic_mtl_vidsw_save_font, 460239691Srwatson .load_font = terasic_mtl_vidsw_load_font, 461239691Srwatson .show_font = terasic_mtl_vidsw_show_font, 462239691Srwatson .save_palette = terasic_mtl_vidsw_save_palette, 463239691Srwatson .load_palette = terasic_mtl_vidsw_load_palette, 464239691Srwatson .set_border = terasic_mtl_vidsw_set_border, 465239691Srwatson .save_state = terasic_mtl_vidsw_save_state, 466239691Srwatson .load_state = terasic_mtl_vidsw_load_state, 467239691Srwatson .set_win_org = terasic_mtl_vidsw_set_win_org, 468239691Srwatson .read_hw_cursor = terasic_mtl_vidsw_read_hw_cursor, 469239691Srwatson .set_hw_cursor = terasic_mtl_vidsw_set_hw_cursor, 470239691Srwatson .set_hw_cursor_shape = terasic_mtl_vidsw_set_hw_cursor_shape, 471239691Srwatson .blank_display = terasic_mtl_vidsw_blank_display, 472239691Srwatson .mmap = terasic_mtl_vidsw_mmap, 473239691Srwatson .ioctl = terasic_mtl_vidsw_ioctl, 474239691Srwatson .clear = terasic_mtl_vidsw_clear, 475239691Srwatson .fill_rect = terasic_mtl_vidsw_fill_rect, 476239691Srwatson .bitblt = terasic_mtl_vidsw_bitblt, 477239691Srwatson .diag = terasic_mtl_vidsw_diag, 478239691Srwatson .save_cursor_palette = terasic_mtl_vidsw_save_cursor_palette, 479239691Srwatson .load_cursor_palette = terasic_mtl_vidsw_load_cursor_palette, 480239691Srwatson .copy = terasic_mtl_vidsw_copy, 481239691Srwatson .putp = terasic_mtl_vidsw_putp, 482239691Srwatson .putc = terasic_mtl_vidsw_putc, 483239691Srwatson .puts = terasic_mtl_vidsw_puts, 484239691Srwatson .putm = terasic_mtl_vidsw_putm, 485239691Srwatson}; 486239691SrwatsonVIDEO_DRIVER(terasic_mtl_syscons, terasic_mtl_vidsw, 487239691Srwatson terasic_mtl_syscons_configure); 488239691Srwatsonextern sc_rndr_sw_t txtrndrsw; 489239691SrwatsonRENDERER(terasic_mtl_syscons, 0, txtrndrsw, gfb_set); 490239691SrwatsonRENDERER_MODULE(terasic_mtl_syscons, gfb_set); 491