versatile_clcd.c revision 244197
1/* 2 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/arm/versatile/versatile_clcd.c 244197 2012-12-13 23:19:13Z gonzo $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/malloc.h> 36#include <sys/rman.h> 37#include <sys/fbio.h> 38#include <sys/consio.h> 39#include <sys/kdb.h> 40 41#include <machine/bus.h> 42#include <machine/cpu.h> 43#include <machine/frame.h> 44#include <machine/intr.h> 45 46#include <dev/fdt/fdt_common.h> 47#include <dev/ofw/openfirm.h> 48#include <dev/ofw/ofw_bus.h> 49#include <dev/ofw/ofw_bus_subr.h> 50 51#include <dev/fb/fbreg.h> 52#include <dev/syscons/syscons.h> 53 54#include <machine/bus.h> 55#include <machine/fdt.h> 56 57#define PL110_VENDOR_ARM926PXP 1 58 59#define MEM_SYS 0 60#define MEM_CLCD 1 61#define MEM_REGIONS 2 62 63#define SYS_CLCD 0x00 64#define SYS_CLCD_CLCDID_SHIFT 0x08 65#define SYS_CLCD_CLCDID_MASK 0x1f 66#define SYS_CLCD_PWR3V5VSWITCH (1 << 4) 67#define SYS_CLCD_VDDPOSSWITCH (1 << 3) 68#define SYS_CLCD_NLCDIOON (1 << 2) 69#define SYS_CLCD_LCD_MODE_MASK 0x03 70 71#define CLCD_MODE_RGB888 0x0 72#define CLCD_MODE_RGB555 0x01 73#define CLCD_MODE_RBG565 0x02 74#define CLCD_MODE_RGB565 0x03 75 76#define CLCDC_TIMING0 0x00 77#define CLCDC_TIMING1 0x04 78#define CLCDC_TIMING2 0x08 79#define CLCDC_TIMING3 0x0C 80#define CLCDC_TIMING3 0x0C 81#define CLCDC_UPBASE 0x10 82#define CLCDC_LPBASE 0x14 83#ifdef PL110_VENDOR_ARM926PXP 84#define CLCDC_CONTROL 0x18 85#define CLCDC_IMSC 0x1C 86#else 87#define CLCDC_IMSC 0x18 88#define CLCDC_CONTROL 0x1C 89#endif 90#define CONTROL_WATERMARK (1 << 16) 91#define CONTROL_VCOMP_VS (0 << 12) 92#define CONTROL_VCOMP_BP (1 << 12) 93#define CONTROL_VCOMP_SAV (2 << 12) 94#define CONTROL_VCOMP_FP (3 << 12) 95#define CONTROL_PWR (1 << 11) 96#define CONTROL_BEPO (1 << 10) 97#define CONTROL_BEBO (1 << 9) 98#define CONTROL_BGR (1 << 8) 99#define CONTROL_DUAL (1 << 7) 100#define CONTROL_MONO8 (1 << 6) 101#define CONTROL_TFT (1 << 5) 102#define CONTROL_BW (1 << 4) 103#define CONTROL_BPP1 (0x00 << 1) 104#define CONTROL_BPP2 (0x01 << 1) 105#define CONTROL_BPP4 (0x02 << 1) 106#define CONTROL_BPP8 (0x03 << 1) 107#define CONTROL_BPP16 (0x04 << 1) 108#define CONTROL_BPP24 (0x05 << 1) 109#define CONTROL_EN (1 << 0) 110#define CLCDC_RIS 0x20 111#define CLCDC_MIS 0x24 112#define INTR_MBERR (1 << 4) 113#define INTR_VCOMP (1 << 3) 114#define INTR_LNB (1 << 2) 115#define INTR_FUF (1 << 1) 116#define CLCDC_ICR 0x28 117 118#ifdef DEBUG 119#define dprintf(fmt, args...) do { printf("%s(): ", __func__); \ 120 printf(fmt,##args); } while (0) 121#else 122#define dprintf(fmt, args...) 123#endif 124 125#define versatile_clcdc_sys_read_4(sc, reg) \ 126 bus_read_4((sc)->mem_res[MEM_SYS], (reg)) 127#define versatile_clcdc_sys_write_4(sc, reg, val) \ 128 bus_write_4((sc)->mem_res[MEM_SYS], (reg), (val)) 129 130#define versatile_clcdc_read_4(sc, reg) \ 131 bus_read_4((sc)->mem_res[MEM_CLCD], (reg)) 132#define versatile_clcdc_write_4(sc, reg, val) \ 133 bus_write_4((sc)->mem_res[MEM_CLCD], (reg), (val)) 134 135struct versatile_clcdc_softc { 136 struct resource* mem_res[MEM_REGIONS]; 137 138 struct mtx mtx; 139 140 int width; 141 int height; 142 int mode; 143 144 bus_dma_tag_t dma_tag; 145 bus_dmamap_t dma_map; 146 bus_addr_t fb_phys; 147 uint8_t *fb_base; 148 149}; 150 151struct video_adapter_softc { 152 /* Videoadpater part */ 153 video_adapter_t va; 154 int console; 155 156 intptr_t fb_addr; 157 unsigned int fb_size; 158 159 unsigned int height; 160 unsigned int width; 161 unsigned int depth; 162 unsigned int stride; 163 164 unsigned int xmargin; 165 unsigned int ymargin; 166 167 unsigned char *font; 168 int initialized; 169}; 170 171struct argb { 172 uint8_t a; 173 uint8_t r; 174 uint8_t g; 175 uint8_t b; 176}; 177 178static struct argb versatilefb_palette[16] = { 179 {0x00, 0x00, 0x00, 0x00}, 180 {0x00, 0x00, 0x00, 0xaa}, 181 {0x00, 0x00, 0xaa, 0x00}, 182 {0x00, 0x00, 0xaa, 0xaa}, 183 {0x00, 0xaa, 0x00, 0x00}, 184 {0x00, 0xaa, 0x00, 0xaa}, 185 {0x00, 0xaa, 0x55, 0x00}, 186 {0x00, 0xaa, 0xaa, 0xaa}, 187 {0x00, 0x55, 0x55, 0x55}, 188 {0x00, 0x55, 0x55, 0xff}, 189 {0x00, 0x55, 0xff, 0x55}, 190 {0x00, 0x55, 0xff, 0xff}, 191 {0x00, 0xff, 0x55, 0x55}, 192 {0x00, 0xff, 0x55, 0xff}, 193 {0x00, 0xff, 0xff, 0x55}, 194 {0x00, 0xff, 0xff, 0xff} 195}; 196 197#define FB_WIDTH 640 198#define FB_HEIGHT 480 199#define FB_DEPTH 16 200 201#define VERSATILE_FONT_HEIGHT 16 202 203static struct video_adapter_softc va_softc; 204 205static struct resource_spec versatile_clcdc_mem_spec[] = { 206 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 207 { SYS_RES_MEMORY, 1, RF_ACTIVE }, 208 { -1, 0, 0 } 209}; 210 211static int versatilefb_configure(int); 212static void versatilefb_update_margins(video_adapter_t *adp); 213 214static void 215versatile_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) 216{ 217 bus_addr_t *addr; 218 219 if (err) 220 return; 221 222 addr = (bus_addr_t*)arg; 223 *addr = segs[0].ds_addr; 224} 225 226static int 227versatile_clcdc_probe(device_t dev) 228{ 229 230 if (ofw_bus_is_compatible(dev, "arm,pl110")) { 231 device_set_desc(dev, "PL110 CLCD controller"); 232 return (BUS_PROBE_DEFAULT); 233 } 234 235 return (ENXIO); 236} 237 238static int 239versatile_clcdc_attach(device_t dev) 240{ 241 struct versatile_clcdc_softc *sc = device_get_softc(dev); 242 struct video_adapter_softc *va_sc = &va_softc; 243 int err; 244 uint32_t reg; 245 int clcdid; 246 int dma_size; 247 248 /* Request memory resources */ 249 err = bus_alloc_resources(dev, versatile_clcdc_mem_spec, 250 sc->mem_res); 251 if (err) { 252 device_printf(dev, "Error: could not allocate memory resources\n"); 253 return (ENXIO); 254 } 255 256 reg = versatile_clcdc_sys_read_4(sc, SYS_CLCD); 257 clcdid = (reg >> SYS_CLCD_CLCDID_SHIFT) & SYS_CLCD_CLCDID_MASK; 258 switch (clcdid) { 259 case 31: 260 device_printf(dev, "QEMU VGA 640x480\n"); 261 sc->width = 640; 262 sc->height = 480; 263 break; 264 default: 265 device_printf(dev, "Unsupported: %d\n", clcdid); 266 goto fail; 267 } 268 269 reg &= ~SYS_CLCD_LCD_MODE_MASK; 270 reg |= CLCD_MODE_RGB565; 271 sc->mode = CLCD_MODE_RGB565; 272 versatile_clcdc_sys_write_4(sc, SYS_CLCD, reg); 273 dma_size = sc->width*sc->height*2; 274 275 /* 276 * Power on LCD 277 */ 278 reg |= SYS_CLCD_PWR3V5VSWITCH | SYS_CLCD_NLCDIOON; 279 versatile_clcdc_sys_write_4(sc, SYS_CLCD, reg); 280 281 /* 282 * XXX: hardcoded timing for VGA. For other modes/panels 283 * we need to keep table of timing register values 284 */ 285 /* 286 * XXX: set SYS_OSC1 287 */ 288 versatile_clcdc_write_4(sc, CLCDC_TIMING0, 0x3F1F3F9C); 289 versatile_clcdc_write_4(sc, CLCDC_TIMING1, 0x090B61DF); 290 versatile_clcdc_write_4(sc, CLCDC_TIMING2, 0x067F1800); 291 /* XXX: timing 3? */ 292 293 /* 294 * Now allocate framebuffer memory 295 */ 296 err = bus_dma_tag_create( 297 bus_get_dma_tag(dev), 298 4, 0, /* alignment, boundary */ 299 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 300 BUS_SPACE_MAXADDR, /* highaddr */ 301 NULL, NULL, /* filter, filterarg */ 302 dma_size, 1, /* maxsize, nsegments */ 303 dma_size, 0, /* maxsegsize, flags */ 304 NULL, NULL, /* lockfunc, lockarg */ 305 &sc->dma_tag); 306 307 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->fb_base, 308 0, &sc->dma_map); 309 if (err) { 310 device_printf(dev, "cannot allocate framebuffer\n"); 311 goto fail; 312 } 313 314 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->fb_base, 315 dma_size, versatile_fb_dmamap_cb, &sc->fb_phys, BUS_DMA_NOWAIT); 316 317 if (err) { 318 device_printf(dev, "cannot load DMA map\n"); 319 goto fail; 320 } 321 322 /* Make sure it's blank */ 323 memset(sc->fb_base, 0x00, dma_size); 324 325 versatile_clcdc_write_4(sc, CLCDC_UPBASE, sc->fb_phys); 326 327 err = (sc_attach_unit(device_get_unit(dev), 328 device_get_flags(dev) | SC_AUTODETECT_KBD)); 329 330 if (err) { 331 device_printf(dev, "failed to attach syscons\n"); 332 goto fail; 333 } 334 335 /* 336 * XXX: hardcoded for VGA 337 */ 338 reg = CONTROL_VCOMP_BP | CONTROL_TFT | CONTROL_BGR | CONTROL_EN; 339 reg |= CONTROL_BPP16; 340 versatile_clcdc_write_4(sc, CLCDC_CONTROL, reg); 341 DELAY(20); 342 reg |= CONTROL_PWR; 343 versatile_clcdc_write_4(sc, CLCDC_CONTROL, reg); 344 345 va_sc->fb_addr = (vm_offset_t)sc->fb_base; 346 va_sc->fb_size = dma_size; 347 va_sc->width = sc->width; 348 va_sc->height = sc->height; 349 va_sc->depth = 16; 350 va_sc->stride = sc->width * 2; 351 versatilefb_update_margins(&va_sc->va); 352 353 return (0); 354 355fail: 356 if (sc->fb_base) 357 bus_dmamem_free(sc->dma_tag, sc->fb_base, sc->dma_map); 358 if (sc->dma_map) 359 bus_dmamap_destroy(sc->dma_tag, sc->dma_map); 360 if (sc->dma_tag) 361 bus_dma_tag_destroy(sc->dma_tag); 362 return (err); 363} 364 365static device_method_t versatile_clcdc_methods[] = { 366 DEVMETHOD(device_probe, versatile_clcdc_probe), 367 DEVMETHOD(device_attach, versatile_clcdc_attach), 368 369 DEVMETHOD_END 370}; 371 372static driver_t versatile_clcdc_driver = { 373 "clcdc", 374 versatile_clcdc_methods, 375 sizeof(struct versatile_clcdc_softc), 376}; 377 378static devclass_t versatile_clcdc_devclass; 379 380DRIVER_MODULE(versatile_clcdc, simplebus, versatile_clcdc_driver, versatile_clcdc_devclass, 0, 0); 381 382/* 383 * Video driver routines and glue. 384 */ 385static vi_probe_t versatilefb_probe; 386static vi_init_t versatilefb_init; 387static vi_get_info_t versatilefb_get_info; 388static vi_query_mode_t versatilefb_query_mode; 389static vi_set_mode_t versatilefb_set_mode; 390static vi_save_font_t versatilefb_save_font; 391static vi_load_font_t versatilefb_load_font; 392static vi_show_font_t versatilefb_show_font; 393static vi_save_palette_t versatilefb_save_palette; 394static vi_load_palette_t versatilefb_load_palette; 395static vi_set_border_t versatilefb_set_border; 396static vi_save_state_t versatilefb_save_state; 397static vi_load_state_t versatilefb_load_state; 398static vi_set_win_org_t versatilefb_set_win_org; 399static vi_read_hw_cursor_t versatilefb_read_hw_cursor; 400static vi_set_hw_cursor_t versatilefb_set_hw_cursor; 401static vi_set_hw_cursor_shape_t versatilefb_set_hw_cursor_shape; 402static vi_blank_display_t versatilefb_blank_display; 403static vi_mmap_t versatilefb_mmap; 404static vi_ioctl_t versatilefb_ioctl; 405static vi_clear_t versatilefb_clear; 406static vi_fill_rect_t versatilefb_fill_rect; 407static vi_bitblt_t versatilefb_bitblt; 408static vi_diag_t versatilefb_diag; 409static vi_save_cursor_palette_t versatilefb_save_cursor_palette; 410static vi_load_cursor_palette_t versatilefb_load_cursor_palette; 411static vi_copy_t versatilefb_copy; 412static vi_putp_t versatilefb_putp; 413static vi_putc_t versatilefb_putc; 414static vi_puts_t versatilefb_puts; 415static vi_putm_t versatilefb_putm; 416 417static video_switch_t versatilefbvidsw = { 418 .probe = versatilefb_probe, 419 .init = versatilefb_init, 420 .get_info = versatilefb_get_info, 421 .query_mode = versatilefb_query_mode, 422 .set_mode = versatilefb_set_mode, 423 .save_font = versatilefb_save_font, 424 .load_font = versatilefb_load_font, 425 .show_font = versatilefb_show_font, 426 .save_palette = versatilefb_save_palette, 427 .load_palette = versatilefb_load_palette, 428 .set_border = versatilefb_set_border, 429 .save_state = versatilefb_save_state, 430 .load_state = versatilefb_load_state, 431 .set_win_org = versatilefb_set_win_org, 432 .read_hw_cursor = versatilefb_read_hw_cursor, 433 .set_hw_cursor = versatilefb_set_hw_cursor, 434 .set_hw_cursor_shape = versatilefb_set_hw_cursor_shape, 435 .blank_display = versatilefb_blank_display, 436 .mmap = versatilefb_mmap, 437 .ioctl = versatilefb_ioctl, 438 .clear = versatilefb_clear, 439 .fill_rect = versatilefb_fill_rect, 440 .bitblt = versatilefb_bitblt, 441 .diag = versatilefb_diag, 442 .save_cursor_palette = versatilefb_save_cursor_palette, 443 .load_cursor_palette = versatilefb_load_cursor_palette, 444 .copy = versatilefb_copy, 445 .putp = versatilefb_putp, 446 .putc = versatilefb_putc, 447 .puts = versatilefb_puts, 448 .putm = versatilefb_putm, 449}; 450 451VIDEO_DRIVER(versatilefb, versatilefbvidsw, versatilefb_configure); 452 453extern sc_rndr_sw_t txtrndrsw; 454RENDERER(versatilefb, 0, txtrndrsw, gfb_set); 455RENDERER_MODULE(versatilefb, gfb_set); 456 457static uint16_t versatilefb_static_window[ROW*COL]; 458extern u_char dflt_font_16[]; 459 460/* 461 * Update videoadapter settings after changing resolution 462 */ 463static void 464versatilefb_update_margins(video_adapter_t *adp) 465{ 466 struct video_adapter_softc *sc; 467 video_info_t *vi; 468 469 sc = (struct video_adapter_softc *)adp; 470 vi = &adp->va_info; 471 472 sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2; 473 sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2; 474} 475 476static int 477versatilefb_configure(int flags) 478{ 479 struct video_adapter_softc *va_sc; 480 481 va_sc = &va_softc; 482 483 if (va_sc->initialized) 484 return (0); 485 486 va_sc->width = FB_WIDTH; 487 va_sc->height = FB_HEIGHT; 488 va_sc->depth = FB_DEPTH; 489 490 versatilefb_init(0, &va_sc->va, 0); 491 492 va_sc->initialized = 1; 493 494 return (0); 495} 496 497static int 498versatilefb_probe(int unit, video_adapter_t **adp, void *arg, int flags) 499{ 500 501 return (0); 502} 503 504static int 505versatilefb_init(int unit, video_adapter_t *adp, int flags) 506{ 507 struct video_adapter_softc *sc; 508 video_info_t *vi; 509 510 sc = (struct video_adapter_softc *)adp; 511 vi = &adp->va_info; 512 513 vid_init_struct(adp, "versatilefb", -1, unit); 514 515 sc->font = dflt_font_16; 516 vi->vi_cheight = VERSATILE_FONT_HEIGHT; 517 vi->vi_cwidth = 8; 518 519 vi->vi_width = sc->width/8; 520 vi->vi_height = sc->height/vi->vi_cheight; 521 522 /* 523 * Clamp width/height to syscons maximums 524 */ 525 if (vi->vi_width > COL) 526 vi->vi_width = COL; 527 if (vi->vi_height > ROW) 528 vi->vi_height = ROW; 529 530 sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2; 531 sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2; 532 533 534 adp->va_window = (vm_offset_t) versatilefb_static_window; 535 adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */; 536 537 vid_register(&sc->va); 538 539 return (0); 540} 541 542static int 543versatilefb_get_info(video_adapter_t *adp, int mode, video_info_t *info) 544{ 545 bcopy(&adp->va_info, info, sizeof(*info)); 546 return (0); 547} 548 549static int 550versatilefb_query_mode(video_adapter_t *adp, video_info_t *info) 551{ 552 return (0); 553} 554 555static int 556versatilefb_set_mode(video_adapter_t *adp, int mode) 557{ 558 return (0); 559} 560 561static int 562versatilefb_save_font(video_adapter_t *adp, int page, int size, int width, 563 u_char *data, int c, int count) 564{ 565 return (0); 566} 567 568static int 569versatilefb_load_font(video_adapter_t *adp, int page, int size, int width, 570 u_char *data, int c, int count) 571{ 572 struct video_adapter_softc *sc = (struct video_adapter_softc *)adp; 573 574 sc->font = data; 575 576 return (0); 577} 578 579static int 580versatilefb_show_font(video_adapter_t *adp, int page) 581{ 582 return (0); 583} 584 585static int 586versatilefb_save_palette(video_adapter_t *adp, u_char *palette) 587{ 588 return (0); 589} 590 591static int 592versatilefb_load_palette(video_adapter_t *adp, u_char *palette) 593{ 594 return (0); 595} 596 597static int 598versatilefb_set_border(video_adapter_t *adp, int border) 599{ 600 return (versatilefb_blank_display(adp, border)); 601} 602 603static int 604versatilefb_save_state(video_adapter_t *adp, void *p, size_t size) 605{ 606 return (0); 607} 608 609static int 610versatilefb_load_state(video_adapter_t *adp, void *p) 611{ 612 return (0); 613} 614 615static int 616versatilefb_set_win_org(video_adapter_t *adp, off_t offset) 617{ 618 return (0); 619} 620 621static int 622versatilefb_read_hw_cursor(video_adapter_t *adp, int *col, int *row) 623{ 624 *col = *row = 0; 625 626 return (0); 627} 628 629static int 630versatilefb_set_hw_cursor(video_adapter_t *adp, int col, int row) 631{ 632 return (0); 633} 634 635static int 636versatilefb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, 637 int celsize, int blink) 638{ 639 return (0); 640} 641 642static int 643versatilefb_blank_display(video_adapter_t *adp, int mode) 644{ 645 646 struct video_adapter_softc *sc; 647 648 sc = (struct video_adapter_softc *)adp; 649 if (sc && sc->fb_addr) 650 memset((void*)sc->fb_addr, 0, sc->fb_size); 651 652 return (0); 653} 654 655static int 656versatilefb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr, 657 int prot, vm_memattr_t *memattr) 658{ 659 struct video_adapter_softc *sc; 660 661 sc = (struct video_adapter_softc *)adp; 662 663 /* 664 * This might be a legacy VGA mem request: if so, just point it at the 665 * framebuffer, since it shouldn't be touched 666 */ 667 if (offset < sc->stride*sc->height) { 668 *paddr = sc->fb_addr + offset; 669 return (0); 670 } 671 672 return (EINVAL); 673} 674 675static int 676versatilefb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data) 677{ 678 679 return (0); 680} 681 682static int 683versatilefb_clear(video_adapter_t *adp) 684{ 685 686 return (versatilefb_blank_display(adp, 0)); 687} 688 689static int 690versatilefb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 691{ 692 693 return (0); 694} 695 696static int 697versatilefb_bitblt(video_adapter_t *adp, ...) 698{ 699 700 return (0); 701} 702 703static int 704versatilefb_diag(video_adapter_t *adp, int level) 705{ 706 707 return (0); 708} 709 710static int 711versatilefb_save_cursor_palette(video_adapter_t *adp, u_char *palette) 712{ 713 714 return (0); 715} 716 717static int 718versatilefb_load_cursor_palette(video_adapter_t *adp, u_char *palette) 719{ 720 721 return (0); 722} 723 724static int 725versatilefb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n) 726{ 727 728 return (0); 729} 730 731static int 732versatilefb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a, 733 int size, int bpp, int bit_ltor, int byte_ltor) 734{ 735 736 return (0); 737} 738 739static int 740versatilefb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) 741{ 742 struct video_adapter_softc *sc; 743 int row; 744 int col; 745 int i, j, k; 746 uint8_t *addr; 747 u_char *p; 748 uint8_t fg, bg, color; 749 uint16_t rgb; 750 751 sc = (struct video_adapter_softc *)adp; 752 753 if (sc->fb_addr == 0) 754 return (0); 755 756 row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight; 757 col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth; 758 p = sc->font + c*VERSATILE_FONT_HEIGHT; 759 addr = (uint8_t *)sc->fb_addr 760 + (row + sc->ymargin)*(sc->stride) 761 + (sc->depth/8) * (col + sc->xmargin); 762 763 fg = a & 0xf ; 764 bg = (a >> 8) & 0xf; 765 766 for (i = 0; i < VERSATILE_FONT_HEIGHT; i++) { 767 for (j = 0, k = 7; j < 8; j++, k--) { 768 if ((p[i] & (1 << k)) == 0) 769 color = bg; 770 else 771 color = fg; 772 773 switch (sc->depth) { 774 case 16: 775 rgb = (versatilefb_palette[color].r >> 3) << 11; 776 rgb |= (versatilefb_palette[color].g >> 2) << 5; 777 rgb |= (versatilefb_palette[color].b >> 3); 778 addr[2*j] = rgb & 0xff; 779 addr[2*j + 1] = (rgb >> 8) & 0xff; 780 default: 781 /* Not supported yet */ 782 break; 783 } 784 } 785 786 addr += (sc->stride); 787 } 788 789 return (0); 790} 791 792static int 793versatilefb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len) 794{ 795 int i; 796 797 for (i = 0; i < len; i++) 798 versatilefb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); 799 800 return (0); 801} 802 803static int 804versatilefb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, 805 uint32_t pixel_mask, int size, int width) 806{ 807 808 return (0); 809} 810 811/* 812 * Define a stub keyboard driver in case one hasn't been 813 * compiled into the kernel 814 */ 815#include <sys/kbio.h> 816#include <dev/kbd/kbdreg.h> 817 818static int dummy_kbd_configure(int flags); 819 820keyboard_switch_t bcmdummysw; 821 822static int 823dummy_kbd_configure(int flags) 824{ 825 826 return (0); 827} 828KEYBOARD_DRIVER(bcmdummy, bcmdummysw, dummy_kbd_configure); 829