| @@ -308,1001 +308,1001 @@ pm3fb_attach(device_t parent, device_t s | | | @@ -308,1001 +308,1001 @@ pm3fb_attach(device_t parent, device_t s |
308 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, | | 308 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, |
309 | &defattr); | | 309 | &defattr); |
310 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | | 310 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; |
311 | | | 311 | |
312 | pm3fb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, | | 312 | pm3fb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, |
313 | ri->ri_devcmap[(defattr >> 16) & 0xff]); | | 313 | ri->ri_devcmap[(defattr >> 16) & 0xff]); |
314 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; | | 314 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; |
315 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; | | 315 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; |
316 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; | | 316 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; |
317 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; | | 317 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; |
318 | | | 318 | |
319 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, | | 319 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, |
320 | defattr); | | 320 | defattr); |
321 | vcons_replay_msgbuf(&sc->sc_console_screen); | | 321 | vcons_replay_msgbuf(&sc->sc_console_screen); |
322 | } else { | | 322 | } else { |
323 | if (sc->sc_console_screen.scr_ri.ri_rows == 0) { | | 323 | if (sc->sc_console_screen.scr_ri.ri_rows == 0) { |
324 | /* do some minimal setup to avoid weirdnesses later */ | | 324 | /* do some minimal setup to avoid weirdnesses later */ |
325 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, | | 325 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, |
326 | &defattr); | | 326 | &defattr); |
327 | } | | 327 | } |
328 | } | | 328 | } |
329 | | | 329 | |
330 | pm3fb_init_palette(sc); | | 330 | pm3fb_init_palette(sc); |
331 | | | 331 | |
332 | aa.console = is_console; | | 332 | aa.console = is_console; |
333 | aa.scrdata = &sc->sc_screenlist; | | 333 | aa.scrdata = &sc->sc_screenlist; |
334 | aa.accessops = &pm3fb_accessops; | | 334 | aa.accessops = &pm3fb_accessops; |
335 | aa.accesscookie = &sc->vd; | | 335 | aa.accesscookie = &sc->vd; |
336 | | | 336 | |
337 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); | | 337 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); |
338 | } | | 338 | } |
339 | | | 339 | |
340 | static int | | 340 | static int |
341 | pm3fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | | 341 | pm3fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, |
342 | struct lwp *l) | | 342 | struct lwp *l) |
343 | { | | 343 | { |
344 | struct vcons_data *vd = v; | | 344 | struct vcons_data *vd = v; |
345 | struct pm3fb_softc *sc = vd->cookie; | | 345 | struct pm3fb_softc *sc = vd->cookie; |
346 | struct wsdisplay_fbinfo *wdf; | | 346 | struct wsdisplay_fbinfo *wdf; |
347 | struct vcons_screen *ms = vd->active; | | 347 | struct vcons_screen *ms = vd->active; |
348 | | | 348 | |
349 | switch (cmd) { | | 349 | switch (cmd) { |
350 | case WSDISPLAYIO_GTYPE: | | 350 | case WSDISPLAYIO_GTYPE: |
351 | *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; | | 351 | *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; |
352 | return 0; | | 352 | return 0; |
353 | | | 353 | |
354 | /* PCI config read/write passthrough. */ | | 354 | /* PCI config read/write passthrough. */ |
355 | case PCI_IOC_CFGREAD: | | 355 | case PCI_IOC_CFGREAD: |
356 | case PCI_IOC_CFGWRITE: | | 356 | case PCI_IOC_CFGWRITE: |
357 | return pci_devioctl(sc->sc_pc, sc->sc_pcitag, | | 357 | return pci_devioctl(sc->sc_pc, sc->sc_pcitag, |
358 | cmd, data, flag, l); | | 358 | cmd, data, flag, l); |
359 | | | 359 | |
360 | case WSDISPLAYIO_GET_BUSID: | | 360 | case WSDISPLAYIO_GET_BUSID: |
361 | return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc, | | 361 | return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc, |
362 | sc->sc_pcitag, data); | | 362 | sc->sc_pcitag, data); |
363 | | | 363 | |
364 | case WSDISPLAYIO_GINFO: | | 364 | case WSDISPLAYIO_GINFO: |
365 | if (ms == NULL) | | 365 | if (ms == NULL) |
366 | return ENODEV; | | 366 | return ENODEV; |
367 | wdf = (void *)data; | | 367 | wdf = (void *)data; |
368 | wdf->height = ms->scr_ri.ri_height; | | 368 | wdf->height = ms->scr_ri.ri_height; |
369 | wdf->width = ms->scr_ri.ri_width; | | 369 | wdf->width = ms->scr_ri.ri_width; |
370 | wdf->depth = ms->scr_ri.ri_depth; | | 370 | wdf->depth = ms->scr_ri.ri_depth; |
371 | wdf->cmsize = 256; | | 371 | wdf->cmsize = 256; |
372 | return 0; | | 372 | return 0; |
373 | | | 373 | |
374 | case WSDISPLAYIO_GETCMAP: | | 374 | case WSDISPLAYIO_GETCMAP: |
375 | return pm3fb_getcmap(sc, | | 375 | return pm3fb_getcmap(sc, |
376 | (struct wsdisplay_cmap *)data); | | 376 | (struct wsdisplay_cmap *)data); |
377 | | | 377 | |
378 | case WSDISPLAYIO_PUTCMAP: | | 378 | case WSDISPLAYIO_PUTCMAP: |
379 | return pm3fb_putcmap(sc, | | 379 | return pm3fb_putcmap(sc, |
380 | (struct wsdisplay_cmap *)data); | | 380 | (struct wsdisplay_cmap *)data); |
381 | | | 381 | |
382 | case WSDISPLAYIO_LINEBYTES: | | 382 | case WSDISPLAYIO_LINEBYTES: |
383 | *(u_int *)data = sc->sc_stride; | | 383 | *(u_int *)data = sc->sc_stride; |
384 | return 0; | | 384 | return 0; |
385 | | | 385 | |
386 | case WSDISPLAYIO_SMODE: { | | 386 | case WSDISPLAYIO_SMODE: { |
387 | int new_mode = *(int*)data; | | 387 | int new_mode = *(int*)data; |
388 | if (new_mode != sc->sc_mode) { | | 388 | if (new_mode != sc->sc_mode) { |
389 | sc->sc_mode = new_mode; | | 389 | sc->sc_mode = new_mode; |
390 | if(new_mode == WSDISPLAYIO_MODE_EMUL) { | | 390 | if(new_mode == WSDISPLAYIO_MODE_EMUL) { |
391 | /* first set the video mode */ | | 391 | /* first set the video mode */ |
392 | if (sc->sc_videomode != NULL) { | | 392 | if (sc->sc_videomode != NULL) { |
393 | pm3fb_set_mode(sc, sc->sc_videomode); | | 393 | pm3fb_set_mode(sc, sc->sc_videomode); |
394 | } | | 394 | } |
395 | /* then initialize the drawing engine */ | | 395 | /* then initialize the drawing engine */ |
396 | pm3fb_init(sc); | | 396 | pm3fb_init(sc); |
397 | pm3fb_init_palette(sc); | | 397 | pm3fb_init_palette(sc); |
398 | vcons_redraw_screen(ms); | | 398 | vcons_redraw_screen(ms); |
399 | } else | | 399 | } else |
400 | pm3fb_flush_engine(sc); | | 400 | pm3fb_flush_engine(sc); |
401 | } | | 401 | } |
402 | } | | 402 | } |
403 | return 0; | | 403 | return 0; |
404 | case WSDISPLAYIO_GET_EDID: { | | 404 | case WSDISPLAYIO_GET_EDID: { |
405 | struct wsdisplayio_edid_info *d = data; | | 405 | struct wsdisplayio_edid_info *d = data; |
406 | d->data_size = 128; | | 406 | d->data_size = 128; |
407 | if (d->buffer_size < 128) | | 407 | if (d->buffer_size < 128) |
408 | return EAGAIN; | | 408 | return EAGAIN; |
409 | return copyout(sc->sc_edid_data, d->edid_data, 128); | | 409 | return copyout(sc->sc_edid_data, d->edid_data, 128); |
410 | } | | 410 | } |
411 | | | 411 | |
412 | case WSDISPLAYIO_GET_FBINFO: { | | 412 | case WSDISPLAYIO_GET_FBINFO: { |
413 | struct wsdisplayio_fbinfo *fbi = data; | | 413 | struct wsdisplayio_fbinfo *fbi = data; |
414 | return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); | | 414 | return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); |
415 | } | | 415 | } |
416 | } | | 416 | } |
417 | return EPASSTHROUGH; | | 417 | return EPASSTHROUGH; |
418 | } | | 418 | } |
419 | | | 419 | |
420 | static paddr_t | | 420 | static paddr_t |
421 | pm3fb_mmap(void *v, void *vs, off_t offset, int prot) | | 421 | pm3fb_mmap(void *v, void *vs, off_t offset, int prot) |
422 | { | | 422 | { |
423 | struct vcons_data *vd = v; | | 423 | struct vcons_data *vd = v; |
424 | struct pm3fb_softc *sc = vd->cookie; | | 424 | struct pm3fb_softc *sc = vd->cookie; |
425 | paddr_t pa; | | 425 | paddr_t pa; |
426 | | | 426 | |
427 | /* 'regular' framebuffer mmap()ing */ | | 427 | /* 'regular' framebuffer mmap()ing */ |
428 | if (offset < sc->sc_fbsize) { | | 428 | if (offset < sc->sc_fbsize) { |
429 | pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot, | | 429 | pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot, |
430 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); | | 430 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); |
431 | return pa; | | 431 | return pa; |
432 | } | | 432 | } |
433 | | | 433 | |
434 | /* | | 434 | /* |
435 | * restrict all other mappings to processes with superuser privileges | | 435 | * restrict all other mappings to processes with superuser privileges |
436 | * or the kernel itself | | 436 | * or the kernel itself |
437 | */ | | 437 | */ |
438 | if (kauth_authorize_machdep(kauth_cred_get(), | | 438 | if (kauth_authorize_machdep(kauth_cred_get(), |
439 | KAUTH_MACHDEP_UNMANAGEDMEM, | | 439 | KAUTH_MACHDEP_UNMANAGEDMEM, |
440 | NULL, NULL, NULL, NULL) != 0) { | | 440 | NULL, NULL, NULL, NULL) != 0) { |
441 | aprint_normal("%s: mmap() rejected.\n", | | 441 | aprint_normal("%s: mmap() rejected.\n", |
442 | device_xname(sc->sc_dev)); | | 442 | device_xname(sc->sc_dev)); |
443 | return -1; | | 443 | return -1; |
444 | } | | 444 | } |
445 | | | 445 | |
446 | if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) { | | 446 | if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) { |
447 | pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, | | 447 | pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, |
448 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); | | 448 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); |
449 | return pa; | | 449 | return pa; |
450 | } | | 450 | } |
451 | | | 451 | |
452 | if ((offset >= sc->sc_reg) && | | 452 | if ((offset >= sc->sc_reg) && |
453 | (offset < (sc->sc_reg + sc->sc_regsize))) { | | 453 | (offset < (sc->sc_reg + sc->sc_regsize))) { |
454 | pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, | | 454 | pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, |
455 | BUS_SPACE_MAP_LINEAR); | | 455 | BUS_SPACE_MAP_LINEAR); |
456 | return pa; | | 456 | return pa; |
457 | } | | 457 | } |
458 | | | 458 | |
459 | #ifdef PCI_MAGIC_IO_RANGE | | 459 | #ifdef PCI_MAGIC_IO_RANGE |
460 | /* allow mapping of IO space */ | | 460 | /* allow mapping of IO space */ |
461 | if ((offset >= PCI_MAGIC_IO_RANGE) && | | 461 | if ((offset >= PCI_MAGIC_IO_RANGE) && |
462 | (offset < PCI_MAGIC_IO_RANGE + 0x10000)) { | | 462 | (offset < PCI_MAGIC_IO_RANGE + 0x10000)) { |
463 | pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE, | | 463 | pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE, |
464 | 0, prot, BUS_SPACE_MAP_LINEAR); | | 464 | 0, prot, BUS_SPACE_MAP_LINEAR); |
465 | return pa; | | 465 | return pa; |
466 | } | | 466 | } |
467 | #endif | | 467 | #endif |
468 | return -1; | | 468 | return -1; |
469 | } | | 469 | } |
470 | | | 470 | |
471 | static void | | 471 | static void |
472 | pm3fb_init_screen(void *cookie, struct vcons_screen *scr, | | 472 | pm3fb_init_screen(void *cookie, struct vcons_screen *scr, |
473 | int existing, long *defattr) | | 473 | int existing, long *defattr) |
474 | { | | 474 | { |
475 | struct pm3fb_softc *sc = cookie; | | 475 | struct pm3fb_softc *sc = cookie; |
476 | struct rasops_info *ri = &scr->scr_ri; | | 476 | struct rasops_info *ri = &scr->scr_ri; |
477 | | | 477 | |
478 | ri->ri_depth = sc->sc_depth; | | 478 | ri->ri_depth = sc->sc_depth; |
479 | ri->ri_width = sc->sc_width; | | 479 | ri->ri_width = sc->sc_width; |
480 | ri->ri_height = sc->sc_height; | | 480 | ri->ri_height = sc->sc_height; |
481 | ri->ri_stride = sc->sc_stride; | | 481 | ri->ri_stride = sc->sc_stride; |
482 | ri->ri_flg = RI_CENTER; | | 482 | ri->ri_flg = RI_CENTER; |
483 | if (sc->sc_depth == 8) | | 483 | if (sc->sc_depth == 8) |
484 | ri->ri_flg |= RI_8BIT_IS_RGB; | | 484 | ri->ri_flg |= RI_8BIT_IS_RGB; |
485 | | | 485 | |
486 | rasops_init(ri, 0, 0); | | 486 | rasops_init(ri, 0, 0); |
487 | ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE; | | 487 | ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE; |
488 | | | 488 | |
489 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | | 489 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, |
490 | sc->sc_width / ri->ri_font->fontwidth); | | 490 | sc->sc_width / ri->ri_font->fontwidth); |
491 | | | 491 | |
492 | ri->ri_hw = scr; | | 492 | ri->ri_hw = scr; |
493 | ri->ri_ops.copyrows = pm3fb_copyrows; | | 493 | ri->ri_ops.copyrows = pm3fb_copyrows; |
494 | ri->ri_ops.copycols = pm3fb_copycols; | | 494 | ri->ri_ops.copycols = pm3fb_copycols; |
495 | ri->ri_ops.cursor = pm3fb_cursor; | | 495 | ri->ri_ops.cursor = pm3fb_cursor; |
496 | ri->ri_ops.eraserows = pm3fb_eraserows; | | 496 | ri->ri_ops.eraserows = pm3fb_eraserows; |
497 | ri->ri_ops.erasecols = pm3fb_erasecols; | | 497 | ri->ri_ops.erasecols = pm3fb_erasecols; |
498 | ri->ri_ops.putchar = pm3fb_putchar; | | 498 | ri->ri_ops.putchar = pm3fb_putchar; |
499 | } | | 499 | } |
500 | | | 500 | |
501 | static int | | 501 | static int |
502 | pm3fb_putcmap(struct pm3fb_softc *sc, struct wsdisplay_cmap *cm) | | 502 | pm3fb_putcmap(struct pm3fb_softc *sc, struct wsdisplay_cmap *cm) |
503 | { | | 503 | { |
504 | u_char *r, *g, *b; | | 504 | u_char *r, *g, *b; |
505 | u_int index = cm->index; | | 505 | u_int index = cm->index; |
506 | u_int count = cm->count; | | 506 | u_int count = cm->count; |
507 | int i, error; | | 507 | int i, error; |
508 | u_char rbuf[256], gbuf[256], bbuf[256]; | | 508 | u_char rbuf[256], gbuf[256], bbuf[256]; |
509 | | | 509 | |
510 | if (cm->index >= 256 || cm->count > 256 || | | 510 | if (cm->index >= 256 || cm->count > 256 || |
511 | (cm->index + cm->count) > 256) | | 511 | (cm->index + cm->count) > 256) |
512 | return EINVAL; | | 512 | return EINVAL; |
513 | error = copyin(cm->red, &rbuf[index], count); | | 513 | error = copyin(cm->red, &rbuf[index], count); |
514 | if (error) | | 514 | if (error) |
515 | return error; | | 515 | return error; |
516 | error = copyin(cm->green, &gbuf[index], count); | | 516 | error = copyin(cm->green, &gbuf[index], count); |
517 | if (error) | | 517 | if (error) |
518 | return error; | | 518 | return error; |
519 | error = copyin(cm->blue, &bbuf[index], count); | | 519 | error = copyin(cm->blue, &bbuf[index], count); |
520 | if (error) | | 520 | if (error) |
521 | return error; | | 521 | return error; |
522 | | | 522 | |
523 | memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); | | 523 | memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); |
524 | memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); | | 524 | memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); |
525 | memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); | | 525 | memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); |
526 | | | 526 | |
527 | r = &sc->sc_cmap_red[index]; | | 527 | r = &sc->sc_cmap_red[index]; |
528 | g = &sc->sc_cmap_green[index]; | | 528 | g = &sc->sc_cmap_green[index]; |
529 | b = &sc->sc_cmap_blue[index]; | | 529 | b = &sc->sc_cmap_blue[index]; |
530 | | | 530 | |
531 | for (i = 0; i < count; i++) { | | 531 | for (i = 0; i < count; i++) { |
532 | pm3fb_putpalreg(sc, index, *r, *g, *b); | | 532 | pm3fb_putpalreg(sc, index, *r, *g, *b); |
533 | index++; | | 533 | index++; |
534 | r++, g++, b++; | | 534 | r++, g++, b++; |
535 | } | | 535 | } |
536 | return 0; | | 536 | return 0; |
537 | } | | 537 | } |
538 | | | 538 | |
539 | static int | | 539 | static int |
540 | pm3fb_getcmap(struct pm3fb_softc *sc, struct wsdisplay_cmap *cm) | | 540 | pm3fb_getcmap(struct pm3fb_softc *sc, struct wsdisplay_cmap *cm) |
541 | { | | 541 | { |
542 | u_int index = cm->index; | | 542 | u_int index = cm->index; |
543 | u_int count = cm->count; | | 543 | u_int count = cm->count; |
544 | int error; | | 544 | int error; |
545 | | | 545 | |
546 | if (index >= 255 || count > 256 || index + count > 256) | | 546 | if (index >= 255 || count > 256 || index + count > 256) |
547 | return EINVAL; | | 547 | return EINVAL; |
548 | | | 548 | |
549 | error = copyout(&sc->sc_cmap_red[index], cm->red, count); | | 549 | error = copyout(&sc->sc_cmap_red[index], cm->red, count); |
550 | if (error) | | 550 | if (error) |
551 | return error; | | 551 | return error; |
552 | error = copyout(&sc->sc_cmap_green[index], cm->green, count); | | 552 | error = copyout(&sc->sc_cmap_green[index], cm->green, count); |
553 | if (error) | | 553 | if (error) |
554 | return error; | | 554 | return error; |
555 | error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); | | 555 | error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); |
556 | if (error) | | 556 | if (error) |
557 | return error; | | 557 | return error; |
558 | | | 558 | |
559 | return 0; | | 559 | return 0; |
560 | } | | 560 | } |
561 | | | 561 | |
562 | static void | | 562 | static void |
563 | pm3fb_init_palette(struct pm3fb_softc *sc) | | 563 | pm3fb_init_palette(struct pm3fb_softc *sc) |
564 | { | | 564 | { |
565 | struct rasops_info *ri = &sc->sc_console_screen.scr_ri; | | 565 | struct rasops_info *ri = &sc->sc_console_screen.scr_ri; |
566 | int i, j = 0; | | 566 | int i, j = 0; |
567 | uint8_t cmap[768]; | | 567 | uint8_t cmap[768]; |
568 | | | 568 | |
569 | rasops_get_cmap(ri, cmap, sizeof(cmap)); | | 569 | rasops_get_cmap(ri, cmap, sizeof(cmap)); |
570 | | | 570 | |
571 | for (i = 0; i < 256; i++) { | | 571 | for (i = 0; i < 256; i++) { |
572 | sc->sc_cmap_red[i] = cmap[j]; | | 572 | sc->sc_cmap_red[i] = cmap[j]; |
573 | sc->sc_cmap_green[i] = cmap[j + 1]; | | 573 | sc->sc_cmap_green[i] = cmap[j + 1]; |
574 | sc->sc_cmap_blue[i] = cmap[j + 2]; | | 574 | sc->sc_cmap_blue[i] = cmap[j + 2]; |
575 | pm3fb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]); | | 575 | pm3fb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]); |
576 | j += 3; | | 576 | j += 3; |
577 | } | | 577 | } |
578 | } | | 578 | } |
579 | | | 579 | |
580 | static int | | 580 | static int |
581 | pm3fb_putpalreg(struct pm3fb_softc *sc, uint8_t idx, uint8_t r, uint8_t g, uint8_t b) | | 581 | pm3fb_putpalreg(struct pm3fb_softc *sc, uint8_t idx, uint8_t r, uint8_t g, uint8_t b) |
582 | { | | 582 | { |
583 | | | 583 | |
584 | pm3fb_wait(sc, 4); | | 584 | pm3fb_wait(sc, 4); |
585 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_WRITE_IDX, idx); | | 585 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_WRITE_IDX, idx); |
586 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, r); | | 586 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, r); |
587 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, g); | | 587 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, g); |
588 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, b); | | 588 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, b); |
589 | return 0; | | 589 | return 0; |
590 | } | | 590 | } |
591 | | | 591 | |
592 | static void | | 592 | static void |
593 | pm3fb_write_dac(struct pm3fb_softc *sc, int reg, uint8_t data) | | 593 | pm3fb_write_dac(struct pm3fb_softc *sc, int reg, uint8_t data) |
594 | { | | 594 | { |
595 | | | 595 | |
596 | pm3fb_wait(sc, 3); | | 596 | pm3fb_wait(sc, 3); |
597 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_LOW, reg & 0xff); | | 597 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_LOW, reg & 0xff); |
598 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_HIGH, (reg >> 8) & 0xff); | | 598 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_HIGH, (reg >> 8) & 0xff); |
599 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_DATA, data); | | 599 | bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_DATA, data); |
600 | } | | 600 | } |
601 | | | 601 | |
602 | static void | | 602 | static void |
603 | pm3fb_init(struct pm3fb_softc *sc) | | 603 | pm3fb_init(struct pm3fb_softc *sc) |
604 | { | | 604 | { |
605 | | | 605 | |
606 | pm3fb_wait(sc, 16); | | 606 | pm3fb_wait(sc, 16); |
607 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_MODE, 0); | | 607 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_MODE, 0); |
608 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_ENABLES, 0); | | 608 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_ENABLES, 0); |
609 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_SOURCEREAD_MODE, 0); | | 609 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_SOURCEREAD_MODE, 0); |
610 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_WRITE_MODE, 0); | | 610 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_WRITE_MODE, 0); |
611 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FILTER_MODE, PM3_FM_PASS_SYNC); | | 611 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FILTER_MODE, PM3_FM_PASS_SYNC); |
612 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STATISTIC_MODE, 0); | | 612 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STATISTIC_MODE, 0); |
613 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTA_MODE, 0); | | 613 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTA_MODE, 0); |
614 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, 0); | | 614 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, 0); |
615 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSOR_MODE, 0); | | 615 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSOR_MODE, 0); |
616 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LINESTIPPLE_MODE, 0); | | 616 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LINESTIPPLE_MODE, 0); |
617 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_AREASTIPPLE_MODE, 0); | | 617 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_AREASTIPPLE_MODE, 0); |
618 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_GID_MODE, 0); | | 618 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_GID_MODE, 0); |
619 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DEPTH_MODE, 0); | | 619 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DEPTH_MODE, 0); |
620 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_MODE, 0); | | 620 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_MODE, 0); |
621 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_DATA, 0); | | 621 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_DATA, 0); |
622 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COLORDDA_MODE, 0); | | 622 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COLORDDA_MODE, 0); |
623 | | | 623 | |
624 | pm3fb_wait(sc, 16); | | 624 | pm3fb_wait(sc, 16); |
625 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREADDRESS_MODE, 0); | | 625 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREADDRESS_MODE, 0); |
626 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE0, 0); | | 626 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE0, 0); |
627 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE1, 0); | | 627 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE1, 0); |
628 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREREAD_MODE, 0); | | 628 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREREAD_MODE, 0); |
629 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXELLUT_MODE, 0); | | 629 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXELLUT_MODE, 0); |
630 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREFILTER_MODE, 0); | | 630 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREFILTER_MODE, 0); |
631 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITE_MODE, 0); | | 631 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITE_MODE, 0); |
632 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOLOR_MODE, 0); | | 632 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOLOR_MODE, 0); |
633 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE1, 0); | | 633 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE1, 0); |
634 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE1, 0); | | 634 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE1, 0); |
635 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE0, 0); | | 635 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE0, 0); |
636 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE0, 0); | | 636 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE0, 0); |
637 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOG_MODE, 0); | | 637 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOG_MODE, 0); |
638 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHROMATEST_MODE, 0); | | 638 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHROMATEST_MODE, 0); |
639 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHATEST_MODE, 0); | | 639 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHATEST_MODE, 0); |
640 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ANTIALIAS_MODE, 0); | | 640 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ANTIALIAS_MODE, 0); |
641 | | | 641 | |
642 | pm3fb_wait(sc, 16); | | 642 | pm3fb_wait(sc, 16); |
643 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YUV_MODE, 0); | | 643 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YUV_MODE, 0); |
644 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDCOLOR_MODE, 0); | | 644 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDCOLOR_MODE, 0); |
645 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDALPHA_MODE, 0); | | 645 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDALPHA_MODE, 0); |
646 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, 0); | | 646 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, 0); |
647 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOGICALOP_MODE, 0); | | 647 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOGICALOP_MODE, 0); |
648 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ROUTER_MODE, 0); | | 648 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ROUTER_MODE, 0); |
649 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_WINDOW, 0); | | 649 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_WINDOW, 0); |
650 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, 0); | | 650 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, 0); |
651 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SPANCOLORMASK, 0xffffffff); | | 651 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SPANCOLORMASK, 0xffffffff); |
652 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_XBIAS, 0); | | 652 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_XBIAS, 0); |
653 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YBIAS, 0); | | 653 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YBIAS, 0); |
654 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTACONTROL, 0); | | 654 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTACONTROL, 0); |
655 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BITMASKPATTERN, 0xffffffff); | | 655 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BITMASKPATTERN, 0xffffffff); |
656 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_ENABLE, | | 656 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_ENABLE, |
657 | PM3_FBDESTREAD_SET(0xff, 0xff, 0xff)); | | 657 | PM3_FBDESTREAD_SET(0xff, 0xff, 0xff)); |
658 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERADDRESS0, 0); | | 658 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERADDRESS0, 0); |
659 | | | 659 | |
660 | pm3fb_wait(sc, 16); | | 660 | pm3fb_wait(sc, 16); |
661 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFEROFFSET0, 0); | | 661 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFEROFFSET0, 0); |
662 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERWIDTH0, | | 662 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERWIDTH0, |
663 | PM3_FBDESTREAD_BUFFERWIDTH_WIDTH(sc->sc_stride)); | | 663 | PM3_FBDESTREAD_BUFFERWIDTH_WIDTH(sc->sc_stride)); |
664 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FB_DESTREAD_MODE, | | 664 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FB_DESTREAD_MODE, |
665 | PM3_FBDRM_ENABLE | PM3_FBDRM_ENABLE0); | | 665 | PM3_FBDRM_ENABLE | PM3_FBDRM_ENABLE0); |
666 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERADDRESS, 0); | | 666 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERADDRESS, 0); |
667 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET, 0); | | 667 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET, 0); |
668 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERWIDTH, | | 668 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERWIDTH, |
669 | PM3_FBSOURCEREAD_BUFFERWIDTH_WIDTH(sc->sc_stride)); | | 669 | PM3_FBSOURCEREAD_BUFFERWIDTH_WIDTH(sc->sc_stride)); |
670 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_MODE, | | 670 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_MODE, |
671 | PM3_FBSOURCEREAD_MODE_BLOCKING | PM3_FBSOURCEREAD_MODE_ENABLE); | | 671 | PM3_FBSOURCEREAD_MODE_BLOCKING | PM3_FBSOURCEREAD_MODE_ENABLE); |
672 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_PIXEL_SIZE, PM3_PS_8BIT); | | 672 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_PIXEL_SIZE, PM3_PS_8BIT); |
673 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOFTWAREWRITEMASK, 0xffffffff); | | 673 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOFTWAREWRITEMASK, 0xffffffff); |
674 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBHARDWAREWRITEMASK, 0xffffffff); | | 674 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBHARDWAREWRITEMASK, 0xffffffff); |
675 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITE_MODE, | | 675 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITE_MODE, |
676 | PM3_FBWRITEMODE_WRITEENABLE | PM3_FBWRITEMODE_OPAQUESPAN | PM3_FBWRITEMODE_ENABLE0); | | 676 | PM3_FBWRITEMODE_WRITEENABLE | PM3_FBWRITEMODE_OPAQUESPAN | PM3_FBWRITEMODE_ENABLE0); |
677 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERADDRESS0, 0); | | 677 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERADDRESS0, 0); |
678 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFEROFFSET0, 0); | | 678 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFEROFFSET0, 0); |
679 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERWIDTH0, | | 679 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERWIDTH0, |
680 | PM3_FBWRITEBUFFERWIDTH_WIDTH(sc->sc_stride)); | | 680 | PM3_FBWRITEBUFFERWIDTH_WIDTH(sc->sc_stride)); |
681 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SIZEOF_FRAMEBUFFER, 4095); | | 681 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SIZEOF_FRAMEBUFFER, 4095); |
682 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, PM3_CF_TO_DIM_CF(4)); | | 682 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, PM3_CF_TO_DIM_CF(4)); |
683 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXDOM, 0); | | 683 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXDOM, 0); |
684 | | | 684 | |
685 | pm3fb_wait(sc, 6); | | 685 | pm3fb_wait(sc, 6); |
686 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXSUB, 0); | | 686 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXSUB, 0); |
687 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DY, 1 << 16); | | 687 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DY, 1 << 16); |
688 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXDOM, 0); | | 688 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXDOM, 0); |
689 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXSUB, 0); | | 689 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXSUB, 0); |
690 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTY, 0); | | 690 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTY, 0); |
691 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COUNT, 0); | | 691 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COUNT, 0); |
692 | } | | 692 | } |
693 | | | 693 | |
694 | static void | | 694 | static void |
695 | pm3fb_rectfill(struct pm3fb_softc *sc, int x, int y, int wi, int he, | | 695 | pm3fb_rectfill(struct pm3fb_softc *sc, int x, int y, int wi, int he, |
696 | uint32_t colour) | | 696 | uint32_t colour) |
697 | { | | 697 | { |
698 | pm3fb_wait(sc, 4); | | 698 | pm3fb_wait(sc, 4); |
699 | | | 699 | |
700 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, | | 700 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, |
701 | PM3_CONFIG2D_USECONSTANTSOURCE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | | | 701 | PM3_CONFIG2D_USECONSTANTSOURCE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | |
702 | (PM3_CONFIG2D_FOREGROUNDROP(0x3)) | PM3_CONFIG2D_FBWRITE_ENABLE); | | 702 | (PM3_CONFIG2D_FOREGROUNDROP(0x3)) | PM3_CONFIG2D_FBWRITE_ENABLE); |
703 | | | 703 | |
704 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOREGROUNDCOLOR, colour); | | 704 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOREGROUNDCOLOR, colour); |
705 | | | 705 | |
706 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION, | | 706 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION, |
707 | (((y) & 0xffff) << 16) | ((x) & 0xffff) ); | | 707 | (((y) & 0xffff) << 16) | ((x) & 0xffff) ); |
708 | | | 708 | |
709 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D, | | 709 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D, |
710 | PM3_RENDER2D_XPOSITIVE | PM3_RENDER2D_YPOSITIVE | | | 710 | PM3_RENDER2D_XPOSITIVE | PM3_RENDER2D_YPOSITIVE | |
711 | PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | | | 711 | PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | |
712 | (((he) & 0x0fff) << 16) | ((wi) & 0x0fff)); | | 712 | (((he) & 0x0fff) << 16) | ((wi) & 0x0fff)); |
713 | | | 713 | |
714 | #ifdef PM3FB_DEBUG | | 714 | #ifdef PM3FB_DEBUG |
715 | pm3fb_flush_engine(sc); | | 715 | pm3fb_flush_engine(sc); |
716 | #endif | | 716 | #endif |
717 | } | | 717 | } |
718 | | | 718 | |
719 | static void | | 719 | static void |
720 | pm3fb_bitblt(void *cookie, int srcx, int srcy, int dstx, int dsty, | | 720 | pm3fb_bitblt(void *cookie, int srcx, int srcy, int dstx, int dsty, |
721 | int width, int height, int rop) | | 721 | int width, int height, int rop) |
722 | { | | 722 | { |
723 | struct pm3fb_softc *sc = cookie; | | 723 | struct pm3fb_softc *sc = cookie; |
724 | int x_align, offset_x, offset_y; | | 724 | int x_align, offset_x, offset_y; |
725 | uint32_t dir = 0; | | 725 | uint32_t dir = 0; |
726 | | | 726 | |
727 | offset_x = srcx - dstx; | | 727 | offset_x = srcx - dstx; |
728 | offset_y = srcy - dsty; | | 728 | offset_y = srcy - dsty; |
729 | | | 729 | |
730 | if (dsty <= srcy) { | | 730 | if (dsty <= srcy) { |
731 | dir |= PM3_RENDER2D_YPOSITIVE; | | 731 | dir |= PM3_RENDER2D_YPOSITIVE; |
732 | } | | 732 | } |
733 | | | 733 | |
734 | if (dstx <= srcx) { | | 734 | if (dstx <= srcx) { |
735 | dir |= PM3_RENDER2D_XPOSITIVE; | | 735 | dir |= PM3_RENDER2D_XPOSITIVE; |
736 | } | | 736 | } |
737 | | | 737 | |
738 | x_align = (srcx & 0x1f); | | 738 | x_align = (srcx & 0x1f); |
739 | | | 739 | |
740 | pm3fb_wait(sc, 6); | | 740 | pm3fb_wait(sc, 6); |
741 | | | 741 | |
742 | if (rop == 3){ | | 742 | if (rop == 3){ |
743 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, | | 743 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, |
744 | PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING | | | 744 | PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING | |
745 | PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE); | | 745 | PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE); |
746 | } else { | | 746 | } else { |
747 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, | | 747 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, |
748 | PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING | | | 748 | PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING | |
749 | PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE | PM3_CONFIG2D_FBDESTREAD_ENABLE); | | 749 | PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE | PM3_CONFIG2D_FBDESTREAD_ENABLE); |
750 | } | | 750 | } |
751 | | | 751 | |
752 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMINXY, | | 752 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMINXY, |
753 | ((dsty & 0x0fff) << 16) | (dstx & 0x0fff)); | | 753 | ((dsty & 0x0fff) << 16) | (dstx & 0x0fff)); |
754 | | | 754 | |
755 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMAXXY, | | 755 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMAXXY, |
756 | (((dsty + height) & 0x0fff) << 16) | ((dstx + width) & 0x0fff)); | | 756 | (((dsty + height) & 0x0fff) << 16) | ((dstx + width) & 0x0fff)); |
757 | | | 757 | |
758 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET, | | 758 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET, |
759 | (((offset_y) & 0xffff) << 16) | ((offset_x) & 0xffff)); | | 759 | (((offset_y) & 0xffff) << 16) | ((offset_x) & 0xffff)); |
760 | | | 760 | |
761 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION, | | 761 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION, |
762 | (((dsty) & 0xffff) << 16) | ((dstx - x_align) & 0xffff)); | | 762 | (((dsty) & 0xffff) << 16) | ((dstx - x_align) & 0xffff)); |
763 | | | 763 | |
764 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D, | | 764 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D, |
765 | dir | | | 765 | dir | |
766 | PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | PM3_RENDER2D_FBSOURCEREADENABLE | | | 766 | PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | PM3_RENDER2D_FBSOURCEREADENABLE | |
767 | (((height) & 0x0fff) << 16) | ((width + x_align) & 0x0fff)); | | 767 | (((height) & 0x0fff) << 16) | ((width + x_align) & 0x0fff)); |
768 | | | 768 | |
769 | #ifdef PM3FB_DEBUG | | 769 | #ifdef PM3FB_DEBUG |
770 | pm3fb_flush_engine(sc); | | 770 | pm3fb_flush_engine(sc); |
771 | #endif | | 771 | #endif |
772 | } | | 772 | } |
773 | | | 773 | |
774 | static void | | 774 | static void |
775 | pm3fb_cursor(void *cookie, int on, int row, int col) | | 775 | pm3fb_cursor(void *cookie, int on, int row, int col) |
776 | { | | 776 | { |
777 | struct rasops_info *ri = cookie; | | 777 | struct rasops_info *ri = cookie; |
778 | struct vcons_screen *scr = ri->ri_hw; | | 778 | struct vcons_screen *scr = ri->ri_hw; |
779 | struct pm3fb_softc *sc = scr->scr_cookie; | | 779 | struct pm3fb_softc *sc = scr->scr_cookie; |
780 | int x, y, wi, he; | | 780 | int x, y, wi, he; |
781 | | | 781 | |
782 | wi = ri->ri_font->fontwidth; | | 782 | wi = ri->ri_font->fontwidth; |
783 | he = ri->ri_font->fontheight; | | 783 | he = ri->ri_font->fontheight; |
784 | | | 784 | |
785 | if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { | | 785 | if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { |
786 | x = ri->ri_ccol * wi + ri->ri_xorigin; | | 786 | x = ri->ri_ccol * wi + ri->ri_xorigin; |
787 | y = ri->ri_crow * he + ri->ri_yorigin; | | 787 | y = ri->ri_crow * he + ri->ri_yorigin; |
788 | if (ri->ri_flg & RI_CURSOR) { | | 788 | if (ri->ri_flg & RI_CURSOR) { |
789 | pm3fb_bitblt(sc, x, y, x, y, wi, he, 12); | | 789 | pm3fb_bitblt(sc, x, y, x, y, wi, he, 12); |
790 | ri->ri_flg &= ~RI_CURSOR; | | 790 | ri->ri_flg &= ~RI_CURSOR; |
791 | } | | 791 | } |
792 | ri->ri_crow = row; | | 792 | ri->ri_crow = row; |
793 | ri->ri_ccol = col; | | 793 | ri->ri_ccol = col; |
794 | if (on) { | | 794 | if (on) { |
795 | x = ri->ri_ccol * wi + ri->ri_xorigin; | | 795 | x = ri->ri_ccol * wi + ri->ri_xorigin; |
796 | y = ri->ri_crow * he + ri->ri_yorigin; | | 796 | y = ri->ri_crow * he + ri->ri_yorigin; |
797 | pm3fb_bitblt(sc, x, y, x, y, wi, he, 12); | | 797 | pm3fb_bitblt(sc, x, y, x, y, wi, he, 12); |
798 | ri->ri_flg |= RI_CURSOR; | | 798 | ri->ri_flg |= RI_CURSOR; |
799 | } | | 799 | } |
800 | } else { | | 800 | } else { |
801 | scr->scr_ri.ri_crow = row; | | 801 | scr->scr_ri.ri_crow = row; |
802 | scr->scr_ri.ri_ccol = col; | | 802 | scr->scr_ri.ri_ccol = col; |
803 | scr->scr_ri.ri_flg &= ~RI_CURSOR; | | 803 | scr->scr_ri.ri_flg &= ~RI_CURSOR; |
804 | } | | 804 | } |
805 | } | | 805 | } |
806 | | | 806 | |
807 | static void | | 807 | static void |
808 | pm3fb_putchar(void *cookie, int row, int col, u_int c, long attr) | | 808 | pm3fb_putchar(void *cookie, int row, int col, u_int c, long attr) |
809 | { | | 809 | { |
810 | struct rasops_info *ri = cookie; | | 810 | struct rasops_info *ri = cookie; |
811 | struct wsdisplay_font *font = PICK_FONT(ri, c); | | 811 | struct wsdisplay_font *font = PICK_FONT(ri, c); |
812 | struct vcons_screen *scr = ri->ri_hw; | | 812 | struct vcons_screen *scr = ri->ri_hw; |
813 | struct pm3fb_softc *sc = scr->scr_cookie; | | 813 | struct pm3fb_softc *sc = scr->scr_cookie; |
814 | uint32_t mode; | | 814 | uint32_t mode; |
815 | | | 815 | |
816 | if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { | | 816 | if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { |
817 | void *data; | | 817 | void *data; |
818 | uint32_t fg, bg; | | 818 | uint32_t fg, bg; |
819 | int uc, i; | | 819 | int uc, i; |
820 | int x, y, wi, he; | | 820 | int x, y, wi, he; |
821 | | | 821 | |
822 | wi = font->fontwidth; | | 822 | wi = font->fontwidth; |
823 | he = font->fontheight; | | 823 | he = font->fontheight; |
824 | | | 824 | |
825 | if (!CHAR_IN_FONT(c, font)) | | 825 | if (!CHAR_IN_FONT(c, font)) |
826 | return; | | 826 | return; |
827 | | | 827 | |
828 | bg = ri->ri_devcmap[(attr >> 16) & 0xf]; | | 828 | bg = ri->ri_devcmap[(attr >> 16) & 0xf]; |
829 | fg = ri->ri_devcmap[(attr >> 24) & 0xf]; | | 829 | fg = ri->ri_devcmap[(attr >> 24) & 0xf]; |
830 | x = ri->ri_xorigin + col * wi; | | 830 | x = ri->ri_xorigin + col * wi; |
831 | y = ri->ri_yorigin + row * he; | | 831 | y = ri->ri_yorigin + row * he; |
832 | if (c == 0x20) { | | 832 | if (c == 0x20) { |
833 | pm3fb_rectfill(sc, x, y, wi, he, bg); | | 833 | pm3fb_rectfill(sc, x, y, wi, he, bg); |
834 | } else { | | 834 | } else { |
835 | uc = c - font->firstchar; | | 835 | uc = c - font->firstchar; |
836 | data = (uint8_t *)font->data + uc * ri->ri_fontscale; | | 836 | data = (uint8_t *)font->data + uc * ri->ri_fontscale; |
837 | mode = PM3_RM_MASK_MIRROR; | | 837 | mode = PM3_RM_MASK_MIRROR; |
838 | | | 838 | |
839 | #if BYTE_ORDER == LITTLE_ENDIAN | | 839 | #if BYTE_ORDER == LITTLE_ENDIAN |
840 | switch (ri->ri_font->stride) { | | 840 | switch (ri->ri_font->stride) { |
841 | case 1: | | 841 | case 1: |
842 | mode |= 4 << 7; | | 842 | mode |= 4 << 7; |
843 | break; | | 843 | break; |
844 | case 2: | | 844 | case 2: |
845 | mode |= 3 << 7; | | 845 | mode |= 3 << 7; |
846 | break; | | 846 | break; |
847 | } | | 847 | } |
848 | #else | | 848 | #else |
849 | switch (ri->ri_font->stride) { | | 849 | switch (ri->ri_font->stride) { |
850 | case 1: | | 850 | case 1: |
851 | mode |= 3 << 7; | | 851 | mode |= 3 << 7; |
852 | break; | | 852 | break; |
853 | case 2: | | 853 | case 2: |
854 | mode |= 2 << 7; | | 854 | mode |= 2 << 7; |
855 | break; | | 855 | break; |
856 | } | | 856 | } |
857 | #endif | | 857 | #endif |
858 | pm3fb_wait(sc, 8); | | 858 | pm3fb_wait(sc, 8); |
859 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 859 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
860 | PM3_FOREGROUNDCOLOR, fg); | | 860 | PM3_FOREGROUNDCOLOR, fg); |
861 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 861 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
862 | PM3_BACKGROUNDCOLOR, bg); | | 862 | PM3_BACKGROUNDCOLOR, bg); |
863 | | | 863 | |
864 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, mode); | | 864 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, mode); |
865 | | | 865 | |
866 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 866 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
867 | PM3_CONFIG2D, | | 867 | PM3_CONFIG2D, |
868 | PM3_CONFIG2D_USERSCISSOR_ENABLE | | | 868 | PM3_CONFIG2D_USERSCISSOR_ENABLE | |
869 | PM3_CONFIG2D_USECONSTANTSOURCE | | | 869 | PM3_CONFIG2D_USECONSTANTSOURCE | |
870 | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | | | 870 | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | |
871 | PM3_CONFIG2D_FOREGROUNDROP(0x03) | | | 871 | PM3_CONFIG2D_FOREGROUNDROP(0x03) | |
872 | PM3_CONFIG2D_OPAQUESPAN | | | 872 | PM3_CONFIG2D_OPAQUESPAN | |
873 | PM3_CONFIG2D_FBWRITE_ENABLE); | | 873 | PM3_CONFIG2D_FBWRITE_ENABLE); |
874 | | | 874 | |
875 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 875 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
876 | PM3_SCISSORMINXY, ((y & 0x0fff) << 16) | (x & 0x0fff)); | | 876 | PM3_SCISSORMINXY, ((y & 0x0fff) << 16) | (x & 0x0fff)); |
877 | | | 877 | |
878 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 878 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
879 | PM3_SCISSORMAXXY, (((y + he) & 0x0fff) << 16) | ((x + wi) & 0x0fff)); | | 879 | PM3_SCISSORMAXXY, (((y + he) & 0x0fff) << 16) | ((x + wi) & 0x0fff)); |
880 | | | 880 | |
881 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 881 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
882 | PM3_RECTANGLEPOSITION, (((y) & 0xffff)<<16) | ((x) & 0xffff)); | | 882 | PM3_RECTANGLEPOSITION, (((y) & 0xffff)<<16) | ((x) & 0xffff)); |
883 | | | 883 | |
884 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 884 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
885 | PM3_RENDER2D, | | 885 | PM3_RENDER2D, |
886 | PM3_RENDER2D_XPOSITIVE | | | 886 | PM3_RENDER2D_XPOSITIVE | |
887 | PM3_RENDER2D_YPOSITIVE | | | 887 | PM3_RENDER2D_YPOSITIVE | |
888 | PM3_RENDER2D_OPERATION_SYNCONBITMASK | | | 888 | PM3_RENDER2D_OPERATION_SYNCONBITMASK | |
889 | PM3_RENDER2D_SPANOPERATION | | | 889 | PM3_RENDER2D_SPANOPERATION | |
890 | ((wi) & 0x0fff) | (((he) & 0x0fff) << 16)); | | 890 | ((wi) & 0x0fff) | (((he) & 0x0fff) << 16)); |
891 | | | 891 | |
892 | pm3fb_wait(sc, he); | | 892 | pm3fb_wait(sc, he); |
893 | | | 893 | |
894 | switch (ri->ri_font->stride) { | | 894 | switch (ri->ri_font->stride) { |
895 | case 1: { | | 895 | case 1: { |
896 | uint8_t *data8 = data; | | 896 | uint8_t *data8 = data; |
897 | uint32_t reg; | | 897 | uint32_t reg; |
898 | for (i = 0; i < he; i++) { | | 898 | for (i = 0; i < he; i++) { |
899 | reg = *data8; | | 899 | reg = *data8; |
900 | bus_space_write_4(sc->sc_memt, | | 900 | bus_space_write_4(sc->sc_memt, |
901 | sc->sc_regh, | | 901 | sc->sc_regh, |
902 | PM3_BITMASKPATTERN, reg); | | 902 | PM3_BITMASKPATTERN, reg); |
903 | data8++; | | 903 | data8++; |
904 | } | | 904 | } |
905 | break; | | 905 | break; |
906 | } | | 906 | } |
907 | case 2: { | | 907 | case 2: { |
908 | uint16_t *data16 = data; | | 908 | uint16_t *data16 = data; |
909 | uint32_t reg; | | 909 | uint32_t reg; |
910 | for (i = 0; i < he; i++) { | | 910 | for (i = 0; i < he; i++) { |
911 | reg = *data16; | | 911 | reg = *data16; |
912 | bus_space_write_4(sc->sc_memt, | | 912 | bus_space_write_4(sc->sc_memt, |
913 | sc->sc_regh, | | 913 | sc->sc_regh, |
914 | PM3_BITMASKPATTERN, reg); | | 914 | PM3_BITMASKPATTERN, reg); |
915 | data16++; | | 915 | data16++; |
916 | } | | 916 | } |
917 | break; | | 917 | break; |
918 | } | | 918 | } |
919 | } | | 919 | } |
920 | } | | 920 | } |
921 | } | | 921 | } |
922 | } | | 922 | } |
923 | | | 923 | |
924 | static void | | 924 | static void |
925 | pm3fb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) | | 925 | pm3fb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) |
926 | { | | 926 | { |
927 | struct rasops_info *ri = cookie; | | 927 | struct rasops_info *ri = cookie; |
928 | struct vcons_screen *scr = ri->ri_hw; | | 928 | struct vcons_screen *scr = ri->ri_hw; |
929 | struct pm3fb_softc *sc = scr->scr_cookie; | | 929 | struct pm3fb_softc *sc = scr->scr_cookie; |
930 | int32_t xs, xd, y, width, height; | | 930 | int32_t xs, xd, y, width, height; |
931 | | | 931 | |
932 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { | | 932 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { |
933 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; | | 933 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; |
934 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; | | 934 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; |
935 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | | 935 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; |
936 | width = ri->ri_font->fontwidth * ncols; | | 936 | width = ri->ri_font->fontwidth * ncols; |
937 | height = ri->ri_font->fontheight; | | 937 | height = ri->ri_font->fontheight; |
938 | pm3fb_bitblt(sc, xs, y, xd, y, width, height, 3); | | 938 | pm3fb_bitblt(sc, xs, y, xd, y, width, height, 3); |
939 | } | | 939 | } |
940 | } | | 940 | } |
941 | | | 941 | |
942 | static void | | 942 | static void |
943 | pm3fb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) | | 943 | pm3fb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) |
944 | { | | 944 | { |
945 | struct rasops_info *ri = cookie; | | 945 | struct rasops_info *ri = cookie; |
946 | struct vcons_screen *scr = ri->ri_hw; | | 946 | struct vcons_screen *scr = ri->ri_hw; |
947 | struct pm3fb_softc *sc = scr->scr_cookie; | | 947 | struct pm3fb_softc *sc = scr->scr_cookie; |
948 | int32_t x, y, width, height, fg, bg, ul; | | 948 | int32_t x, y, width, height, fg, bg, ul; |
949 | | | 949 | |
950 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { | | 950 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { |
951 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; | | 951 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; |
952 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | | 952 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; |
953 | width = ri->ri_font->fontwidth * ncols; | | 953 | width = ri->ri_font->fontwidth * ncols; |
954 | height = ri->ri_font->fontheight; | | 954 | height = ri->ri_font->fontheight; |
955 | rasops_unpack_attr(fillattr, &fg, &bg, &ul); | | 955 | rasops_unpack_attr(fillattr, &fg, &bg, &ul); |
956 | | | 956 | |
957 | pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); | | 957 | pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); |
958 | } | | 958 | } |
959 | } | | 959 | } |
960 | | | 960 | |
961 | static void | | 961 | static void |
962 | pm3fb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) | | 962 | pm3fb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) |
963 | { | | 963 | { |
964 | struct rasops_info *ri = cookie; | | 964 | struct rasops_info *ri = cookie; |
965 | struct vcons_screen *scr = ri->ri_hw; | | 965 | struct vcons_screen *scr = ri->ri_hw; |
966 | struct pm3fb_softc *sc = scr->scr_cookie; | | 966 | struct pm3fb_softc *sc = scr->scr_cookie; |
967 | int32_t x, ys, yd, width, height; | | 967 | int32_t x, ys, yd, width, height; |
968 | | | 968 | |
969 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { | | 969 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { |
970 | x = ri->ri_xorigin; | | 970 | x = ri->ri_xorigin; |
971 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; | | 971 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; |
972 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; | | 972 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; |
973 | width = ri->ri_emuwidth; | | 973 | width = ri->ri_emuwidth; |
974 | height = ri->ri_font->fontheight*nrows; | | 974 | height = ri->ri_font->fontheight*nrows; |
975 | pm3fb_bitblt(sc, x, ys, x, yd, width, height, 3); | | 975 | pm3fb_bitblt(sc, x, ys, x, yd, width, height, 3); |
976 | } | | 976 | } |
977 | } | | 977 | } |
978 | | | 978 | |
979 | static void | | 979 | static void |
980 | pm3fb_eraserows(void *cookie, int row, int nrows, long fillattr) | | 980 | pm3fb_eraserows(void *cookie, int row, int nrows, long fillattr) |
981 | { | | 981 | { |
982 | struct rasops_info *ri = cookie; | | 982 | struct rasops_info *ri = cookie; |
983 | struct vcons_screen *scr = ri->ri_hw; | | 983 | struct vcons_screen *scr = ri->ri_hw; |
984 | struct pm3fb_softc *sc = scr->scr_cookie; | | 984 | struct pm3fb_softc *sc = scr->scr_cookie; |
985 | int32_t x, y, width, height, fg, bg, ul; | | 985 | int32_t x, y, width, height, fg, bg, ul; |
986 | | | 986 | |
987 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { | | 987 | if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { |
988 | x = ri->ri_xorigin; | | 988 | x = ri->ri_xorigin; |
989 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | | 989 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; |
990 | width = ri->ri_emuwidth; | | 990 | width = ri->ri_emuwidth; |
991 | height = ri->ri_font->fontheight * nrows; | | 991 | height = ri->ri_font->fontheight * nrows; |
992 | rasops_unpack_attr(fillattr, &fg, &bg, &ul); | | 992 | rasops_unpack_attr(fillattr, &fg, &bg, &ul); |
993 | | | 993 | |
994 | pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); | | 994 | pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); |
995 | } | | 995 | } |
996 | } | | 996 | } |
997 | | | 997 | |
998 | /* should be enough */ | | 998 | /* should be enough */ |
999 | #define MODE_IS_VALID(m) (((m)->hdisplay < 2048)) | | 999 | #define MODE_IS_VALID(m) (((m)->hdisplay < 2048)) |
1000 | | | 1000 | |
1001 | static void | | 1001 | static void |
1002 | pm3_setup_i2c(struct pm3fb_softc *sc) | | 1002 | pm3_setup_i2c(struct pm3fb_softc *sc) |
1003 | { | | 1003 | { |
1004 | int i; | | 1004 | int i; |
1005 | | | 1005 | |
1006 | /* Fill in the i2c tag */ | | 1006 | /* Fill in the i2c tag */ |
1007 | sc->sc_i2c.ic_cookie = sc; | | 1007 | sc->sc_i2c.ic_cookie = sc; |
1008 | sc->sc_i2c.ic_acquire_bus = pm3fb_i2c_acquire_bus; | | 1008 | sc->sc_i2c.ic_acquire_bus = pm3fb_i2c_acquire_bus; |
1009 | sc->sc_i2c.ic_release_bus = pm3fb_i2c_release_bus; | | 1009 | sc->sc_i2c.ic_release_bus = pm3fb_i2c_release_bus; |
1010 | sc->sc_i2c.ic_send_start = pm3fb_i2c_send_start; | | 1010 | sc->sc_i2c.ic_send_start = pm3fb_i2c_send_start; |
1011 | sc->sc_i2c.ic_send_stop = pm3fb_i2c_send_stop; | | 1011 | sc->sc_i2c.ic_send_stop = pm3fb_i2c_send_stop; |
1012 | sc->sc_i2c.ic_initiate_xfer = pm3fb_i2c_initiate_xfer; | | 1012 | sc->sc_i2c.ic_initiate_xfer = pm3fb_i2c_initiate_xfer; |
1013 | sc->sc_i2c.ic_read_byte = pm3fb_i2c_read_byte; | | 1013 | sc->sc_i2c.ic_read_byte = pm3fb_i2c_read_byte; |
1014 | sc->sc_i2c.ic_write_byte = pm3fb_i2c_write_byte; | | 1014 | sc->sc_i2c.ic_write_byte = pm3fb_i2c_write_byte; |
1015 | sc->sc_i2c.ic_exec = NULL; | | 1015 | sc->sc_i2c.ic_exec = NULL; |
1016 | | | 1016 | |
1017 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, 0); | | 1017 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, 0); |
1018 | | | 1018 | |
1019 | /* zero out the EDID buffer */ | | 1019 | /* zero out the EDID buffer */ |
1020 | memset(sc->sc_edid_data, 0, 128); | | 1020 | memset(sc->sc_edid_data, 0, 128); |
1021 | | | 1021 | |
1022 | /* Some monitors don't respond first time */ | | 1022 | /* Some monitors don't respond first time */ |
1023 | i = 0; | | 1023 | i = 0; |
1024 | while (sc->sc_edid_data[1] == 0 && i < 10) { | | 1024 | while (sc->sc_edid_data[1] == 0 && i < 10) { |
1025 | ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128); | | 1025 | ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128); |
1026 | i++; | | 1026 | i++; |
1027 | } | | 1027 | } |
1028 | | | 1028 | |
1029 | if (edid_parse(&sc->sc_edid_data[0], &sc->sc_ei) != -1) { | | 1029 | if (edid_parse(&sc->sc_edid_data[0], &sc->sc_ei) != -1) { |
1030 | /* | | 1030 | /* |
1031 | * Now pick a mode. | | 1031 | * Now pick a mode. |
1032 | */ | | 1032 | */ |
1033 | if ((sc->sc_ei.edid_preferred_mode != NULL)) { | | 1033 | if ((sc->sc_ei.edid_preferred_mode != NULL)) { |
1034 | struct videomode *m = sc->sc_ei.edid_preferred_mode; | | 1034 | struct videomode *m = sc->sc_ei.edid_preferred_mode; |
1035 | if (MODE_IS_VALID(m)) { | | 1035 | if (MODE_IS_VALID(m)) { |
1036 | sc->sc_videomode = m; | | 1036 | sc->sc_videomode = m; |
1037 | } else { | | 1037 | } else { |
1038 | aprint_error_dev(sc->sc_dev, | | 1038 | aprint_error_dev(sc->sc_dev, |
1039 | "unable to use preferred mode\n"); | | 1039 | "unable to use preferred mode\n"); |
1040 | } | | 1040 | } |
1041 | } | | 1041 | } |
1042 | /* | | 1042 | /* |
1043 | * if we can't use the preferred mode go look for the | | 1043 | * if we can't use the preferred mode go look for the |
1044 | * best one we can support | | 1044 | * best one we can support |
1045 | */ | | 1045 | */ |
1046 | if (sc->sc_videomode == NULL) { | | 1046 | if (sc->sc_videomode == NULL) { |
1047 | struct videomode *m = sc->sc_ei.edid_modes; | | 1047 | struct videomode *m = sc->sc_ei.edid_modes; |
1048 | | | 1048 | |
1049 | sort_modes(sc->sc_ei.edid_modes, | | 1049 | sort_modes(sc->sc_ei.edid_modes, |
1050 | &sc->sc_ei.edid_preferred_mode, | | 1050 | &sc->sc_ei.edid_preferred_mode, |
1051 | sc->sc_ei.edid_nmodes); | | 1051 | sc->sc_ei.edid_nmodes); |
1052 | if (sc->sc_videomode == NULL) | | 1052 | if (sc->sc_videomode == NULL) |
1053 | for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) | | 1053 | for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) |
1054 | if (MODE_IS_VALID(&m[n])) { | | 1054 | if (MODE_IS_VALID(&m[n])) { |
1055 | sc->sc_videomode = &m[n]; | | 1055 | sc->sc_videomode = &m[n]; |
1056 | break; | | 1056 | break; |
1057 | } | | 1057 | } |
1058 | } | | 1058 | } |
1059 | } | | 1059 | } |
1060 | if (sc->sc_videomode == NULL) { | | 1060 | if (sc->sc_videomode == NULL) { |
1061 | /* no EDID data? */ | | 1061 | /* no EDID data? */ |
1062 | sc->sc_videomode = pick_mode_by_ref(sc->sc_width, | | 1062 | sc->sc_videomode = pick_mode_by_ref(sc->sc_width, |
1063 | sc->sc_height, 60); | | 1063 | sc->sc_height, 60); |
1064 | } | | 1064 | } |
1065 | if (sc->sc_videomode != NULL) { | | 1065 | if (sc->sc_videomode != NULL) { |
1066 | pm3fb_set_mode(sc, sc->sc_videomode); | | 1066 | pm3fb_set_mode(sc, sc->sc_videomode); |
1067 | } | | 1067 | } |
1068 | } | | 1068 | } |
1069 | | | 1069 | |
1070 | /* I2C bitbanging */ | | 1070 | /* I2C bitbanging */ |
1071 | static void pm3fb_i2cbb_set_bits(void *cookie, uint32_t bits) | | 1071 | static void pm3fb_i2cbb_set_bits(void *cookie, uint32_t bits) |
1072 | { | | 1072 | { |
1073 | struct pm3fb_softc *sc = cookie; | | 1073 | struct pm3fb_softc *sc = cookie; |
1074 | uint32_t out; | | 1074 | uint32_t out; |
1075 | | | 1075 | |
1076 | out = bits << 2; /* bitmasks match the IN bits */ | | 1076 | out = bits << 2; /* bitmasks match the IN bits */ |
1077 | | | 1077 | |
1078 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, out); | | 1078 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, out); |
1079 | delay(100); | | 1079 | delay(100); |
1080 | } | | 1080 | } |
1081 | | | 1081 | |
1082 | static void pm3fb_i2cbb_set_dir(void *cookie, uint32_t dir) | | 1082 | static void pm3fb_i2cbb_set_dir(void *cookie, uint32_t dir) |
1083 | { | | 1083 | { |
1084 | /* Nothing to do */ | | 1084 | /* Nothing to do */ |
1085 | } | | 1085 | } |
1086 | | | 1086 | |
1087 | static uint32_t pm3fb_i2cbb_read(void *cookie) | | 1087 | static uint32_t pm3fb_i2cbb_read(void *cookie) |
1088 | { | | 1088 | { |
1089 | struct pm3fb_softc *sc = cookie; | | 1089 | struct pm3fb_softc *sc = cookie; |
1090 | uint32_t bits; | | 1090 | uint32_t bits; |
1091 | | | 1091 | |
1092 | bits = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA); | | 1092 | bits = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA); |
1093 | return bits; | | 1093 | return bits; |
1094 | } | | 1094 | } |
1095 | | | 1095 | |
1096 | /* higher level I2C stuff */ | | 1096 | /* higher level I2C stuff */ |
1097 | static int | | 1097 | static int |
1098 | pm3fb_i2c_acquire_bus(void *cookie, int flags) | | 1098 | pm3fb_i2c_acquire_bus(void *cookie, int flags) |
1099 | { | | 1099 | { |
1100 | /* private bus */ | | 1100 | /* private bus */ |
1101 | return (0); | | 1101 | return (0); |
1102 | } | | 1102 | } |
1103 | | | 1103 | |
1104 | static void | | 1104 | static void |
1105 | pm3fb_i2c_release_bus(void *cookie, int flags) | | 1105 | pm3fb_i2c_release_bus(void *cookie, int flags) |
1106 | { | | 1106 | { |
1107 | /* private bus */ | | 1107 | /* private bus */ |
1108 | } | | 1108 | } |
1109 | | | 1109 | |
1110 | static int | | 1110 | static int |
1111 | pm3fb_i2c_send_start(void *cookie, int flags) | | 1111 | pm3fb_i2c_send_start(void *cookie, int flags) |
1112 | { | | 1112 | { |
1113 | | | 1113 | |
1114 | return (i2c_bitbang_send_start(cookie, flags, &pm3fb_i2cbb_ops)); | | 1114 | return (i2c_bitbang_send_start(cookie, flags, &pm3fb_i2cbb_ops)); |
1115 | } | | 1115 | } |
1116 | | | 1116 | |
1117 | static int | | 1117 | static int |
1118 | pm3fb_i2c_send_stop(void *cookie, int flags) | | 1118 | pm3fb_i2c_send_stop(void *cookie, int flags) |
1119 | { | | 1119 | { |
1120 | | | 1120 | |
1121 | return (i2c_bitbang_send_stop(cookie, flags, &pm3fb_i2cbb_ops)); | | 1121 | return (i2c_bitbang_send_stop(cookie, flags, &pm3fb_i2cbb_ops)); |
1122 | } | | 1122 | } |
1123 | | | 1123 | |
1124 | static int | | 1124 | static int |
1125 | pm3fb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) | | 1125 | pm3fb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) |
1126 | { | | 1126 | { |
1127 | | | 1127 | |
1128 | return (i2c_bitbang_initiate_xfer(cookie, addr, flags, | | 1128 | return (i2c_bitbang_initiate_xfer(cookie, addr, flags, |
1129 | &pm3fb_i2cbb_ops)); | | 1129 | &pm3fb_i2cbb_ops)); |
1130 | } | | 1130 | } |
1131 | | | 1131 | |
1132 | static int | | 1132 | static int |
1133 | pm3fb_i2c_read_byte(void *cookie, uint8_t *valp, int flags) | | 1133 | pm3fb_i2c_read_byte(void *cookie, uint8_t *valp, int flags) |
1134 | { | | 1134 | { |
1135 | | | 1135 | |
1136 | return (i2c_bitbang_read_byte(cookie, valp, flags, &pm3fb_i2cbb_ops)); | | 1136 | return (i2c_bitbang_read_byte(cookie, valp, flags, &pm3fb_i2cbb_ops)); |
1137 | } | | 1137 | } |
1138 | | | 1138 | |
1139 | static int | | 1139 | static int |
1140 | pm3fb_i2c_write_byte(void *cookie, uint8_t val, int flags) | | 1140 | pm3fb_i2c_write_byte(void *cookie, uint8_t val, int flags) |
1141 | { | | 1141 | { |
1142 | return (i2c_bitbang_write_byte(cookie, val, flags, &pm3fb_i2cbb_ops)); | | 1142 | return (i2c_bitbang_write_byte(cookie, val, flags, &pm3fb_i2cbb_ops)); |
1143 | } | | 1143 | } |
1144 | | | 1144 | |
1145 | static int | | 1145 | static int |
1146 | pm3fb_set_pll(struct pm3fb_softc *sc, int freq) | | 1146 | pm3fb_set_pll(struct pm3fb_softc *sc, int freq) |
1147 | { | | 1147 | { |
1148 | uint8_t bf = 0, bpre = 0, bpost = 0; | | 1148 | uint8_t bf = 0, bpre = 0, bpost = 0; |
1149 | int count; | | 1149 | int count; |
1150 | unsigned long feedback, prescale, postscale, IntRef, VCO, out_freq, diff, VCOlow, VCOhigh, bdiff = 1000000; | | 1150 | unsigned long feedback, prescale, postscale, IntRef, VCO, out_freq, diff, VCOlow, VCOhigh, bdiff = 1000000; |
1151 | | | 1151 | |
1152 | freq *= 10; /* convert into 100Hz units */ | | 1152 | freq *= 10; /* convert into 100Hz units */ |
1153 | | | 1153 | |
1154 | for (postscale = 0; postscale <= 5; postscale++) { | | 1154 | for (postscale = 0; postscale <= 5; postscale++) { |
1155 | /* | | 1155 | /* |
1156 | * It is pointless going through the main loop if all values of | | 1156 | * It is pointless going through the main loop if all values of |
1157 | * prescale produce an VCO outside the acceptable range | | 1157 | * prescale produce an VCO outside the acceptable range |
1158 | */ | | 1158 | */ |
1159 | prescale = 1; | | 1159 | prescale = 1; |
1160 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); | | 1160 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); |
1161 | VCOlow = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; | | 1161 | VCOlow = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; |
1162 | if (VCOlow > PM3_VCO_FREQ_MAX) | | 1162 | if (VCOlow > PM3_VCO_FREQ_MAX) |
1163 | continue; | | 1163 | continue; |
1164 | | | 1164 | |
1165 | prescale = 255; | | 1165 | prescale = 255; |
1166 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); | | 1166 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); |
1167 | VCOhigh = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; | | 1167 | VCOhigh = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; |
1168 | if (VCOhigh < PM3_VCO_FREQ_MIN) | | 1168 | if (VCOhigh < PM3_VCO_FREQ_MIN) |
1169 | continue; | | 1169 | continue; |
1170 | | | 1170 | |
1171 | for (prescale = 1; prescale <= 255; prescale++) { | | 1171 | for (prescale = 1; prescale <= 255; prescale++) { |
1172 | IntRef = PM3_EXT_CLOCK_FREQ / prescale; | | 1172 | IntRef = PM3_EXT_CLOCK_FREQ / prescale; |
1173 | if (IntRef < PM3_INTREF_MIN || IntRef > PM3_INTREF_MAX) { | | 1173 | if (IntRef < PM3_INTREF_MIN || IntRef > PM3_INTREF_MAX) { |
1174 | if (IntRef > PM3_INTREF_MAX) { | | 1174 | if (IntRef > PM3_INTREF_MAX) { |
1175 | /* | | 1175 | /* |
1176 | * Hopefully we will get into range as the prescale | | 1176 | * Hopefully we will get into range as the prescale |
1177 | * value increases | | 1177 | * value increases |
1178 | */ | | 1178 | */ |
1179 | continue; | | 1179 | continue; |
1180 | } else { | | 1180 | } else { |
1181 | /* | | 1181 | /* |
1182 | * already below minimum and it will only get worse | | 1182 | * already below minimum and it will only get worse |
1183 | * move to the next postscale value | | 1183 | * move to the next postscale value |
1184 | */ | | 1184 | */ |
1185 | break; | | 1185 | break; |
1186 | } | | 1186 | } |
1187 | } | | 1187 | } |
1188 | | | 1188 | |
1189 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); | | 1189 | feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ); |
1190 | | | 1190 | |
1191 | if (feedback > 255) { | | 1191 | if (feedback > 255) { |
1192 | /* | | 1192 | /* |
1193 | * prescale, feedbackscale & postscale registers | | 1193 | * prescale, feedbackscale & postscale registers |
1194 | * are only 8 bits wide | | 1194 | * are only 8 bits wide |
1195 | */ | | 1195 | */ |
1196 | break; | | 1196 | break; |
1197 | } else if (feedback == 255) { | | 1197 | } else if (feedback == 255) { |
1198 | count = 1; | | 1198 | count = 1; |
1199 | } else { | | 1199 | } else { |
1200 | count = 2; | | 1200 | count = 2; |
1201 | } | | 1201 | } |
1202 | | | 1202 | |
1203 | do { | | 1203 | do { |
1204 | VCO = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; | | 1204 | VCO = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale; |
1205 | if (VCO >= PM3_VCO_FREQ_MIN && VCO <= PM3_VCO_FREQ_MAX) { | | 1205 | if (VCO >= PM3_VCO_FREQ_MIN && VCO <= PM3_VCO_FREQ_MAX) { |
1206 | out_freq = VCO / (1UL << postscale); | | 1206 | out_freq = VCO / (1UL << postscale); |
1207 | diff = abs(out_freq - freq); | | 1207 | diff = abs(out_freq - freq); |
1208 | if (diff < bdiff) { | | 1208 | if (diff < bdiff) { |
1209 | bdiff = diff; | | 1209 | bdiff = diff; |
1210 | bf = feedback; | | 1210 | bf = feedback; |
1211 | bpre = prescale; | | 1211 | bpre = prescale; |
1212 | bpost = postscale; | | 1212 | bpost = postscale; |
1213 | if (diff == 0) | | 1213 | if (diff == 0) |
1214 | goto out; | | 1214 | goto out; |
1215 | } | | 1215 | } |
1216 | } | | 1216 | } |
1217 | feedback++; | | 1217 | feedback++; |
1218 | } while (--count >= 0); | | 1218 | } while (--count >= 0); |
1219 | } | | 1219 | } |
1220 | } | | 1220 | } |
1221 | out: | | 1221 | out: |
1222 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_PRE_SCALE, bpre); | | 1222 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_PRE_SCALE, bpre); |
1223 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_FEEDBACK_SCALE, bf); | | 1223 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_FEEDBACK_SCALE, bf); |
1224 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_POST_SCALE, bpost); | | 1224 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_POST_SCALE, bpost); |
1225 | return 0; | | 1225 | return 0; |
1226 | } | | 1226 | } |
1227 | | | 1227 | |
1228 | static void | | 1228 | static void |
1229 | pm3fb_set_mode(struct pm3fb_softc *sc, const struct videomode *mode) | | 1229 | pm3fb_set_mode(struct pm3fb_softc *sc, const struct videomode *mode) |
1230 | { | | 1230 | { |
1231 | int t1, t2, t3, t4, stride; | | 1231 | int t1, t2, t3, t4, stride; |
1232 | uint32_t vclk, tmp1; | | 1232 | uint32_t vclk, tmp1; |
1233 | uint8_t sync = 0; | | 1233 | uint8_t sync = 0; |
1234 | | | 1234 | |
1235 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BYPASS_MASK, 0xffffffff); | | 1235 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BYPASS_MASK, 0xffffffff); |
1236 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE1_CONTROL, 0x00000000); | | 1236 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE1_CONTROL, 0x00000000); |
1237 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE2_CONTROL, 0x00000000); | | 1237 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE2_CONTROL, 0x00000000); |
1238 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFODISCONNECT, 0x00000007); | | 1238 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFODISCONNECT, 0x00000007); |
1239 | | | 1239 | |
1240 | t1 = mode->hsync_start - mode->hdisplay; | | 1240 | t1 = mode->hsync_start - mode->hdisplay; |
1241 | t2 = mode->vsync_start - mode->vdisplay; | | 1241 | t2 = mode->vsync_start - mode->vdisplay; |
1242 | t3 = mode->hsync_end - mode->hsync_start; | | 1242 | t3 = mode->hsync_end - mode->hsync_start; |
1243 | t4 = mode->vsync_end - mode->vsync_start; | | 1243 | t4 = mode->vsync_end - mode->vsync_start; |
1244 | stride = (mode->hdisplay + 31) & ~31; | | 1244 | stride = (mode->hdisplay + 31) & ~31; |
1245 | | | 1245 | |
1246 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_TOTAL, | | 1246 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_TOTAL, |
1247 | ((mode->htotal - 1) >> 4)); | | 1247 | ((mode->htotal - 1) >> 4)); |
1248 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_END, | | 1248 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_END, |
1249 | (t1 + t3) >> 4); | | 1249 | (t1 + t3) >> 4); |
1250 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_START, | | 1250 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_START, |
1251 | (t1 >> 4)); | | 1251 | (t1 >> 4)); |
1252 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_BLANK_END, | | 1252 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_BLANK_END, |
1253 | (mode->htotal - mode->hdisplay) >> 4); | | 1253 | (mode->htotal - mode->hdisplay) >> 4); |
1254 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_GATE_END, | | 1254 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_GATE_END, |
1255 | (mode->htotal - mode->hdisplay) >> 4); | | 1255 | (mode->htotal - mode->hdisplay) >> 4); |
1256 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_STRIDE, | | 1256 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_STRIDE, |
1257 | (stride >> 4)); | | 1257 | (stride >> 4)); |
1258 | | | 1258 | |
1259 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1259 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1260 | PM3_VERT_TOTAL, mode->vtotal - 1); | | 1260 | PM3_VERT_TOTAL, mode->vtotal - 1); |
1261 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1261 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1262 | PM3_VERT_SYNC_END, t2 + t4 - 1); | | 1262 | PM3_VERT_SYNC_END, t2 + t4 - 1); |
1263 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1263 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1264 | PM3_VERT_SYNC_START, t2 - 1); | | 1264 | PM3_VERT_SYNC_START, t2 - 1); |
1265 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1265 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1266 | PM3_VERT_BLANK_END, mode->vtotal - mode->vdisplay); | | 1266 | PM3_VERT_BLANK_END, mode->vtotal - mode->vdisplay); |
1267 | | | 1267 | |
1268 | /*8bpp*/ | | 1268 | /*8bpp*/ |
1269 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1269 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1270 | PM3_BYAPERTURE1MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT); | | 1270 | PM3_BYAPERTURE1MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT); |
1271 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1271 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1272 | PM3_BYAPERTURE2MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT); | | 1272 | PM3_BYAPERTURE2MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT); |
1273 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_VIDEO_CONTROL, | | 1273 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_VIDEO_CONTROL, |
1274 | (PM3_VC_ENABLE | PM3_VC_HSC_ACTIVE_HIGH | PM3_VC_VSC_ACTIVE_HIGH | PM3_VC_PIXELSIZE_8BIT)); | | 1274 | (PM3_VC_ENABLE | PM3_VC_HSC_ACTIVE_HIGH | PM3_VC_VSC_ACTIVE_HIGH | PM3_VC_PIXELSIZE_8BIT)); |
1275 | | | 1275 | |
1276 | vclk = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL); | | 1276 | vclk = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL); |
1277 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL, (vclk & 0xFFFFFFFC)); | | 1277 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL, (vclk & 0xFFFFFFFC)); |
1278 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_BASE, 0x0); | | 1278 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_BASE, 0x0); |
1279 | | | 1279 | |
1280 | tmp1 = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG); | | 1280 | tmp1 = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG); |
1281 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG, tmp1 & 0xFFFFFFFD); | | 1281 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG, tmp1 & 0xFFFFFFFD); |
1282 | | | 1282 | |
1283 | pm3fb_set_pll(sc, mode->dot_clock); | | 1283 | pm3fb_set_pll(sc, mode->dot_clock); |
1284 | | | 1284 | |
1285 | if (mode->flags & VID_PHSYNC) | | 1285 | if (mode->flags & VID_PHSYNC) |
1286 | sync |= PM3_SC_HSYNC_ACTIVE_HIGH; | | 1286 | sync |= PM3_SC_HSYNC_ACTIVE_HIGH; |
1287 | if (mode->flags & VID_PVSYNC) | | 1287 | if (mode->flags & VID_PVSYNC) |
1288 | sync |= PM3_SC_VSYNC_ACTIVE_HIGH; | | 1288 | sync |= PM3_SC_VSYNC_ACTIVE_HIGH; |
1289 | | | 1289 | |
1290 | bus_space_write_4(sc->sc_memt, sc->sc_regh, | | 1290 | bus_space_write_4(sc->sc_memt, sc->sc_regh, |
1291 | PM3_RD_PM3_INDEX_CONTROL, PM3_INCREMENT_DISABLE); | | 1291 | PM3_RD_PM3_INDEX_CONTROL, PM3_INCREMENT_DISABLE); |
1292 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_SYNC_CONTROL, sync); | | 1292 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_SYNC_CONTROL, sync); |
1293 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_DAC_CONTROL, 0x00); | | 1293 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_DAC_CONTROL, 0x00); |
1294 | | | 1294 | |
1295 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_PIXEL_SIZE, PM3_DACPS_8BIT); | | 1295 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_PIXEL_SIZE, PM3_DACPS_8BIT); |
1296 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_COLOR_FORMAT, | | 1296 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_COLOR_FORMAT, |
1297 | (PM3_CF_ORDER_BGR | PM3_CF_VISUAL_256_COLOR)); | | 1297 | (PM3_CF_ORDER_BGR | PM3_CF_VISUAL_256_COLOR)); |
1298 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_MISC_CONTROL, PM3_MC_DAC_SIZE_8BIT); | | 1298 | pm3fb_write_dac(sc, PM3_RAMDAC_CMD_MISC_CONTROL, PM3_MC_DAC_SIZE_8BIT); |
1299 | | | 1299 | |
1300 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFOCONTROL, 0x00000905); | | 1300 | bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFOCONTROL, 0x00000905); |
1301 | | | 1301 | |
1302 | sc->sc_width = mode->hdisplay; | | 1302 | sc->sc_width = mode->hdisplay; |
1303 | sc->sc_height = mode->vdisplay; | | 1303 | sc->sc_height = mode->vdisplay; |
1304 | sc->sc_depth = 8; | | 1304 | sc->sc_depth = 8; |
1305 | sc->sc_stride = stride; | | 1305 | sc->sc_stride = stride; |
1306 | aprint_normal_dev(sc->sc_dev, "pm3 using %d x %d in 8 bit, stride %d\n", | | 1306 | aprint_normal_dev(sc->sc_dev, "pm3 using %d x %d in 8 bit, stride %d\n", |
1307 | sc->sc_width, sc->sc_height, sc->sc_width); | | 1307 | sc->sc_width, sc->sc_height, stride); |
1308 | } | | 1308 | } |