1/* $NetBSD: omapfb.c,v 1.2 2011/04/12 18:10:15 ahoka Exp $ */ 2 3/* 4 * Copyright (c) 2010 Michael Lorenz 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28/* 29 * A console driver for OMAP 3530's built-in video controller 30 * tested on beagleboard only so far 31 */ 32 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.2 2011/04/12 18:10:15 ahoka Exp $"); 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/kernel.h> 39#include <sys/device.h> 40#include <sys/malloc.h> 41#include <sys/lwp.h> 42#include <sys/kauth.h> 43 44#include <uvm/uvm_extern.h> 45 46#include <dev/videomode/videomode.h> 47 48#include <sys/bus.h> 49#include <arm/omap/omapfbreg.h> 50#include <arm/omap/omap2_obiovar.h> 51#include <arm/omap/omap2_obioreg.h> 52 53#include <dev/wscons/wsdisplayvar.h> 54#include <dev/wscons/wsconsio.h> 55#include <dev/wsfont/wsfont.h> 56#include <dev/rasops/rasops.h> 57#include <dev/wscons/wsdisplay_vconsvar.h> 58 59struct omapfb_softc { 60 device_t sc_dev; 61 62 bus_space_tag_t sc_iot; 63 bus_dma_tag_t sc_dmat; 64 bus_space_handle_t sc_regh; 65 bus_dmamap_t sc_dmamap; 66 bus_dma_segment_t sc_dmamem[1]; 67 size_t sc_vramsize; 68 69 int sc_width, sc_height, sc_depth, sc_stride; 70 int sc_locked; 71 void *sc_fbaddr, *sc_vramaddr; 72 uint32_t *sc_clut; 73 struct vcons_screen sc_console_screen; 74 struct wsscreen_descr sc_defaultscreen_descr; 75 const struct wsscreen_descr *sc_screens[1]; 76 struct wsscreen_list sc_screenlist; 77 struct vcons_data vd; 78 int sc_mode; 79 uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256]; 80}; 81 82static int omapfb_match(device_t, cfdata_t, void *); 83static void omapfb_attach(device_t, device_t, void *); 84 85CFATTACH_DECL_NEW(omapfb, sizeof(struct omapfb_softc), 86 omapfb_match, omapfb_attach, NULL, NULL); 87 88static int omapfb_ioctl(void *, void *, u_long, void *, int, 89 struct lwp *); 90static paddr_t omapfb_mmap(void *, void *, off_t, int); 91static void omapfb_init_screen(void *, struct vcons_screen *, int, long *); 92 93static void omapfb_init(struct omapfb_softc *); 94 95static int omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *); 96static int omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *); 97static void omapfb_restore_palette(struct omapfb_softc *); 98static void omapfb_putpalreg(struct omapfb_softc *, int, uint8_t, 99 uint8_t, uint8_t); 100 101#if 0 102static void omapfb_flush_engine(struct omapfb_softc *); 103static void omapfb_rectfill(struct omapfb_softc *, int, int, int, int, 104 uint32_t); 105static void omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int, 106 int, int); 107 108static void omapfb_cursor(void *, int, int, int); 109static void omapfb_putchar(void *, int, int, u_int, long); 110static void omapfb_copycols(void *, int, int, int, int); 111static void omapfb_erasecols(void *, int, int, int, long); 112static void omapfb_copyrows(void *, int, int, int); 113static void omapfb_eraserows(void *, int, int, long); 114#endif 115 116struct wsdisplay_accessops omapfb_accessops = { 117 omapfb_ioctl, 118 omapfb_mmap, 119 NULL, /* alloc_screen */ 120 NULL, /* free_screen */ 121 NULL, /* show_screen */ 122 NULL, /* load_font */ 123 NULL, /* pollc */ 124 NULL /* scroll */ 125}; 126 127uint32_t venc_mode_ntsc[] = { 128 0x00000000, 0x00000001, 0x00008040, 0x00000359, 129 0x0000020c, 0x00000000, 0x043f2631, 0x00000000, 130 0x00000102, 0x0000016c, 0x0000012f, 0x00000043, 131 0x00000038, 0x00000007, 0x00000001, 0x00000038, 132 0x21f07c1f, 0x00000000, 0x01310011, 0x0000f003, 133 0x00000000, 0x069300f4, 0x0016020c, 0x00060107, 134 0x008e0350, 0x000f0359, 0x01a00000, 0x020701a0, 135 0x01ac0024, 0x020d01ac, 0x00000006, 0x03480078, 136 0x02060024, 0x0001008a, 0x01ac0106, 0x01060006, 137 0x00140001, 0x00010001, 0x00f90000, 0x0000000d, 138 0x00000000}; 139 140extern const u_char rasops_cmap[768]; 141 142static int 143omapfb_match(device_t parent, cfdata_t match, void *aux) 144{ 145 struct obio_attach_args *obio = aux; 146 147 if ((obio->obio_addr == -1) || (obio->obio_size == 0)) 148 return 0; 149 return 1; 150} 151 152static void 153omapfb_attach(device_t parent, device_t self, void *aux) 154{ 155 struct omapfb_softc *sc = device_private(self); 156 struct obio_attach_args *obio = aux; 157 struct rasops_info *ri; 158 struct wsemuldisplaydev_attach_args aa; 159 prop_dictionary_t dict; 160 unsigned long defattr; 161 bool is_console; 162 uint32_t sz, reg; 163 int segs, i, j, adr; 164 165 sc->sc_iot = obio->obio_iot; 166 sc->sc_dev = self; 167 sc->sc_dmat = obio->obio_dmat; 168 169 printf(": OMAP onboard video\n"); 170 if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, 171 &sc->sc_regh)) { 172 aprint_error(": couldn't map register space\n"); 173 return; 174 } 175 176 sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE); 177 sc->sc_width = (sz & 0xfff) + 1; 178 sc->sc_height = ((sz & 0x0fff0000 ) >> 16) + 1; 179 sc->sc_depth = 16; 180 sc->sc_stride = sc->sc_width << 1; 181 182 if (sc->sc_width == 1 || sc->sc_height == 1) { 183 aprint_error_dev(self, "bogus display size, not attaching\n"); 184 return; 185 } 186 187 printf("%s: firmware set up %d x %d\n", device_xname(self), 188 sc->sc_width, sc->sc_height); 189#if 0 190 printf("DSS revision: %08x\n", 191 bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_REVISION)); 192#endif 193 dict = device_properties(self); 194 prop_dictionary_get_bool(dict, "is_console", &is_console); 195 is_console = 1; 196 197 /* setup video DMA */ 198 sc->sc_vramsize = (12 << 20) + 0x1000; /* 12MB + CLUT */ 199 200 if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0, 201 sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) { 202 panic("boo!\n"); 203 aprint_error_dev(sc->sc_dev, 204 "failed to allocate video memory\n"); 205 return; 206 } 207 208 if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize, 209 &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) { 210 aprint_error_dev(sc->sc_dev, "failed to map video RAM\n"); 211 return; 212 } 213 sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + 0x1000; 214 sc->sc_clut = sc->sc_vramaddr; 215 216 if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize, 217 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { 218 aprint_error_dev(sc->sc_dev, "failed to create DMA map\n"); 219 return; 220 } 221 222 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr, 223 sc->sc_vramsize, NULL, BUS_DMA_NOWAIT) != 0) { 224 aprint_error_dev(sc->sc_dev, "failed to load DMA map\n"); 225 return; 226 } 227 228 if (sc->sc_depth == 8) { 229 j = 0; 230 for (i = 0; i < 256; i++) { 231 sc->sc_cmap_red[i] = rasops_cmap[j]; 232 sc->sc_cmap_green[i] = rasops_cmap[j + 1]; 233 sc->sc_cmap_blue[i] = rasops_cmap[j + 2]; 234 j += 3; 235 } 236 } else { 237 for (i = 0; i < 256; i++) { 238 sc->sc_cmap_red[i] = i; 239 sc->sc_cmap_green[i] = i; 240 sc->sc_cmap_blue[i] = i; 241 } 242 } 243 omapfb_restore_palette(sc); 244 245 /* now that we have video memory, stick it to the video controller */ 246 247 reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG); 248 reg &= ~(OMAP_DISPC_SYSC_STANDBY_MASK | OMAP_DISPC_SYSC_IDLE_MASK); 249 reg |= OMAP_DISPC_SYSC_SMART_STANDBY | OMAP_DISPC_SYSC_SMART_IDLE | 250 OMAP_DISPC_SYSC_WAKEUP_ENABLE | OMAP_SYSCONF_AUTOIDLE; 251 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG, reg); 252 253 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_SYSCONFIG, 254 OMAP_SYSCONF_AUTOIDLE); 255 reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG); 256 reg = 0x8; 257 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG, reg); 258 259 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0, 260 sc->sc_dmamem->ds_addr + 0x1000); 261 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_TABLE_BASE, 262 sc->sc_dmamem->ds_addr); 263 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION, 264 0); 265 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD, 0x60); 266 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES, 267 OMAP_DISPC_ATTR_ENABLE | 268 OMAP_DISPC_ATTR_BURST_16x32 | 269 /*OMAP_DISPC_ATTR_8BIT*/OMAP_DISPC_ATTR_RGB16 270 | OMAP_DISPC_ATTR_REPLICATION); 271#if 0 272 printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL)); 273 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL, 274 /*OMAP_DSSCTRL_DISPC_CLK_SWITCH |*/ 275 OMAP_DSSCTRL_CLOCK_MODE | 276 OMAP_DSSCTRL_VENC_CLOCK_4X | 277 OMAP_DSSCTRL_DAC_DEMEN); 278#endif 279 280 /* VENC to NTSC mode */ 281 adr = OMAPFB_VENC_F_CONTROL; 282#if 0 283 for (i = 0; i < __arraycount(venc_mode_ntsc); i++) { 284 bus_space_write_4(sc->sc_iot, sc->sc_regh, adr, 285 venc_mode_ntsc[i]); 286 adr += 4; 287 } 288 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_F_CONTROL, 289 venc_mode_ntsc[0]); 290 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_SYNC_CTRL, 291 venc_mode_ntsc[2]); 292 293 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_DEFAULT_COLOR_1, 294 0x00ff0000); 295#endif 296 reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); 297 bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, 298 reg | OMAP_DISPC_CTRL_GO_LCD); 299 300#ifdef OMAPFB_DEBUG 301 printf("attr: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES)); 302 printf("preload: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD)); 303 printf("config: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG)); 304 printf("control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL)); 305 printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL)); 306 printf("threshold: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_FIFO_THRESH)); 307 printf("GFX size: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE)); 308 printf("row inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ROW_INC)); 309 printf("pixel inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PIXEL_INC)); 310#endif 311 312 sc->sc_defaultscreen_descr = (struct wsscreen_descr){ 313 "default", 314 0, 0, 315 NULL, 316 8, 16, 317 WSSCREEN_WSCOLORS | WSSCREEN_HILIT, 318 NULL 319 }; 320 sc->sc_screens[0] = &sc->sc_defaultscreen_descr; 321 sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; 322 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 323 sc->sc_locked = 0; 324 325 vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, 326 &omapfb_accessops); 327 sc->vd.init_screen = omapfb_init_screen; 328 329 /* init engine here */ 330 omapfb_init(sc); 331 332 ri = &sc->sc_console_screen.scr_ri; 333 334 if (is_console) { 335 vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, 336 &defattr); 337 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 338 339#if 0 340 omapfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 341 ri->ri_devcmap[(defattr >> 16) & 0xff]); 342#endif 343 sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 344 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 345 sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 346 sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 347 wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, 348 defattr); 349 vcons_replay_msgbuf(&sc->sc_console_screen); 350 } else { 351 /* 352 * since we're not the console we can postpone the rest 353 * until someone actually allocates a screen for us 354 */ 355 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); 356 } 357 358 aa.console = is_console; 359 aa.scrdata = &sc->sc_screenlist; 360 aa.accessops = &omapfb_accessops; 361 aa.accesscookie = &sc->vd; 362 363 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); 364 365} 366 367static int 368omapfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 369 struct lwp *l) 370{ 371 struct vcons_data *vd = v; 372 struct omapfb_softc *sc = vd->cookie; 373 struct wsdisplay_fbinfo *wdf; 374 struct vcons_screen *ms = vd->active; 375 376 switch (cmd) { 377 378 case WSDISPLAYIO_GTYPE: 379 *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; 380 return 0; 381 382 case WSDISPLAYIO_GINFO: 383 if (ms == NULL) 384 return ENODEV; 385 wdf = (void *)data; 386 wdf->height = ms->scr_ri.ri_height; 387 wdf->width = ms->scr_ri.ri_width; 388 wdf->depth = ms->scr_ri.ri_depth; 389 wdf->cmsize = 256; 390 return 0; 391 392 case WSDISPLAYIO_GETCMAP: 393 return omapfb_getcmap(sc, 394 (struct wsdisplay_cmap *)data); 395 396 case WSDISPLAYIO_PUTCMAP: 397 return omapfb_putcmap(sc, 398 (struct wsdisplay_cmap *)data); 399 400 case WSDISPLAYIO_LINEBYTES: 401 *(u_int *)data = sc->sc_stride; 402 return 0; 403 404 case WSDISPLAYIO_SMODE: 405 { 406 int new_mode = *(int*)data; 407 408 /* notify the bus backend */ 409 if (new_mode != sc->sc_mode) { 410 sc->sc_mode = new_mode; 411 if(new_mode == WSDISPLAYIO_MODE_EMUL) { 412 vcons_redraw_screen(ms); 413 } 414 } 415 } 416 return 0; 417 } 418 return EPASSTHROUGH; 419} 420 421static paddr_t 422omapfb_mmap(void *v, void *vs, off_t offset, int prot) 423{ 424 paddr_t pa = -1; 425#if 0 426 struct vcons_data *vd = v; 427 struct omapfb_softc *sc = vd->cookie; 428 429 /* 'regular' framebuffer mmap()ing */ 430 if (offset < sc->sc_fbsize) { 431 pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot, 432 BUS_SPACE_MAP_LINEAR); 433 return pa; 434 } 435#endif 436 return pa; 437} 438 439static void 440omapfb_init_screen(void *cookie, struct vcons_screen *scr, 441 int existing, long *defattr) 442{ 443 struct omapfb_softc *sc = cookie; 444 struct rasops_info *ri = &scr->scr_ri; 445 446 ri->ri_depth = sc->sc_depth; 447 ri->ri_width = sc->sc_width; 448 ri->ri_height = sc->sc_height; 449 ri->ri_stride = sc->sc_stride; 450 ri->ri_flg = RI_CENTER | RI_FULLCLEAR; 451 452 ri->ri_bits = (char *)sc->sc_fbaddr; 453 454 scr->scr_flags |= VCONS_DONT_READ; 455 456 if (existing) { 457 ri->ri_flg |= RI_CLEAR; 458 } 459 460 rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); 461 ri->ri_caps = WSSCREEN_WSCOLORS; 462 463 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 464 sc->sc_width / ri->ri_font->fontwidth); 465 466 ri->ri_hw = scr; 467#if 0 468 ri->ri_ops.copyrows = omapfb_copyrows; 469 ri->ri_ops.copycols = omapfb_copycols; 470 ri->ri_ops.eraserows = omapfb_eraserows; 471 ri->ri_ops.erasecols = omapfb_erasecols; 472 ri->ri_ops.cursor = omapfb_cursor; 473 ri->ri_ops.putchar = omapfb_putchar; 474#endif 475} 476 477static int 478omapfb_putcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm) 479{ 480 u_char *r, *g, *b; 481 u_int index = cm->index; 482 u_int count = cm->count; 483 int i, error; 484 u_char rbuf[256], gbuf[256], bbuf[256]; 485 486 if (cm->index >= 256 || cm->count > 256 || 487 (cm->index + cm->count) > 256) 488 return EINVAL; 489 error = copyin(cm->red, &rbuf[index], count); 490 if (error) 491 return error; 492 error = copyin(cm->green, &gbuf[index], count); 493 if (error) 494 return error; 495 error = copyin(cm->blue, &bbuf[index], count); 496 if (error) 497 return error; 498 499 memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); 500 memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); 501 memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); 502 503 r = &sc->sc_cmap_red[index]; 504 g = &sc->sc_cmap_green[index]; 505 b = &sc->sc_cmap_blue[index]; 506 507 for (i = 0; i < count; i++) { 508 omapfb_putpalreg(sc, index, *r, *g, *b); 509 index++; 510 r++, g++, b++; 511 } 512 return 0; 513} 514 515static int 516omapfb_getcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm) 517{ 518 u_int index = cm->index; 519 u_int count = cm->count; 520 int error; 521 522 if (index >= 255 || count > 256 || index + count > 256) 523 return EINVAL; 524 525 error = copyout(&sc->sc_cmap_red[index], cm->red, count); 526 if (error) 527 return error; 528 error = copyout(&sc->sc_cmap_green[index], cm->green, count); 529 if (error) 530 return error; 531 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 532 if (error) 533 return error; 534 535 return 0; 536} 537 538static void 539omapfb_restore_palette(struct omapfb_softc *sc) 540{ 541 int i; 542 543 for (i = 0; i < (1 << sc->sc_depth); i++) { 544 omapfb_putpalreg(sc, i, sc->sc_cmap_red[i], 545 sc->sc_cmap_green[i], sc->sc_cmap_blue[i]); 546 } 547} 548 549static void 550omapfb_putpalreg(struct omapfb_softc *sc, int idx, uint8_t r, uint8_t g, 551 uint8_t b) 552{ 553 uint32_t reg; 554 555 if ((idx < 0) || (idx > 255)) 556 return; 557 /* whack the DAC */ 558 reg = (r << 16) | (g << 8) | b; 559 sc->sc_clut[idx] = reg; 560 561} 562 563static void 564omapfb_init(struct omapfb_softc *sc) 565{ 566} 567 568#if 0 569static void 570omapfb_rectfill(struct omapfb_softc *sc, int x, int y, int wi, int he, 571 uint32_t colour) 572{ 573} 574 575static void 576omapfb_bitblt(struct omapfb_softc *sc, int xs, int ys, int xd, int yd, 577 int wi, int he, int rop) 578{ 579} 580 581static void 582omapfb_cursor(void *cookie, int on, int row, int col) 583{ 584 struct rasops_info *ri = cookie; 585 struct vcons_screen *scr = ri->ri_hw; 586 struct omapfb_softc *sc = scr->scr_cookie; 587 int x, y, wi, he; 588 589 wi = ri->ri_font->fontwidth; 590 he = ri->ri_font->fontheight; 591 592 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 593 x = ri->ri_ccol * wi + ri->ri_xorigin; 594 y = ri->ri_crow * he + ri->ri_yorigin; 595 if (ri->ri_flg & RI_CURSOR) { 596 omapfb_bitblt(sc, x, y, x, y, wi, he, 3); 597 ri->ri_flg &= ~RI_CURSOR; 598 } 599 ri->ri_crow = row; 600 ri->ri_ccol = col; 601 if (on) { 602 x = ri->ri_ccol * wi + ri->ri_xorigin; 603 y = ri->ri_crow * he + ri->ri_yorigin; 604 omapfb_bitblt(sc, x, y, x, y, wi, he, 3); 605 ri->ri_flg |= RI_CURSOR; 606 } 607 } else { 608 scr->scr_ri.ri_crow = row; 609 scr->scr_ri.ri_ccol = col; 610 scr->scr_ri.ri_flg &= ~RI_CURSOR; 611 } 612 613} 614 615#if 0 616static void 617omapfb_putchar(void *cookie, int row, int col, u_int c, long attr) 618{ 619} 620#endif 621 622static void 623omapfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 624{ 625 struct rasops_info *ri = cookie; 626 struct vcons_screen *scr = ri->ri_hw; 627 struct omapfb_softc *sc = scr->scr_cookie; 628 int32_t xs, xd, y, width, height; 629 630 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 631 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 632 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 633 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 634 width = ri->ri_font->fontwidth * ncols; 635 height = ri->ri_font->fontheight; 636 omapfb_bitblt(sc, xs, y, xd, y, width, height, 12); 637 } 638} 639 640static void 641omapfb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) 642{ 643 struct rasops_info *ri = cookie; 644 struct vcons_screen *scr = ri->ri_hw; 645 struct omapfb_softc *sc = scr->scr_cookie; 646 int32_t x, y, width, height, fg, bg, ul; 647 648 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 649 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 650 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 651 width = ri->ri_font->fontwidth * ncols; 652 height = ri->ri_font->fontheight; 653 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 654 655 omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 656 } 657} 658 659static void 660omapfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 661{ 662 struct rasops_info *ri = cookie; 663 struct vcons_screen *scr = ri->ri_hw; 664 struct omapfb_softc *sc = scr->scr_cookie; 665 int32_t x, ys, yd, width, height; 666 667 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 668 x = ri->ri_xorigin; 669 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 670 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 671 width = ri->ri_emuwidth; 672 height = ri->ri_font->fontheight*nrows; 673 omapfb_bitblt(sc, x, ys, x, yd, width, height, 12); 674 } 675} 676 677static void 678omapfb_eraserows(void *cookie, int row, int nrows, long fillattr) 679{ 680 struct rasops_info *ri = cookie; 681 struct vcons_screen *scr = ri->ri_hw; 682 struct omapfb_softc *sc = scr->scr_cookie; 683 int32_t x, y, width, height, fg, bg, ul; 684 685 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 686 x = ri->ri_xorigin; 687 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 688 width = ri->ri_emuwidth; 689 height = ri->ri_font->fontheight * nrows; 690 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 691 692 omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 693 } 694} 695#endif 696