| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: crmfb.c,v 1.37 2013/12/16 15:45:29 mrg Exp $ */ | | 1 | /* $NetBSD: crmfb.c,v 1.38 2014/09/02 15:44:44 macallan Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * 2008 Michael Lorenz <macallan@netbsd.org> | | 5 | * 2008 Michael Lorenz <macallan@netbsd.org> |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | * POSSIBILITY OF SUCH DAMAGE. | | 27 | * POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | /* | | 30 | /* |
31 | * SGI-CRM (O2) Framebuffer driver | | 31 | * SGI-CRM (O2) Framebuffer driver |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: crmfb.c,v 1.37 2013/12/16 15:45:29 mrg Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: crmfb.c,v 1.38 2014/09/02 15:44:44 macallan Exp $"); |
36 | | | 36 | |
37 | #include <sys/param.h> | | 37 | #include <sys/param.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/device.h> | | 39 | #include <sys/device.h> |
40 | #include <sys/malloc.h> | | 40 | #include <sys/malloc.h> |
41 | | | 41 | |
42 | #define _SGIMIPS_BUS_DMA_PRIVATE | | 42 | #define _SGIMIPS_BUS_DMA_PRIVATE |
43 | #include <machine/autoconf.h> | | 43 | #include <machine/autoconf.h> |
44 | #include <sys/bus.h> | | 44 | #include <sys/bus.h> |
45 | #include <machine/machtype.h> | | 45 | #include <machine/machtype.h> |
46 | #include <machine/vmparam.h> | | 46 | #include <machine/vmparam.h> |
47 | | | 47 | |
48 | #include <dev/arcbios/arcbios.h> | | 48 | #include <dev/arcbios/arcbios.h> |
| @@ -143,30 +143,33 @@ struct crmfb_softc { | | | @@ -143,30 +143,33 @@ struct crmfb_softc { |
143 | | | 143 | |
144 | struct crmfb_dma sc_dma; | | 144 | struct crmfb_dma sc_dma; |
145 | struct crmfb_dma sc_dmai; | | 145 | struct crmfb_dma sc_dmai; |
146 | | | 146 | |
147 | int sc_width; | | 147 | int sc_width; |
148 | int sc_height; | | 148 | int sc_height; |
149 | int sc_depth; | | 149 | int sc_depth; |
150 | int sc_console_depth; | | 150 | int sc_console_depth; |
151 | int sc_tiles_x, sc_tiles_y; | | 151 | int sc_tiles_x, sc_tiles_y; |
152 | uint32_t sc_fbsize; | | 152 | uint32_t sc_fbsize; |
153 | int sc_mte_direction; | | 153 | int sc_mte_direction; |
154 | int sc_mte_x_shift; | | 154 | int sc_mte_x_shift; |
155 | uint32_t sc_mte_mode; | | 155 | uint32_t sc_mte_mode; |
| | | 156 | uint32_t sc_de_mode; |
156 | uint8_t *sc_scratch; | | 157 | uint8_t *sc_scratch; |
157 | paddr_t sc_linear; | | 158 | paddr_t sc_linear; |
158 | int sc_wsmode; | | 159 | uint32_t sc_vtflags; |
159 | struct edid_info sc_edid_info; | | 160 | int sc_wsmode, sc_video_on; |
| | | 161 | uint8_t sc_edid_data[128]; |
| | | 162 | struct edid_info sc_edid_info; |
160 | | | 163 | |
161 | /* cursor stuff */ | | 164 | /* cursor stuff */ |
162 | int sc_cur_x; | | 165 | int sc_cur_x; |
163 | int sc_cur_y; | | 166 | int sc_cur_y; |
164 | int sc_hot_x; | | 167 | int sc_hot_x; |
165 | int sc_hot_y; | | 168 | int sc_hot_y; |
166 | | | 169 | |
167 | u_char sc_cmap_red[256]; | | 170 | u_char sc_cmap_red[256]; |
168 | u_char sc_cmap_green[256]; | | 171 | u_char sc_cmap_green[256]; |
169 | u_char sc_cmap_blue[256]; | | 172 | u_char sc_cmap_blue[256]; |
170 | }; | | 173 | }; |
171 | | | 174 | |
172 | static int crmfb_putcmap(struct crmfb_softc *, struct wsdisplay_cmap *); | | 175 | static int crmfb_putcmap(struct crmfb_softc *, struct wsdisplay_cmap *); |
| @@ -273,26 +276,30 @@ crmfb_attach(device_t parent, device_t s | | | @@ -273,26 +276,30 @@ crmfb_attach(device_t parent, device_t s |
273 | sc->sc_width = (d >> CRMFB_VT_HCMAP_ON_SHIFT) & 0xfff; | | 276 | sc->sc_width = (d >> CRMFB_VT_HCMAP_ON_SHIFT) & 0xfff; |
274 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_VT_VCMAP); | | 277 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_VT_VCMAP); |
275 | sc->sc_height = (d >> CRMFB_VT_VCMAP_ON_SHIFT) & 0xfff; | | 278 | sc->sc_height = (d >> CRMFB_VT_VCMAP_ON_SHIFT) & 0xfff; |
276 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_TILESIZE); | | 279 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_TILESIZE); |
277 | h = (d >> CRMFB_FRM_TILESIZE_DEPTH_SHIFT) & 0x3; | | 280 | h = (d >> CRMFB_FRM_TILESIZE_DEPTH_SHIFT) & 0x3; |
278 | if (h == 0) | | 281 | if (h == 0) |
279 | sc->sc_depth = 8; | | 282 | sc->sc_depth = 8; |
280 | else if (h == 1) | | 283 | else if (h == 1) |
281 | sc->sc_depth = 16; | | 284 | sc->sc_depth = 16; |
282 | else | | 285 | else |
283 | sc->sc_depth = 32; | | 286 | sc->sc_depth = 32; |
284 | | | 287 | |
285 | if (sc->sc_width == 0 || sc->sc_height == 0) { | | 288 | if (sc->sc_width == 0 || sc->sc_height == 0) { |
| | | 289 | /* |
| | | 290 | * XXX |
| | | 291 | * actually, these days we probably could |
| | | 292 | */ |
286 | aprint_error_dev(sc->sc_dev, | | 293 | aprint_error_dev(sc->sc_dev, |
287 | "device unusable if not setup by firmware\n"); | | 294 | "device unusable if not setup by firmware\n"); |
288 | bus_space_unmap(sc->sc_iot, sc->sc_ioh, 0 /* XXX */); | | 295 | bus_space_unmap(sc->sc_iot, sc->sc_ioh, 0 /* XXX */); |
289 | return; | | 296 | return; |
290 | } | | 297 | } |
291 | | | 298 | |
292 | aprint_normal_dev(sc->sc_dev, "initial resolution %dx%d\n", | | 299 | aprint_normal_dev(sc->sc_dev, "initial resolution %dx%d\n", |
293 | sc->sc_width, sc->sc_height); | | 300 | sc->sc_width, sc->sc_height); |
294 | | | 301 | |
295 | sc->sc_console_depth = 8; | | 302 | sc->sc_console_depth = 8; |
296 | | | 303 | |
297 | crmfb_setup_ddc(sc); | | 304 | crmfb_setup_ddc(sc); |
298 | if ((sc->sc_edid_info.edid_preferred_mode != NULL)) { | | 305 | if ((sc->sc_edid_info.edid_preferred_mode != NULL)) { |
| @@ -357,26 +364,27 @@ crmfb_attach(device_t parent, device_t s | | | @@ -357,26 +364,27 @@ crmfb_attach(device_t parent, device_t s |
357 | p[i] = ((uint32_t)v >> 16) + i; | | 364 | p[i] = ((uint32_t)v >> 16) + i; |
358 | } | | 365 | } |
359 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmai.map, 0, sc->sc_dmai.size, | | 366 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmai.map, 0, sc->sc_dmai.size, |
360 | BUS_DMASYNC_PREWRITE); | | 367 | BUS_DMASYNC_PREWRITE); |
361 | sc->sc_scratch = (char *)KERNADDR(sc->sc_dma) + (0xf0000 * sc->sc_tiles_x); | | 368 | sc->sc_scratch = (char *)KERNADDR(sc->sc_dma) + (0xf0000 * sc->sc_tiles_x); |
362 | sc->sc_linear = (paddr_t)DMAADDR(sc->sc_dma) + 0x100000 * sc->sc_tiles_x; | | 369 | sc->sc_linear = (paddr_t)DMAADDR(sc->sc_dma) + 0x100000 * sc->sc_tiles_x; |
363 | | | 370 | |
364 | aprint_normal_dev(sc->sc_dev, "allocated %d byte fb @ %p (%p)\n", | | 371 | aprint_normal_dev(sc->sc_dev, "allocated %d byte fb @ %p (%p)\n", |
365 | sc->sc_fbsize, KERNADDR(sc->sc_dmai), KERNADDR(sc->sc_dma)); | | 372 | sc->sc_fbsize, KERNADDR(sc->sc_dmai), KERNADDR(sc->sc_dma)); |
366 | | | 373 | |
367 | crmfb_setup_video(sc, sc->sc_console_depth); | | 374 | crmfb_setup_video(sc, sc->sc_console_depth); |
368 | ri = &crmfb_console_screen.scr_ri; | | 375 | ri = &crmfb_console_screen.scr_ri; |
369 | memset(ri, 0, sizeof(struct rasops_info)); | | 376 | memset(ri, 0, sizeof(struct rasops_info)); |
| | | 377 | sc->sc_video_on = 1; |
370 | | | 378 | |
371 | vcons_init(&sc->sc_vd, sc, &crmfb_defaultscreen, &crmfb_accessops); | | 379 | vcons_init(&sc->sc_vd, sc, &crmfb_defaultscreen, &crmfb_accessops); |
372 | sc->sc_vd.init_screen = crmfb_init_screen; | | 380 | sc->sc_vd.init_screen = crmfb_init_screen; |
373 | crmfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | | 381 | crmfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; |
374 | vcons_init_screen(&sc->sc_vd, &crmfb_console_screen, 1, &defattr); | | 382 | vcons_init_screen(&sc->sc_vd, &crmfb_console_screen, 1, &defattr); |
375 | | | 383 | |
376 | crmfb_defaultscreen.ncols = ri->ri_cols; | | 384 | crmfb_defaultscreen.ncols = ri->ri_cols; |
377 | crmfb_defaultscreen.nrows = ri->ri_rows; | | 385 | crmfb_defaultscreen.nrows = ri->ri_rows; |
378 | crmfb_defaultscreen.textops = &ri->ri_ops; | | 386 | crmfb_defaultscreen.textops = &ri->ri_ops; |
379 | crmfb_defaultscreen.capabilities = ri->ri_caps; | | 387 | crmfb_defaultscreen.capabilities = ri->ri_caps; |
380 | crmfb_defaultscreen.modecookie = NULL; | | 388 | crmfb_defaultscreen.modecookie = NULL; |
381 | | | 389 | |
382 | crmfb_setup_palette(sc); | | 390 | crmfb_setup_palette(sc); |
| @@ -418,27 +426,27 @@ static int | | | @@ -418,27 +426,27 @@ static int |
418 | crmfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) | | 426 | crmfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) |
419 | { | | 427 | { |
420 | struct vcons_data *vd; | | 428 | struct vcons_data *vd; |
421 | struct crmfb_softc *sc; | | 429 | struct crmfb_softc *sc; |
422 | struct wsdisplay_fbinfo *wdf; | | 430 | struct wsdisplay_fbinfo *wdf; |
423 | int nmode; | | 431 | int nmode; |
424 | | | 432 | |
425 | vd = (struct vcons_data *)v; | | 433 | vd = (struct vcons_data *)v; |
426 | sc = (struct crmfb_softc *)vd->cookie; | | 434 | sc = (struct crmfb_softc *)vd->cookie; |
427 | | | 435 | |
428 | switch (cmd) { | | 436 | switch (cmd) { |
429 | case WSDISPLAYIO_GTYPE: | | 437 | case WSDISPLAYIO_GTYPE: |
430 | /* not really, but who cares? */ | | 438 | /* not really, but who cares? */ |
431 | /* wsfb does */ | | 439 | /* xf86-video-crime does */ |
432 | *(u_int *)data = WSDISPLAY_TYPE_CRIME; | | 440 | *(u_int *)data = WSDISPLAY_TYPE_CRIME; |
433 | return 0; | | 441 | return 0; |
434 | case WSDISPLAYIO_GINFO: | | 442 | case WSDISPLAYIO_GINFO: |
435 | if (vd->active != NULL) { | | 443 | if (vd->active != NULL) { |
436 | wdf = (void *)data; | | 444 | wdf = (void *)data; |
437 | wdf->height = sc->sc_height; | | 445 | wdf->height = sc->sc_height; |
438 | wdf->width = sc->sc_width; | | 446 | wdf->width = sc->sc_width; |
439 | wdf->depth = 32; | | 447 | wdf->depth = 32; |
440 | wdf->cmsize = 256; | | 448 | wdf->cmsize = 256; |
441 | return 0; | | 449 | return 0; |
442 | } else | | 450 | } else |
443 | return ENODEV; | | 451 | return ENODEV; |
444 | case WSDISPLAYIO_GETCMAP: | | 452 | case WSDISPLAYIO_GETCMAP: |
| @@ -458,28 +466,47 @@ crmfb_ioctl(void *v, void *vs, u_long cm | | | @@ -458,28 +466,47 @@ crmfb_ioctl(void *v, void *vs, u_long cm |
458 | nmode = *(int *)data; | | 466 | nmode = *(int *)data; |
459 | if (nmode != sc->sc_wsmode) { | | 467 | if (nmode != sc->sc_wsmode) { |
460 | sc->sc_wsmode = nmode; | | 468 | sc->sc_wsmode = nmode; |
461 | if (nmode == WSDISPLAYIO_MODE_EMUL) { | | 469 | if (nmode == WSDISPLAYIO_MODE_EMUL) { |
462 | crmfb_setup_video(sc, sc->sc_console_depth); | | 470 | crmfb_setup_video(sc, sc->sc_console_depth); |
463 | crmfb_setup_palette(sc); | | 471 | crmfb_setup_palette(sc); |
464 | vcons_redraw_screen(vd->active); | | 472 | vcons_redraw_screen(vd->active); |
465 | } else { | | 473 | } else { |
466 | crmfb_setup_video(sc, 32); | | 474 | crmfb_setup_video(sc, 32); |
467 | } | | 475 | } |
468 | } | | 476 | } |
469 | return 0; | | 477 | return 0; |
470 | case WSDISPLAYIO_SVIDEO: | | 478 | case WSDISPLAYIO_SVIDEO: |
| | | 479 | { |
| | | 480 | int d = *(int *)data; |
| | | 481 | if (d == sc->sc_video_on) |
| | | 482 | return 0; |
| | | 483 | sc->sc_video_on = d; |
| | | 484 | if (d == WSDISPLAYIO_VIDEO_ON) { |
| | | 485 | crmfb_write_reg(sc, |
| | | 486 | CRMFB_VT_FLAGS, sc->sc_vtflags); |
| | | 487 | } else { |
| | | 488 | /* turn all SYNCs off */ |
| | | 489 | crmfb_write_reg(sc, CRMFB_VT_FLAGS, |
| | | 490 | sc->sc_vtflags | CRMFB_VT_FLAGS_VDRV_LOW | |
| | | 491 | CRMFB_VT_FLAGS_HDRV_LOW | |
| | | 492 | CRMFB_VT_FLAGS_SYNC_LOW); |
| | | 493 | } |
| | | 494 | } |
| | | 495 | return 0; |
| | | 496 | |
471 | case WSDISPLAYIO_GVIDEO: | | 497 | case WSDISPLAYIO_GVIDEO: |
472 | return ENODEV; /* not supported yet */ | | 498 | *(int *)data = sc->sc_video_on; |
| | | 499 | return 0; |
473 | | | 500 | |
474 | case WSDISPLAYIO_GCURPOS: | | 501 | case WSDISPLAYIO_GCURPOS: |
475 | { | | 502 | { |
476 | struct wsdisplay_curpos *pos; | | 503 | struct wsdisplay_curpos *pos; |
477 | | | 504 | |
478 | pos = (struct wsdisplay_curpos *)data; | | 505 | pos = (struct wsdisplay_curpos *)data; |
479 | pos->x = sc->sc_cur_x; | | 506 | pos->x = sc->sc_cur_x; |
480 | pos->y = sc->sc_cur_y; | | 507 | pos->y = sc->sc_cur_y; |
481 | } | | 508 | } |
482 | return 0; | | 509 | return 0; |
483 | case WSDISPLAYIO_SCURPOS: | | 510 | case WSDISPLAYIO_SCURPOS: |
484 | { | | 511 | { |
485 | struct wsdisplay_curpos *pos; | | 512 | struct wsdisplay_curpos *pos; |
| @@ -501,26 +528,36 @@ crmfb_ioctl(void *v, void *vs, u_long cm | | | @@ -501,26 +528,36 @@ crmfb_ioctl(void *v, void *vs, u_long cm |
501 | { | | 528 | { |
502 | struct wsdisplay_cursor *cu; | | 529 | struct wsdisplay_cursor *cu; |
503 | | | 530 | |
504 | cu = (struct wsdisplay_cursor *)data; | | 531 | cu = (struct wsdisplay_cursor *)data; |
505 | return crmfb_gcursor(sc, cu); | | 532 | return crmfb_gcursor(sc, cu); |
506 | } | | 533 | } |
507 | case WSDISPLAYIO_SCURSOR: | | 534 | case WSDISPLAYIO_SCURSOR: |
508 | { | | 535 | { |
509 | struct wsdisplay_cursor *cu; | | 536 | struct wsdisplay_cursor *cu; |
510 | | | 537 | |
511 | cu = (struct wsdisplay_cursor *)data; | | 538 | cu = (struct wsdisplay_cursor *)data; |
512 | return crmfb_scursor(sc, cu); | | 539 | return crmfb_scursor(sc, cu); |
513 | } | | 540 | } |
| | | 541 | case WSDISPLAYIO_GET_EDID: { |
| | | 542 | struct wsdisplayio_edid_info *d = data; |
| | | 543 | |
| | | 544 | d->data_size = 128; |
| | | 545 | if (d->buffer_size < 128) |
| | | 546 | return EAGAIN; |
| | | 547 | if (sc->sc_edid_data[1] == 0) |
| | | 548 | return ENODATA; |
| | | 549 | return copyout(sc->sc_edid_data, d->edid_data, 128); |
| | | 550 | } |
514 | } | | 551 | } |
515 | return EPASSTHROUGH; | | 552 | return EPASSTHROUGH; |
516 | } | | 553 | } |
517 | | | 554 | |
518 | static paddr_t | | 555 | static paddr_t |
519 | crmfb_mmap(void *v, void *vs, off_t offset, int prot) | | 556 | crmfb_mmap(void *v, void *vs, off_t offset, int prot) |
520 | { | | 557 | { |
521 | struct vcons_data *vd; | | 558 | struct vcons_data *vd; |
522 | struct crmfb_softc *sc; | | 559 | struct crmfb_softc *sc; |
523 | paddr_t pa; | | 560 | paddr_t pa; |
524 | | | 561 | |
525 | vd = (struct vcons_data *)v; | | 562 | vd = (struct vcons_data *)v; |
526 | sc = (struct crmfb_softc *)vd->cookie; | | 563 | sc = (struct crmfb_softc *)vd->cookie; |
| @@ -557,42 +594,45 @@ crmfb_init_screen(void *c, struct vcons_ | | | @@ -557,42 +594,45 @@ crmfb_init_screen(void *c, struct vcons_ |
557 | long *defattr) | | 594 | long *defattr) |
558 | { | | 595 | { |
559 | struct crmfb_softc *sc; | | 596 | struct crmfb_softc *sc; |
560 | struct rasops_info *ri; | | 597 | struct rasops_info *ri; |
561 | | | 598 | |
562 | sc = (struct crmfb_softc *)c; | | 599 | sc = (struct crmfb_softc *)c; |
563 | ri = &scr->scr_ri; | | 600 | ri = &scr->scr_ri; |
564 | | | 601 | |
565 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; | | 602 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; |
566 | ri->ri_depth = sc->sc_console_depth; | | 603 | ri->ri_depth = sc->sc_console_depth; |
567 | ri->ri_width = sc->sc_width; | | 604 | ri->ri_width = sc->sc_width; |
568 | ri->ri_height = sc->sc_height; | | 605 | ri->ri_height = sc->sc_height; |
569 | ri->ri_stride = ri->ri_width * (ri->ri_depth / 8); | | 606 | ri->ri_stride = ri->ri_width * (ri->ri_depth / 8); |
570 | #if 1 | | 607 | |
571 | switch (ri->ri_depth) { | | 608 | switch (ri->ri_depth) { |
| | | 609 | case 8: |
| | | 610 | ri->ri_flg |= RI_8BIT_IS_RGB; |
| | | 611 | break; |
572 | case 16: | | 612 | case 16: |
573 | ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 5; | | 613 | ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 5; |
574 | ri->ri_rpos = 11; | | 614 | ri->ri_rpos = 11; |
575 | ri->ri_gpos = 6; | | 615 | ri->ri_gpos = 6; |
576 | ri->ri_bpos = 1; | | 616 | ri->ri_bpos = 1; |
577 | break; | | 617 | break; |
578 | case 32: | | 618 | case 32: |
579 | ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 8; | | 619 | ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 8; |
580 | ri->ri_rpos = 8; | | 620 | ri->ri_rpos = 8; |
581 | ri->ri_gpos = 16; | | 621 | ri->ri_gpos = 16; |
582 | ri->ri_bpos = 24; | | 622 | ri->ri_bpos = 24; |
583 | break; | | 623 | break; |
584 | } | | 624 | } |
585 | #endif | | 625 | |
586 | ri->ri_bits = KERNADDR(sc->sc_dma); | | 626 | ri->ri_bits = KERNADDR(sc->sc_dma); |
587 | | | 627 | |
588 | if (existing) | | 628 | if (existing) |
589 | ri->ri_flg |= RI_CLEAR; | | 629 | ri->ri_flg |= RI_CLEAR; |
590 | | | 630 | |
591 | rasops_init(ri, 0, 0); | | 631 | rasops_init(ri, 0, 0); |
592 | ri->ri_caps = WSSCREEN_WSCOLORS; | | 632 | ri->ri_caps = WSSCREEN_WSCOLORS; |
593 | rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, | | 633 | rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, |
594 | ri->ri_width / ri->ri_font->fontwidth); | | 634 | ri->ri_width / ri->ri_font->fontwidth); |
595 | ri->ri_hw = scr; | | 635 | ri->ri_hw = scr; |
596 | | | 636 | |
597 | ri->ri_ops.cursor = crmfb_cursor; | | 637 | ri->ri_ops.cursor = crmfb_cursor; |
598 | ri->ri_ops.copyrows = crmfb_copyrows; | | 638 | ri->ri_ops.copyrows = crmfb_copyrows; |
| @@ -804,27 +844,27 @@ crmfb_wait_dma_idle(struct crmfb_softc * | | | @@ -804,27 +844,27 @@ crmfb_wait_dma_idle(struct crmfb_softc * |
804 | ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, | | 844 | ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, |
805 | CRMFB_DID_CONTROL) & 1) == 0); | | 845 | CRMFB_DID_CONTROL) & 1) == 0); |
806 | if (!idle) | | 846 | if (!idle) |
807 | delay(10); | | 847 | delay(10); |
808 | bail--; | | 848 | bail--; |
809 | } while ((!idle) && (bail > 0)); | | 849 | } while ((!idle) && (bail > 0)); |
810 | return idle; | | 850 | return idle; |
811 | } | | 851 | } |
812 | | | 852 | |
813 | static int | | 853 | static int |
814 | crmfb_setup_video(struct crmfb_softc *sc, int depth) | | 854 | crmfb_setup_video(struct crmfb_softc *sc, int depth) |
815 | { | | 855 | { |
816 | uint64_t reg; | | 856 | uint64_t reg; |
817 | uint32_t d, h, mode, page; | | 857 | uint32_t d, h, page; |
818 | int i, bail, tile_width, tlbptr, lptr, j, tx, shift, overhang; | | 858 | int i, bail, tile_width, tlbptr, lptr, j, tx, shift, overhang; |
819 | const char *wantsync; | | 859 | const char *wantsync; |
820 | uint16_t v; | | 860 | uint16_t v; |
821 | | | 861 | |
822 | /* disable DMA */ | | 862 | /* disable DMA */ |
823 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_OVR_CONTROL); | | 863 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_OVR_CONTROL); |
824 | d &= ~(1 << CRMFB_OVR_CONTROL_DMAEN_SHIFT); | | 864 | d &= ~(1 << CRMFB_OVR_CONTROL_DMAEN_SHIFT); |
825 | crmfb_write_reg(sc, CRMFB_OVR_CONTROL, d); | | 865 | crmfb_write_reg(sc, CRMFB_OVR_CONTROL, d); |
826 | DELAY(50000); | | 866 | DELAY(50000); |
827 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_CONTROL); | | 867 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_CONTROL); |
828 | d &= ~(1 << CRMFB_FRM_CONTROL_DMAEN_SHIFT); | | 868 | d &= ~(1 << CRMFB_FRM_CONTROL_DMAEN_SHIFT); |
829 | crmfb_write_reg(sc, CRMFB_FRM_CONTROL, d); | | 869 | crmfb_write_reg(sc, CRMFB_FRM_CONTROL, d); |
830 | DELAY(50000); | | 870 | DELAY(50000); |
| @@ -852,27 +892,27 @@ crmfb_setup_video(struct crmfb_softc *sc | | | @@ -852,27 +892,27 @@ crmfb_setup_video(struct crmfb_softc *sc |
852 | bail--; | | 892 | bail--; |
853 | } | | 893 | } |
854 | | | 894 | |
855 | /* reset FIFO */ | | 895 | /* reset FIFO */ |
856 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_TILESIZE); | | 896 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_FRM_TILESIZE); |
857 | d |= (1 << CRMFB_FRM_TILESIZE_FIFOR_SHIFT); | | 897 | d |= (1 << CRMFB_FRM_TILESIZE_FIFOR_SHIFT); |
858 | crmfb_write_reg(sc, CRMFB_FRM_TILESIZE, d); | | 898 | crmfb_write_reg(sc, CRMFB_FRM_TILESIZE, d); |
859 | d &= ~(1 << CRMFB_FRM_TILESIZE_FIFOR_SHIFT); | | 899 | d &= ~(1 << CRMFB_FRM_TILESIZE_FIFOR_SHIFT); |
860 | crmfb_write_reg(sc, CRMFB_FRM_TILESIZE, d); | | 900 | crmfb_write_reg(sc, CRMFB_FRM_TILESIZE, d); |
861 | | | 901 | |
862 | /* setup colour mode */ | | 902 | /* setup colour mode */ |
863 | switch (depth) { | | 903 | switch (depth) { |
864 | case 8: | | 904 | case 8: |
865 | h = CRMFB_MODE_TYP_I8; | | 905 | h = CRMFB_MODE_TYP_RG3B2; |
866 | tile_width = 512; | | 906 | tile_width = 512; |
867 | break; | | 907 | break; |
868 | case 16: | | 908 | case 16: |
869 | h = CRMFB_MODE_TYP_ARGB5; | | 909 | h = CRMFB_MODE_TYP_ARGB5; |
870 | tile_width = 256; | | 910 | tile_width = 256; |
871 | break; | | 911 | break; |
872 | case 32: | | 912 | case 32: |
873 | h = CRMFB_MODE_TYP_RGB8; | | 913 | h = CRMFB_MODE_TYP_RGB8; |
874 | tile_width = 128; | | 914 | tile_width = 128; |
875 | break; | | 915 | break; |
876 | default: | | 916 | default: |
877 | panic("Unsupported depth"); | | 917 | panic("Unsupported depth"); |
878 | } | | 918 | } |
| @@ -933,29 +973,27 @@ crmfb_setup_video(struct crmfb_softc *sc | | | @@ -933,29 +973,27 @@ crmfb_setup_video(struct crmfb_softc *sc |
933 | d |= (1 << CRMFB_FRM_CONTROL_DMAEN_SHIFT); | | 973 | d |= (1 << CRMFB_FRM_CONTROL_DMAEN_SHIFT); |
934 | crmfb_write_reg(sc, CRMFB_FRM_CONTROL, d); | | 974 | crmfb_write_reg(sc, CRMFB_FRM_CONTROL, d); |
935 | | | 975 | |
936 | /* enable drawing again */ | | 976 | /* enable drawing again */ |
937 | crmfb_write_reg(sc, CRMFB_VT_XY, 0); | | 977 | crmfb_write_reg(sc, CRMFB_VT_XY, 0); |
938 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_DOTCLOCK); | | 978 | d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CRMFB_DOTCLOCK); |
939 | d |= (1 << CRMFB_DOTCLOCK_CLKRUN_SHIFT); | | 979 | d |= (1 << CRMFB_DOTCLOCK_CLKRUN_SHIFT); |
940 | crmfb_write_reg(sc, CRMFB_DOTCLOCK, d); | | 980 | crmfb_write_reg(sc, CRMFB_DOTCLOCK, d); |
941 | | | 981 | |
942 | /* turn off sync-on-green */ | | 982 | /* turn off sync-on-green */ |
943 | | | 983 | |
944 | wantsync = arcbios_GetEnvironmentVariable("SyncOnGreen"); | | 984 | wantsync = arcbios_GetEnvironmentVariable("SyncOnGreen"); |
945 | if ( (wantsync != NULL) && (wantsync[0] == 'n') ) { | | 985 | if ( (wantsync != NULL) && (wantsync[0] == 'n') ) { |
946 | d = ( 1 << CRMFB_VT_FLAGS_SYNC_LOW_LSB) & | | 986 | sc->sc_vtflags |= CRMFB_VT_FLAGS_SYNC_LOW; |
947 | CRMFB_REG_MASK(CRMFB_VT_FLAGS_SYNC_LOW_MSB, | | | |
948 | CRMFB_VT_FLAGS_SYNC_LOW_LSB); | | | |
949 | crmfb_write_reg(sc, CRMFB_VT_FLAGS, d); | | 987 | crmfb_write_reg(sc, CRMFB_VT_FLAGS, d); |
950 | } | | 988 | } |
951 | | | 989 | |
952 | sc->sc_depth = depth; | | 990 | sc->sc_depth = depth; |
953 | | | 991 | |
954 | /* finally set up the drawing engine's TLB A */ | | 992 | /* finally set up the drawing engine's TLB A */ |
955 | v = (DMAADDR(sc->sc_dma) >> 16) & 0xffff; | | 993 | v = (DMAADDR(sc->sc_dma) >> 16) & 0xffff; |
956 | tlbptr = 0; | | 994 | tlbptr = 0; |
957 | tx = ((sc->sc_width + (tile_width - 1)) & ~(tile_width - 1)) / | | 995 | tx = ((sc->sc_width + (tile_width - 1)) & ~(tile_width - 1)) / |
958 | tile_width; | | 996 | tile_width; |
959 | | | 997 | |
960 | DPRINTF("tx: %d\n", tx); | | 998 | DPRINTF("tx: %d\n", tx); |
961 | | | 999 | |
| @@ -1003,58 +1041,60 @@ crmfb_setup_video(struct crmfb_softc *sc | | | @@ -1003,58 +1041,60 @@ crmfb_setup_video(struct crmfb_softc *sc |
1003 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_WINOFFSET_SRC, 0); | | 1041 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_WINOFFSET_SRC, 0); |
1004 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_WINOFFSET_DST, 0); | | 1042 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_WINOFFSET_DST, 0); |
1005 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_PLANEMASK, | | 1043 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_PLANEMASK, |
1006 | 0xffffffff); | | 1044 | 0xffffffff); |
1007 | | | 1045 | |
1008 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x20, 0); | | 1046 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x20, 0); |
1009 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x28, 0); | | 1047 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x28, 0); |
1010 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x30, 0); | | 1048 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x30, 0); |
1011 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x38, 0); | | 1049 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x38, 0); |
1012 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x40, 0); | | 1050 | bus_space_write_8(sc->sc_iot, sc->sc_reh, 0x40, 0); |
1013 | | | 1051 | |
1014 | switch (depth) { | | 1052 | switch (depth) { |
1015 | case 8: | | 1053 | case 8: |
1016 | mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_8 | | | 1054 | sc->sc_de_mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_8 | |
1017 | DE_MODE_TYPE_CI | DE_MODE_PIXDEPTH_8; | | 1055 | DE_MODE_TYPE_CI | DE_MODE_PIXDEPTH_8; |
1018 | sc->sc_mte_mode = MTE_MODE_DST_ECC | | | 1056 | sc->sc_mte_mode = MTE_MODE_DST_ECC | |
1019 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | | | 1057 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | |
1020 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | | | 1058 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | |
1021 | (MTE_DEPTH_8 << MTE_DEPTH_SHIFT); | | 1059 | (MTE_DEPTH_8 << MTE_DEPTH_SHIFT); |
1022 | sc->sc_mte_x_shift = 0; | | 1060 | sc->sc_mte_x_shift = 0; |
1023 | break; | | 1061 | break; |
1024 | case 16: | | 1062 | case 16: |
1025 | mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_16 | | | 1063 | sc->sc_de_mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_16 | |
1026 | DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_16; | | 1064 | DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_16; |
1027 | sc->sc_mte_mode = MTE_MODE_DST_ECC | | | 1065 | sc->sc_mte_mode = MTE_MODE_DST_ECC | |
1028 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | | | 1066 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | |
1029 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | | | 1067 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | |
1030 | (MTE_DEPTH_16 << MTE_DEPTH_SHIFT); | | 1068 | (MTE_DEPTH_16 << MTE_DEPTH_SHIFT); |
1031 | sc->sc_mte_x_shift = 1; | | 1069 | sc->sc_mte_x_shift = 1; |
1032 | break; | | 1070 | break; |
1033 | case 32: | | 1071 | case 32: |
1034 | mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | | | 1072 | sc->sc_de_mode = DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | |
1035 | DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32; | | 1073 | DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32; |
1036 | break; | | 1074 | break; |
1037 | sc->sc_mte_mode = MTE_MODE_DST_ECC | | | 1075 | sc->sc_mte_mode = MTE_MODE_DST_ECC | |
1038 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | | | 1076 | (MTE_TLB_A << MTE_DST_TLB_SHIFT) | |
1039 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | | | 1077 | (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | |
1040 | (MTE_DEPTH_32 << MTE_DEPTH_SHIFT); | | 1078 | (MTE_DEPTH_32 << MTE_DEPTH_SHIFT); |
1041 | sc->sc_mte_x_shift = 2; | | 1079 | sc->sc_mte_x_shift = 2; |
1042 | default: | | 1080 | default: |
1043 | panic("%s: unsuported colour depth %d\n", __func__, | | 1081 | panic("%s: unsuported colour depth %d\n", __func__, |
1044 | depth); | | 1082 | depth); |
1045 | } | | 1083 | } |
1046 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_DST, mode); | | 1084 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_DST, |
1047 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC, mode); | | 1085 | sc->sc_de_mode); |
| | | 1086 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC, |
| | | 1087 | sc->sc_de_mode); |
1048 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_X, 1); | | 1088 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_X, 1); |
1049 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_Y, 1); | | 1089 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_Y, 1); |
1050 | | | 1090 | |
1051 | /* initialize memory transfer engine */ | | 1091 | /* initialize memory transfer engine */ |
1052 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_MODE, | | 1092 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_MODE, |
1053 | sc->sc_mte_mode | MTE_MODE_COPY); | | 1093 | sc->sc_mte_mode | MTE_MODE_COPY); |
1054 | sc->sc_mte_direction = 1; | | 1094 | sc->sc_mte_direction = 1; |
1055 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_DST_Y_STEP, 1); | | 1095 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_DST_Y_STEP, 1); |
1056 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_SRC_Y_STEP, 1); | | 1096 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_SRC_Y_STEP, 1); |
1057 | | | 1097 | |
1058 | return 0; | | 1098 | return 0; |
1059 | } | | 1099 | } |
1060 | | | 1100 | |
| @@ -1113,26 +1153,28 @@ crmfb_fill_rect(struct crmfb_softc *sc, | | | @@ -1113,26 +1153,28 @@ crmfb_fill_rect(struct crmfb_softc *sc, |
1113 | (rxa << 16) | (y & 0xffff)); | | 1153 | (rxa << 16) | (y & 0xffff)); |
1114 | bus_space_write_4(sc->sc_iot, sc->sc_reh, | | 1154 | bus_space_write_4(sc->sc_iot, sc->sc_reh, |
1115 | CRIME_MTE_DST1 | CRIME_DE_START, | | 1155 | CRIME_MTE_DST1 | CRIME_DE_START, |
1116 | (rxe << 16) | ((y + height - 1) & 0xffff)); | | 1156 | (rxe << 16) | ((y + height - 1) & 0xffff)); |
1117 | } | | 1157 | } |
1118 | | | 1158 | |
1119 | static void | | 1159 | static void |
1120 | crmfb_bitblt(struct crmfb_softc *sc, int xs, int ys, int xd, int yd, | | 1160 | crmfb_bitblt(struct crmfb_softc *sc, int xs, int ys, int xd, int yd, |
1121 | int wi, int he, uint32_t rop) | | 1161 | int wi, int he, uint32_t rop) |
1122 | { | | 1162 | { |
1123 | uint32_t prim = DE_PRIM_RECTANGLE; | | 1163 | uint32_t prim = DE_PRIM_RECTANGLE; |
1124 | int rxa, rya, rxe, rye, rxs, rys; | | 1164 | int rxa, rya, rxe, rye, rxs, rys; |
1125 | crmfb_wait_idle(sc); | | 1165 | crmfb_wait_idle(sc); |
| | | 1166 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC, |
| | | 1167 | sc->sc_de_mode); |
1126 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE, | | 1168 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE, |
1127 | DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | | | 1169 | DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | |
1128 | DE_DRAWMODE_XFER_EN); | | 1170 | DE_DRAWMODE_XFER_EN); |
1129 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_ROP, rop); | | 1171 | bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_ROP, rop); |
1130 | if (xs < xd) { | | 1172 | if (xs < xd) { |
1131 | prim |= DE_PRIM_RL; | | 1173 | prim |= DE_PRIM_RL; |
1132 | rxe = xd; | | 1174 | rxe = xd; |
1133 | rxa = xd + wi - 1; | | 1175 | rxa = xd + wi - 1; |
1134 | rxs = xs + wi - 1; | | 1176 | rxs = xs + wi - 1; |
1135 | } else { | | 1177 | } else { |
1136 | prim |= DE_PRIM_LR; | | 1178 | prim |= DE_PRIM_LR; |
1137 | rxe = xd + wi - 1; | | 1179 | rxe = xd + wi - 1; |
1138 | rxa = xd; | | 1180 | rxa = xd; |
| @@ -1374,46 +1416,45 @@ crmfb_putchar(void *cookie, int row, int | | | @@ -1374,46 +1416,45 @@ crmfb_putchar(void *cookie, int row, int |
1374 | CRIME_DE_X_VERTEX_1 | CRIME_DE_START, | | 1416 | CRIME_DE_X_VERTEX_1 | CRIME_DE_START, |
1375 | ((x + wi) << 16) | y); | | 1417 | ((x + wi) << 16) | y); |
1376 | y++; | | 1418 | y++; |
1377 | fd16++; | | 1419 | fd16++; |
1378 | } | | 1420 | } |
1379 | } | | 1421 | } |
1380 | } | | 1422 | } |
1381 | } | | 1423 | } |
1382 | | | 1424 | |
1383 | static void | | 1425 | static void |
1384 | crmfb_setup_ddc(struct crmfb_softc *sc) | | 1426 | crmfb_setup_ddc(struct crmfb_softc *sc) |
1385 | { | | 1427 | { |
1386 | int i; | | 1428 | int i; |
1387 | char edid_data[128]; | | | |
1388 | | | 1429 | |
1389 | memset(edid_data, 0, 128); | | 1430 | memset(sc->sc_edid_data, 0, 128); |
1390 | sc->sc_i2c.ic_cookie = sc; | | 1431 | sc->sc_i2c.ic_cookie = sc; |
1391 | sc->sc_i2c.ic_acquire_bus = crmfb_i2c_acquire_bus; | | 1432 | sc->sc_i2c.ic_acquire_bus = crmfb_i2c_acquire_bus; |
1392 | sc->sc_i2c.ic_release_bus = crmfb_i2c_release_bus; | | 1433 | sc->sc_i2c.ic_release_bus = crmfb_i2c_release_bus; |
1393 | sc->sc_i2c.ic_send_start = crmfb_i2c_send_start; | | 1434 | sc->sc_i2c.ic_send_start = crmfb_i2c_send_start; |
1394 | sc->sc_i2c.ic_send_stop = crmfb_i2c_send_stop; | | 1435 | sc->sc_i2c.ic_send_stop = crmfb_i2c_send_stop; |
1395 | sc->sc_i2c.ic_initiate_xfer = crmfb_i2c_initiate_xfer; | | 1436 | sc->sc_i2c.ic_initiate_xfer = crmfb_i2c_initiate_xfer; |
1396 | sc->sc_i2c.ic_read_byte = crmfb_i2c_read_byte; | | 1437 | sc->sc_i2c.ic_read_byte = crmfb_i2c_read_byte; |
1397 | sc->sc_i2c.ic_write_byte = crmfb_i2c_write_byte; | | 1438 | sc->sc_i2c.ic_write_byte = crmfb_i2c_write_byte; |
1398 | sc->sc_i2c.ic_exec = NULL; | | 1439 | sc->sc_i2c.ic_exec = NULL; |
1399 | i = 0; | | 1440 | i = 0; |
1400 | while (edid_data[1] == 0 && i++ < 10) | | 1441 | while (sc->sc_edid_data[1] == 0 && i++ < 10) |
1401 | ddc_read_edid(&sc->sc_i2c, edid_data, 128); | | 1442 | ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128); |
1402 | if (i > 1) | | 1443 | if (i > 1) |
1403 | aprint_debug_dev(sc->sc_dev, | | 1444 | aprint_debug_dev(sc->sc_dev, |
1404 | "had to try %d times to get EDID data\n", i); | | 1445 | "had to try %d times to get EDID data\n", i); |
1405 | if (i < 11) { | | 1446 | if (i < 11) { |
1406 | edid_parse(edid_data, &sc->sc_edid_info); | | 1447 | edid_parse(sc->sc_edid_data, &sc->sc_edid_info); |
1407 | edid_print(&sc->sc_edid_info); | | 1448 | edid_print(&sc->sc_edid_info); |
1408 | } | | 1449 | } |
1409 | } | | 1450 | } |
1410 | | | 1451 | |
1411 | /* I2C bitbanging */ | | 1452 | /* I2C bitbanging */ |
1412 | static void | | 1453 | static void |
1413 | crmfb_i2cbb_set_bits(void *cookie, uint32_t bits) | | 1454 | crmfb_i2cbb_set_bits(void *cookie, uint32_t bits) |
1414 | { | | 1455 | { |
1415 | struct crmfb_softc *sc = cookie; | | 1456 | struct crmfb_softc *sc = cookie; |
1416 | | | 1457 | |
1417 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, CRMFB_I2C_VGA, bits ^ 3); | | 1458 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, CRMFB_I2C_VGA, bits ^ 3); |
1418 | } | | 1459 | } |
1419 | | | 1460 | |
| @@ -1600,26 +1641,27 @@ crmfb_set_mode(struct crmfb_softc *sc, c | | | @@ -1600,26 +1641,27 @@ crmfb_set_mode(struct crmfb_softc *sc, c |
1600 | | | 1641 | |
1601 | d = (mode->htotal - 5) | ((mode->hdisplay - 5) << 12); | | 1642 | d = (mode->htotal - 5) | ((mode->hdisplay - 5) << 12); |
1602 | crmfb_write_reg(sc, CRMFB_VT_HBLANK, d); | | 1643 | crmfb_write_reg(sc, CRMFB_VT_HBLANK, d); |
1603 | | | 1644 | |
1604 | d = mode->vtotal | (mode->vdisplay << 12); | | 1645 | d = mode->vtotal | (mode->vdisplay << 12); |
1605 | crmfb_write_reg(sc, CRMFB_VT_VCMAP, d); | | 1646 | crmfb_write_reg(sc, CRMFB_VT_VCMAP, d); |
1606 | d = mode->htotal | (mode->hdisplay << 12); | | 1647 | d = mode->htotal | (mode->hdisplay << 12); |
1607 | crmfb_write_reg(sc, CRMFB_VT_HCMAP, d); | | 1648 | crmfb_write_reg(sc, CRMFB_VT_HCMAP, d); |
1608 | | | 1649 | |
1609 | d = 0; | | 1650 | d = 0; |
1610 | if (mode->flags & VID_NHSYNC) d |= CRMFB_VT_FLAGS_HDRV_INVERT; | | 1651 | if (mode->flags & VID_NHSYNC) d |= CRMFB_VT_FLAGS_HDRV_INVERT; |
1611 | if (mode->flags & VID_NVSYNC) d |= CRMFB_VT_FLAGS_VDRV_INVERT; | | 1652 | if (mode->flags & VID_NVSYNC) d |= CRMFB_VT_FLAGS_VDRV_INVERT; |
1612 | crmfb_write_reg(sc, CRMFB_VT_FLAGS, d); | | 1653 | crmfb_write_reg(sc, CRMFB_VT_FLAGS, d); |
| | | 1654 | sc->sc_vtflags = d; |
1613 | | | 1655 | |
1614 | diff = -abs(mode->vtotal - mode->vdisplay - 1); | | 1656 | diff = -abs(mode->vtotal - mode->vdisplay - 1); |
1615 | d = ((uint32_t)diff << 12) & 0x00fff000; | | 1657 | d = ((uint32_t)diff << 12) & 0x00fff000; |
1616 | d |= (mode->htotal - 20); | | 1658 | d |= (mode->htotal - 20); |
1617 | crmfb_write_reg(sc, CRMFB_VT_DID_STARTXY, d); | | 1659 | crmfb_write_reg(sc, CRMFB_VT_DID_STARTXY, d); |
1618 | | | 1660 | |
1619 | d = ((uint32_t)(diff + 1) << 12) & 0x00fff000; | | 1661 | d = ((uint32_t)(diff + 1) << 12) & 0x00fff000; |
1620 | d |= (mode->htotal - 54); | | 1662 | d |= (mode->htotal - 54); |
1621 | crmfb_write_reg(sc, CRMFB_VT_CRS_STARTXY, d); | | 1663 | crmfb_write_reg(sc, CRMFB_VT_CRS_STARTXY, d); |
1622 | | | 1664 | |
1623 | d = ((uint32_t)diff << 12) & 0x00fff000; | | 1665 | d = ((uint32_t)diff << 12) & 0x00fff000; |
1624 | d |= (mode->htotal - 4); | | 1666 | d |= (mode->htotal - 4); |
1625 | crmfb_write_reg(sc, CRMFB_VT_VC_STARTXY, d); | | 1667 | crmfb_write_reg(sc, CRMFB_VT_VC_STARTXY, d); |