Tue Sep 2 15:44:44 2014 UTC ()
support ioctl() WSDISPLAYIO_SVIDEO, _GVIDEO and _GET_EDID
now xf86-video-crime can actually turn the monitor off


(macallan)
diff -r1.37 -r1.38 src/sys/arch/sgimips/dev/crmfb.c

cvs diff -r1.37 -r1.38 src/sys/arch/sgimips/dev/crmfb.c (expand / switch to unified diff)

--- src/sys/arch/sgimips/dev/crmfb.c 2013/12/16 15:45:29 1.37
+++ src/sys/arch/sgimips/dev/crmfb.c 2014/09/02 15:44:44 1.38
@@ -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
172static int crmfb_putcmap(struct crmfb_softc *, struct wsdisplay_cmap *); 175static 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
418crmfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) 426crmfb_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
518static paddr_t 555static paddr_t
519crmfb_mmap(void *v, void *vs, off_t offset, int prot) 556crmfb_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
813static int 853static int
814crmfb_setup_video(struct crmfb_softc *sc, int depth) 854crmfb_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
1119static void 1159static void
1120crmfb_bitblt(struct crmfb_softc *sc, int xs, int ys, int xd, int yd, 1160crmfb_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
1383static void 1425static void
1384crmfb_setup_ddc(struct crmfb_softc *sc) 1426crmfb_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 */
1412static void 1453static void
1413crmfb_i2cbb_set_bits(void *cookie, uint32_t bits) 1454crmfb_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);