Sat Dec 7 01:00:40 2019 UTC ()
clean up the video mode selection logic, switch modes only when actually
necessary
while there make some debug output optional


(macallan)
diff -r1.97 -r1.98 src/sys/dev/pci/machfb.c

cvs diff -r1.97 -r1.98 src/sys/dev/pci/machfb.c (expand / switch to unified diff)

--- src/sys/dev/pci/machfb.c 2019/02/05 06:12:39 1.97
+++ src/sys/dev/pci/machfb.c 2019/12/07 01:00:40 1.98
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $ */ 1/* $NetBSD: machfb.c,v 1.98 2019/12/07 01:00:40 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2002 Bang Jun-Young 4 * Copyright (c) 2002 Bang Jun-Young
5 * Copyright (c) 2005, 2006, 2007 Michael Lorenz 5 * Copyright (c) 2005, 2006, 2007 Michael Lorenz
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
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide. 32 * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, 36__KERNEL_RCSID(0,
37 "$NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $"); 37 "$NetBSD: machfb.c,v 1.98 2019/12/07 01:00:40 macallan Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kernel.h> 41#include <sys/kernel.h>
42#include <sys/device.h> 42#include <sys/device.h>
43#include <sys/malloc.h> 43#include <sys/malloc.h>
44#include <sys/callout.h> 44#include <sys/callout.h>
45#include <sys/lwp.h> 45#include <sys/lwp.h>
46#include <sys/kauth.h> 46#include <sys/kauth.h>
47 47
48#include <dev/videomode/videomode.h> 48#include <dev/videomode/videomode.h>
49#include <dev/videomode/edidvar.h> 49#include <dev/videomode/edidvar.h>
50 50
@@ -58,26 +58,32 @@ __KERNEL_RCSID(0, @@ -58,26 +58,32 @@ __KERNEL_RCSID(0,
58 58
59#include <dev/wscons/wsconsio.h> 59#include <dev/wscons/wsconsio.h>
60#include <dev/wsfont/wsfont.h> 60#include <dev/wsfont/wsfont.h>
61#include <dev/rasops/rasops.h> 61#include <dev/rasops/rasops.h>
62#include <dev/pci/wsdisplay_pci.h> 62#include <dev/pci/wsdisplay_pci.h>
63 63
64#include <dev/wscons/wsdisplay_vconsvar.h> 64#include <dev/wscons/wsdisplay_vconsvar.h>
65#include <dev/wscons/wsdisplay_glyphcachevar.h> 65#include <dev/wscons/wsdisplay_glyphcachevar.h>
66 66
67#include "opt_wsemul.h" 67#include "opt_wsemul.h"
68#include "opt_machfb.h" 68#include "opt_machfb.h"
69#include "opt_glyphcache.h" 69#include "opt_glyphcache.h"
70 70
 71#ifdef MACHFB_DEBUG
 72#define DPRINTF printf
 73#else
 74#define DPRINTF while (0) printf
 75#endif
 76
71#define MACH64_REG_SIZE 0x800 77#define MACH64_REG_SIZE 0x800
72#define MACH64_REG_OFF 0x7ff800 78#define MACH64_REG_OFF 0x7ff800
73 79
74#define NBARS 3 /* number of Mach64 PCI BARs */ 80#define NBARS 3 /* number of Mach64 PCI BARs */
75 81
76struct vga_bar { 82struct vga_bar {
77 bus_addr_t vb_base; 83 bus_addr_t vb_base;
78 bus_size_t vb_size; 84 bus_size_t vb_size;
79 pcireg_t vb_type; 85 pcireg_t vb_type;
80 int vb_flags; 86 int vb_flags;
81}; 87};
82 88
83struct mach64_softc { 89struct mach64_softc {
@@ -130,26 +136,27 @@ struct mach64_softc { @@ -130,26 +136,27 @@ struct mach64_softc {
130 int ref_div; 136 int ref_div;
131 int log2_vclk_post_div; 137 int log2_vclk_post_div;
132 int vclk_post_div; 138 int vclk_post_div;
133 int vclk_fb_div; 139 int vclk_fb_div;
134 int mclk_post_div; 140 int mclk_post_div;
135 int mclk_fb_div; 141 int mclk_fb_div;
136 int sc_clock; /* which clock to use */ 142 int sc_clock; /* which clock to use */
137 int minref, m; 143 int minref, m;
138 144
139 struct videomode *sc_my_mode; 145 struct videomode *sc_my_mode;
140 int sc_edid_size; 146 int sc_edid_size;
141 uint8_t sc_edid_data[1024]; 147 uint8_t sc_edid_data[1024];
142 struct edid_info sc_ei; 148 struct edid_info sc_ei;
 149 int sc_setmode;
143 150
144 u_char sc_cmap_red[256]; 151 u_char sc_cmap_red[256];
145 u_char sc_cmap_green[256]; 152 u_char sc_cmap_green[256];
146 u_char sc_cmap_blue[256]; 153 u_char sc_cmap_blue[256];
147 int sc_dacw, sc_blanked, sc_console; 154 int sc_dacw, sc_blanked, sc_console;
148 struct vcons_data vd; 155 struct vcons_data vd;
149 struct wsdisplay_accessops sc_accessops; 156 struct wsdisplay_accessops sc_accessops;
150 glyphcache sc_gc; 157 glyphcache sc_gc;
151}; 158};
152 159
153struct mach64_crtcregs { 160struct mach64_crtcregs {
154 uint32_t h_total_disp; 161 uint32_t h_total_disp;
155 uint32_t h_sync_strt_wid; 162 uint32_t h_sync_strt_wid;
@@ -211,27 +218,29 @@ static const char *mach64_memtype_names[ @@ -211,27 +218,29 @@ static const char *mach64_memtype_names[
211 218
212extern const u_char rasops_cmap[768]; 219extern const u_char rasops_cmap[768];
213 220
214static int mach64_match(device_t, cfdata_t, void *); 221static int mach64_match(device_t, cfdata_t, void *);
215static void mach64_attach(device_t, device_t, void *); 222static void mach64_attach(device_t, device_t, void *);
216 223
217CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match, 224CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match,
218 mach64_attach, NULL, NULL); 225 mach64_attach, NULL, NULL);
219 226
220static void mach64_init(struct mach64_softc *); 227static void mach64_init(struct mach64_softc *);
221static int mach64_get_memsize(struct mach64_softc *); 228static int mach64_get_memsize(struct mach64_softc *);
222static int mach64_get_max_ramdac(struct mach64_softc *); 229static int mach64_get_max_ramdac(struct mach64_softc *);
223 230
 231#if 0
224static void mach64_get_mode(struct mach64_softc *, struct videomode *); 232static void mach64_get_mode(struct mach64_softc *, struct videomode *);
 233#endif
225 234
226static int mach64_calc_crtcregs(struct mach64_softc *, 235static int mach64_calc_crtcregs(struct mach64_softc *,
227 struct mach64_crtcregs *, 236 struct mach64_crtcregs *,
228 struct videomode *); 237 struct videomode *);
229static void mach64_set_crtcregs(struct mach64_softc *, 238static void mach64_set_crtcregs(struct mach64_softc *,
230 struct mach64_crtcregs *); 239 struct mach64_crtcregs *);
231 240
232static int mach64_modeswitch(struct mach64_softc *, struct videomode *); 241static int mach64_modeswitch(struct mach64_softc *, struct videomode *);
233static void mach64_set_dsp(struct mach64_softc *); 242static void mach64_set_dsp(struct mach64_softc *);
234static void mach64_set_pll(struct mach64_softc *, int); 243static void mach64_set_pll(struct mach64_softc *, int);
235static void mach64_reset_engine(struct mach64_softc *); 244static void mach64_reset_engine(struct mach64_softc *);
236static void mach64_init_engine(struct mach64_softc *); 245static void mach64_init_engine(struct mach64_softc *);
237#if 0 246#if 0
@@ -398,44 +407,45 @@ mach64_match(device_t parent, cfdata_t m @@ -398,44 +407,45 @@ mach64_match(device_t parent, cfdata_t m
398static void 407static void
399mach64_attach(device_t parent, device_t self, void *aux) 408mach64_attach(device_t parent, device_t self, void *aux)
400{ 409{
401 struct mach64_softc *sc = device_private(self); 410 struct mach64_softc *sc = device_private(self);
402 struct pci_attach_args *pa = aux; 411 struct pci_attach_args *pa = aux;
403 struct rasops_info *ri; 412 struct rasops_info *ri;
404 prop_data_t edid_data; 413 prop_data_t edid_data;
405 const struct videomode *mode = NULL; 414 const struct videomode *mode = NULL;
406 int bar, id, expected_id; 415 int bar, id, expected_id;
407 int is_gx; 416 int is_gx;
408 const char **memtype_names; 417 const char **memtype_names;
409 struct wsemuldisplaydev_attach_args aa; 418 struct wsemuldisplaydev_attach_args aa;
410 long defattr; 419 long defattr;
411 int setmode = 0, width, height; 420 int width = 1024, height = 768;
412 pcireg_t screg; 421 pcireg_t screg;
413 uint32_t reg; 422 uint32_t reg;
414 const pcireg_t enables = PCI_COMMAND_MEM_ENABLE; 423 const pcireg_t enables = PCI_COMMAND_MEM_ENABLE;
415 int use_mmio = FALSE; 424 int use_mmio = FALSE;
416 425
417 sc->sc_dev = self; 426 sc->sc_dev = self;
418 sc->sc_pc = pa->pa_pc; 427 sc->sc_pc = pa->pa_pc;
419 sc->sc_pcitag = pa->pa_tag; 428 sc->sc_pcitag = pa->pa_tag;
420 sc->sc_dacw = -1; 429 sc->sc_dacw = -1;
421 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 430 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
422 sc->sc_nbus = pa->pa_bus; 431 sc->sc_nbus = pa->pa_bus;
423 sc->sc_ndev = pa->pa_device; 432 sc->sc_ndev = pa->pa_device;
424 sc->sc_nfunc = pa->pa_function; 433 sc->sc_nfunc = pa->pa_function;
425 sc->sc_locked = 0; 434 sc->sc_locked = 0;
426 sc->sc_iot = pa->pa_iot; 435 sc->sc_iot = pa->pa_iot;
427 sc->sc_accessops.ioctl = mach64_ioctl; 436 sc->sc_accessops.ioctl = mach64_ioctl;
428 sc->sc_accessops.mmap = mach64_mmap; 437 sc->sc_accessops.mmap = mach64_mmap;
 438 sc->sc_setmode = 0;
429 439
430 pci_aprint_devinfo(pa, "Graphics processor"); 440 pci_aprint_devinfo(pa, "Graphics processor");
431#ifdef MACHFB_DEBUG 441#ifdef MACHFB_DEBUG
432 printf(prop_dictionary_externalize(device_properties(self))); 442 printf(prop_dictionary_externalize(device_properties(self)));
433#endif 443#endif
434 444
435 /* enable memory access */ 445 /* enable memory access */
436 screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 446 screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
437 if ((screg & enables) != enables) { 447 if ((screg & enables) != enables) {
438 screg |= enables; 448 screg |= enables;
439 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 449 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
440 PCI_COMMAND_STATUS_REG, screg); 450 PCI_COMMAND_STATUS_REG, screg);
441 } 451 }
@@ -488,42 +498,44 @@ mach64_attach(device_t parent, device_t  @@ -488,42 +498,44 @@ mach64_attach(device_t parent, device_t
488 498
489 aprint_normal_dev(sc->sc_dev, 499 aprint_normal_dev(sc->sc_dev,
490 "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n", 500 "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
491 (u_int)(sc->sc_apersize / (1024 * 1024)), 501 (u_int)(sc->sc_apersize / (1024 * 1024)),
492 (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024), 502 (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024),
493 (u_int)sc->sc_regbase); 503 (u_int)sc->sc_regbase);
494 504
495 printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev), 505 printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev),
496 (int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base); 506 (int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base);
497 507
498 prop_dictionary_get_uint32(device_properties(self), "width", &width); 508 prop_dictionary_get_uint32(device_properties(self), "width", &width);
499 prop_dictionary_get_uint32(device_properties(self), "height", &height); 509 prop_dictionary_get_uint32(device_properties(self), "height", &height);
500 510
 511 default_mode.hdisplay = width;
 512 default_mode.vdisplay = height;
 513
501 memset(&sc->sc_ei, 0, sizeof(sc->sc_ei)); 514 memset(&sc->sc_ei, 0, sizeof(sc->sc_ei));
502 if ((edid_data = prop_dictionary_get(device_properties(self), "EDID")) 515 if ((edid_data = prop_dictionary_get(device_properties(self), "EDID"))
503 != NULL) { 516 != NULL) {
504 517
505 sc->sc_edid_size = uimin(1024, prop_data_size(edid_data)); 518 sc->sc_edid_size = uimin(1024, prop_data_size(edid_data));
506 memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data)); 519 memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data));
507 memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data), 520 memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data),
508 sc->sc_edid_size); 521 sc->sc_edid_size);
509 522
510 edid_parse(sc->sc_edid_data, &sc->sc_ei); 523 edid_parse(sc->sc_edid_data, &sc->sc_ei);
511 524
512#ifdef MACHFB_DEBUG 525#ifdef MACHFB_DEBUG
513 edid_print(&sc->sc_ei); 526 edid_print(&sc->sc_ei);
514#endif 527#endif
515 } 528 }
516 
517 is_gx = 0; 529 is_gx = 0;
518 switch(mach64_chip_id) { 530 switch(mach64_chip_id) {
519 case PCI_PRODUCT_ATI_MACH64_GX: 531 case PCI_PRODUCT_ATI_MACH64_GX:
520 case PCI_PRODUCT_ATI_MACH64_CX: 532 case PCI_PRODUCT_ATI_MACH64_CX:
521 is_gx = 1; 533 is_gx = 1;
522 /* FALLTHROUGH */ 534 /* FALLTHROUGH */
523 case PCI_PRODUCT_ATI_MACH64_CT: 535 case PCI_PRODUCT_ATI_MACH64_CT:
524 sc->has_dsp = 0; 536 sc->has_dsp = 0;
525 break; 537 break;
526 case PCI_PRODUCT_ATI_MACH64_VT: 538 case PCI_PRODUCT_ATI_MACH64_VT:
527 case PCI_PRODUCT_ATI_RAGE_II: 539 case PCI_PRODUCT_ATI_RAGE_II:
528 if((mach64_chip_rev & 0x07) == 0) { 540 if((mach64_chip_rev & 0x07) == 0) {
529 sc->has_dsp = 0; 541 sc->has_dsp = 0;
@@ -551,38 +563,38 @@ mach64_attach(device_t parent, device_t  @@ -551,38 +563,38 @@ mach64_attach(device_t parent, device_t
551 ((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) && 563 ((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) &&
552 (mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) { 564 (mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) {
553 aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n"); 565 aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n");
554 sc->ref_freq = 29498; 566 sc->ref_freq = 29498;
555 } else 567 } else
556 sc->ref_freq = 14318; 568 sc->ref_freq = 14318;
557 569
558 reg = regr(sc, CLOCK_CNTL); 570 reg = regr(sc, CLOCK_CNTL);
559 aprint_debug("CLOCK_CNTL: %08x\n", reg); 571 aprint_debug("CLOCK_CNTL: %08x\n", reg);
560 sc->sc_clock = reg & 3; 572 sc->sc_clock = reg & 3;
561 aprint_debug("using clock %d\n", sc->sc_clock); 573 aprint_debug("using clock %d\n", sc->sc_clock);
562 574
563 sc->ref_div = regrb_pll(sc, PLL_REF_DIV); 575 sc->ref_div = regrb_pll(sc, PLL_REF_DIV);
564 aprint_error("ref_div: %d\n", sc->ref_div); 576 DPRINTF("ref_div: %d\n", sc->ref_div);
565 sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV); 577 sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV);
566 aprint_error("mclk_fb_div: %d\n", sc->mclk_fb_div); 578 DPRINTF("mclk_fb_div: %d\n", sc->mclk_fb_div);
567 sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) / 579 sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
568 (sc->ref_div * 2); 580 (sc->ref_div * 2);
569 sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) / 581 sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
570 (sc->mem_freq * sc->ref_div); 582 (sc->mem_freq * sc->ref_div);
571 sc->ramdac_freq = mach64_get_max_ramdac(sc); 583 sc->ramdac_freq = mach64_get_max_ramdac(sc);
572 { 584 {
573 sc->minref = sc->ramdac_freq / 510; 585 sc->minref = sc->ramdac_freq / 510;
574 sc->m = sc->ref_freq / sc->minref; 586 sc->m = sc->ref_freq / sc->minref;
575 aprint_error("minref: %d m: %d\n", sc->minref, sc->m); 587 DPRINTF("minref: %d m: %d\n", sc->minref, sc->m);
576 } 588 }
577 aprint_normal_dev(sc->sc_dev, 589 aprint_normal_dev(sc->sc_dev,
578 "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n", 590 "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
579 (u_long)sc->memsize, 591 (u_long)sc->memsize,
580 memtype_names[sc->memtype], 592 memtype_names[sc->memtype],
581 sc->mem_freq / 1000, sc->mem_freq % 1000, 593 sc->mem_freq / 1000, sc->mem_freq % 1000,
582 sc->ramdac_freq / 1000); 594 sc->ramdac_freq / 1000);
583 595
584 id = regr(sc, CONFIG_CHIP_ID) & 0xffff; 596 id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
585 switch(mach64_chip_id) { 597 switch(mach64_chip_id) {
586 case PCI_PRODUCT_ATI_MACH64_GX: 598 case PCI_PRODUCT_ATI_MACH64_GX:
587 expected_id = 0x00d7; 599 expected_id = 0x00d7;
588 break; 600 break;
@@ -594,102 +606,109 @@ mach64_attach(device_t parent, device_t  @@ -594,102 +606,109 @@ mach64_attach(device_t parent, device_t
594 expected_id = mach64_chip_id; 606 expected_id = mach64_chip_id;
595 } 607 }
596 608
597 if (id != expected_id) { 609 if (id != expected_id) {
598 aprint_error_dev(sc->sc_dev, 610 aprint_error_dev(sc->sc_dev,
599 "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id); 611 "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id);
600 return; 612 return;
601 } 613 }
602 614
603 sc->sc_console = mach64_is_console(sc); 615 sc->sc_console = mach64_is_console(sc);
604 aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL)); 616 aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL));
605 617
606#define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \ 618#define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \
607 ((m)->hdisplay <= 11280)) 619 ((m)->hdisplay <= 1280))
608 620
609 /* no mode setting support on ancient chips with external clocks */ 621 /* no mode setting support on ancient chips with external clocks */
610 setmode = 0; 622 sc->sc_setmode = 0;
611 if (!is_gx) { 623 if (!is_gx) {
612 /* 624 /*
613 * Now pick a mode. 625 * Now pick a mode.
614 */ 626 */
615 if ((sc->sc_ei.edid_preferred_mode != NULL)) { 627 if ((sc->sc_ei.edid_preferred_mode != NULL)) {
616 struct videomode *m = sc->sc_ei.edid_preferred_mode; 628 struct videomode *m = sc->sc_ei.edid_preferred_mode;
617 if (MODE_IS_VALID(m)) { 629 if (MODE_IS_VALID(m)) {
618 memcpy(&default_mode, m, 630 memcpy(&default_mode, m,
619 sizeof(struct videomode)); 631 sizeof(struct videomode));
620 setmode = 1; 632 sc->sc_setmode = 1;
621 } else { 633 } else {
622 aprint_error_dev(sc->sc_dev, 634 aprint_error_dev(sc->sc_dev,
623 "unable to use preferred mode\n"); 635 "unable to use preferred mode\n");
624 } 636 }
625 } 637 }
626 /* 638 /*
627 * if we can't use the preferred mode go look for the 639 * if we can't use the preferred mode go look for the
628 * best one we can support 640 * best one we can support
629 */ 641 */
630 if (setmode == 0) { 642 if (sc->sc_setmode == 0) {
631 struct videomode *m = sc->sc_ei.edid_modes; 643 struct videomode *m = sc->sc_ei.edid_modes;
632 644
633 mode = NULL; 645 mode = NULL;
634 sort_modes(sc->sc_ei.edid_modes, 646 sort_modes(sc->sc_ei.edid_modes,
635 &sc->sc_ei.edid_preferred_mode, 647 &sc->sc_ei.edid_preferred_mode,
636 sc->sc_ei.edid_nmodes); 648 sc->sc_ei.edid_nmodes);
637 for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) 649 for (int n = 0; n < sc->sc_ei.edid_nmodes; n++)
638 if (MODE_IS_VALID(&m[n])) { 650 if (MODE_IS_VALID(&m[n])) {
639 mode = &m[n]; 651 mode = &m[n];
640 break; 652 break;
641 } 653 }
642 if (mode != NULL) { 654 if (mode != NULL) {
643 memcpy(&default_mode, mode, 655 memcpy(&default_mode, mode,
644 sizeof(struct videomode)); 656 sizeof(struct videomode));
645 setmode = 1; 657 sc->sc_setmode = 1;
646 } 658 }
647 } 659 }
648 /* got nothing? try to pick one based on firmware parameters */ 660 }
649 if (setmode == 0 && width > 0 && height > 0) { 661
650 /* no EDID data? */ 662 /* make sure my_mode points at something sensible if the above fails */
651 mode = pick_mode_by_ref(width, height, 60); 663 if (default_mode.dot_clock == 0) {
652 memcpy(&default_mode, mode, sizeof(struct videomode)); 664 sc->sc_setmode = 0;
653 setmode = 1; 665 mode = pick_mode_by_ref(width, height, 60);
654 } 666 if (mode != NULL) {
655 /* still nothing? Grab the default */ 667 memcpy(&default_mode, mode, sizeof(default_mode));
656 if (setmode == 0) { 668 } else if ((width > 0) && (height > 0)) {
 669 default_mode.hdisplay = width;
 670 default_mode.vdisplay = height;
 671 } else {
 672 /*
 673 * if we end up here we're probably dealing with
 674 * uninitialized hardware - try to set 1024x768@60 and
 675 * hope for the best...
 676 */
657 mode = pick_mode_by_ref(1024, 768, 60); 677 mode = pick_mode_by_ref(1024, 768, 60);
658 memcpy(&default_mode, mode, sizeof(struct videomode)); 678 if (mode == NULL) return;
659 setmode = 1; 679 memcpy(&default_mode, mode, sizeof(default_mode));
660 } 680 if (!is_gx) sc->sc_setmode = 1;
661 } else { 681 }
662 /* make sure my_mode points at something sensible */ 
663 mach64_get_mode(sc, &default_mode); 
664 if (default_mode.dot_clock == 0) { 
665 memcpy(&default_mode, pick_mode_by_ref(width, height, 60),  
666 sizeof(default_mode)); 
667 } 
668 } 682 }
 683
669 sc->sc_my_mode = &default_mode; 684 sc->sc_my_mode = &default_mode;
670 685
 686 if ((width == sc->sc_my_mode->hdisplay) &&
 687 (height == sc->sc_my_mode->vdisplay))
 688 sc->sc_setmode = 0;
 689
671 sc->bits_per_pixel = 8; 690 sc->bits_per_pixel = 8;
672 sc->virt_x = sc->sc_my_mode->hdisplay; 691 sc->virt_x = sc->sc_my_mode->hdisplay;
673 sc->virt_y = sc->sc_my_mode->vdisplay; 692 sc->virt_y = sc->sc_my_mode->vdisplay;
674 sc->max_x = sc->virt_x - 1; 693 sc->max_x = sc->virt_x - 1;
675 sc->max_y = (sc->memsize * 1024) / 694 sc->max_y = (sc->memsize * 1024) /
676 (sc->virt_x * (sc->bits_per_pixel / 8)) - 1; 695 (sc->virt_x * (sc->bits_per_pixel / 8)) - 1;
677 696
678 sc->color_depth = CRTC_PIX_WIDTH_8BPP; 697 sc->color_depth = CRTC_PIX_WIDTH_8BPP;
679 698
680 mach64_init_engine(sc); 699 mach64_init_engine(sc);
681 700
682 if (setmode) 701 if (sc->sc_setmode)
683 mach64_modeswitch(sc, sc->sc_my_mode); 702 mach64_modeswitch(sc, sc->sc_my_mode);
684 703
685 aprint_normal_dev(sc->sc_dev, 704 aprint_normal_dev(sc->sc_dev,
686 "initial resolution %dx%d at %d bpp\n", 705 "initial resolution %dx%d at %d bpp\n",
687 sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay, 706 sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay,
688 sc->bits_per_pixel); 707 sc->bits_per_pixel);
689 708
690 wsfont_init(); 709 wsfont_init();
691 710
692#ifdef GLYPHCACHE_DEBUG 711#ifdef GLYPHCACHE_DEBUG
693 /* shrink the screen so we can see part of the glyph cache */ 712 /* shrink the screen so we can see part of the glyph cache */
694 sc->sc_my_mode->vdisplay -= 200; 713 sc->sc_my_mode->vdisplay -= 200;
695#endif 714#endif
@@ -717,27 +736,26 @@ mach64_attach(device_t parent, device_t  @@ -717,27 +736,26 @@ mach64_attach(device_t parent, device_t
717 glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, 736 glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5,
718 ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - 737 ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) -
719 sc->sc_my_mode->vdisplay - 5, 738 sc->sc_my_mode->vdisplay - 5,
720 sc->sc_my_mode->hdisplay, 739 sc->sc_my_mode->hdisplay,
721 ri->ri_font->fontwidth, 740 ri->ri_font->fontwidth,
722 ri->ri_font->fontheight, 741 ri->ri_font->fontheight,
723 defattr); 742 defattr);
724 wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr); 743 wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr);
725 } else { 744 } else {
726 /* 745 /*
727 * since we're not the console we can postpone the rest 746 * since we're not the console we can postpone the rest
728 * until someone actually allocates a screen for us 747 * until someone actually allocates a screen for us
729 */ 748 */
730 mach64_modeswitch(sc, sc->sc_my_mode); 
731 if (mach64_console_screen.scr_ri.ri_rows == 0) { 749 if (mach64_console_screen.scr_ri.ri_rows == 0) {
732 /* do some minimal setup to avoid weirdnesses later */ 750 /* do some minimal setup to avoid weirdnesses later */
733 vcons_init_screen(&sc->vd, &mach64_console_screen, 1, 751 vcons_init_screen(&sc->vd, &mach64_console_screen, 1,
734 &defattr); 752 &defattr);
735 } else 753 } else
736 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); 754 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
737 755
738 glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, 756 glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5,
739 ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - 757 ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) -
740 sc->sc_my_mode->vdisplay - 5, 758 sc->sc_my_mode->vdisplay - 5,
741 sc->sc_my_mode->hdisplay, 759 sc->sc_my_mode->hdisplay,
742 ri->ri_font->fontwidth, 760 ri->ri_font->fontwidth,
743 ri->ri_font->fontheight, 761 ri->ri_font->fontheight,
@@ -872,52 +890,54 @@ mach64_get_max_ramdac(struct mach64_soft @@ -872,52 +890,54 @@ mach64_get_max_ramdac(struct mach64_soft
872 (mach64_chip_rev & 0x07)) 890 (mach64_chip_rev & 0x07))
873 return 170000; 891 return 170000;
874 892
875 for (i = 0; i < __arraycount(mach64_info); i++) 893 for (i = 0; i < __arraycount(mach64_info); i++)
876 if (mach64_chip_id == mach64_info[i].chip_id) 894 if (mach64_chip_id == mach64_info[i].chip_id)
877 return mach64_info[i].ramdac_freq; 895 return mach64_info[i].ramdac_freq;
878 896
879 if (sc->bits_per_pixel == 8) 897 if (sc->bits_per_pixel == 8)
880 return 135000; 898 return 135000;
881 else 899 else
882 return 80000; 900 return 80000;
883} 901}
884 902
 903#if 0
885static void 904static void
886mach64_get_mode(struct mach64_softc *sc, struct videomode *mode) 905mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
887{ 906{
888 struct mach64_crtcregs crtc; 907 struct mach64_crtcregs crtc;
889 908
890 crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP); 909 crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP);
891 crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID); 910 crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID);
892 crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP); 911 crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP);
893 crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID); 912 crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID);
894 913
895 mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3; 914 mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3;
896 mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3; 915 mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3;
897 mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3; 916 mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3;
898 mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) + 917 mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) +
899 mode->hsync_start; 918 mode->hsync_start;
900 mode->vtotal = (crtc.v_total_disp & 0xffff) + 1; 919 mode->vtotal = (crtc.v_total_disp & 0xffff) + 1;
901 mode->vdisplay = (crtc.v_total_disp >> 16) + 1; 920 mode->vdisplay = (crtc.v_total_disp >> 16) + 1;
902 mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1; 921 mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1;
903 mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start; 922 mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start;
904 923
905#ifdef MACHFB_DEBUG 924#ifdef MACHFB_DEBUG
906 printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n", 925 printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n",
907 mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, 926 mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
908 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal); 927 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
909#endif 928#endif
910} 929}
 930#endif
911 931
912static int 932static int
913mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc, 933mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc,
914 struct videomode *mode) 934 struct videomode *mode)
915{ 935{
916 936
917 if (mode->dot_clock > sc->ramdac_freq) 937 if (mode->dot_clock > sc->ramdac_freq)
918 /* Clock too high. */ 938 /* Clock too high. */
919 return 1; 939 return 1;
920 940
921 crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) | 941 crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) |
922 ((mode->htotal >> 3) - 1); 942 ((mode->htotal >> 3) - 1);
923 crtc->h_sync_strt_wid = 943 crtc->h_sync_strt_wid =
@@ -1137,27 +1157,30 @@ mach64_set_dsp(struct mach64_softc *sc) @@ -1137,27 +1157,30 @@ mach64_set_dsp(struct mach64_softc *sc)
1137 fifo_depth = 24; 1157 fifo_depth = 24;
1138 } else { 1158 } else {
1139 dsp_loop_latency = 2; 1159 dsp_loop_latency = 2;
1140 fifo_depth = 32; 1160 fifo_depth = 32;
1141 } 1161 }
1142 1162
1143 dsp_precision = 0; 1163 dsp_precision = 0;
1144 1164
1145 xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) / 1165 xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) /
1146 (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel); 1166 (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel);
1147 1167
1148 xclks_per_qw_m = (sc->mem_freq * 64 << 4) / 1168 xclks_per_qw_m = (sc->mem_freq * 64 << 4) /
1149 (sc->vclk_freq * sc->bits_per_pixel); 1169 (sc->vclk_freq * sc->bits_per_pixel);
1150 printf("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m); 1170
 1171 DPRINTF("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m);
 1172 DPRINTF("mem %dkHz v %dkHz\n", sc->mem_freq, sc->vclk_freq);
 1173
1151 y = (xclks_per_qw * fifo_depth) >> 11; 1174 y = (xclks_per_qw * fifo_depth) >> 11;
1152  1175
1153 while (y) { 1176 while (y) {
1154 y >>= 1; 1177 y >>= 1;
1155 dsp_precision++; 1178 dsp_precision++;
1156 } 1179 }
1157 dsp_precision -= 5; 1180 dsp_precision -= 5;
1158 fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6); 1181 fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6);
1159 1182
1160 switch (sc->memtype) { 1183 switch (sc->memtype) {
1161 case DRAM: 1184 case DRAM:
1162 case EDO_DRAM: 1185 case EDO_DRAM:
1163 case PSEUDO_EDO: 1186 case PSEUDO_EDO:
@@ -1199,31 +1222,34 @@ mach64_set_dsp(struct mach64_softc *sc) @@ -1199,31 +1222,34 @@ mach64_set_dsp(struct mach64_softc *sc)
1199 dsp_xclks_per_qw = xclks_per_qw >> dsp_precision; 1222 dsp_xclks_per_qw = xclks_per_qw >> dsp_precision;
1200 dsp_on = fifo_on >> dsp_precision; 1223 dsp_on = fifo_on >> dsp_precision;
1201 dsp_off = fifo_off >> dsp_precision; 1224 dsp_off = fifo_off >> dsp_precision;
1202 1225
1203#ifdef MACHFB_DEBUG 1226#ifdef MACHFB_DEBUG
1204 printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n" 1227 printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
1205 "dsp_precision = %d, dsp_loop_latency = %d,\n" 1228 "dsp_precision = %d, dsp_loop_latency = %d,\n"
1206 "mclk_fb_div = %d, vclk_fb_div = %d,\n" 1229 "mclk_fb_div = %d, vclk_fb_div = %d,\n"
1207 "mclk_post_div = %d, vclk_post_div = %d\n", 1230 "mclk_post_div = %d, vclk_post_div = %d\n",
1208 dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency, 1231 dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency,
1209 sc->mclk_fb_div, sc->vclk_fb_div, 1232 sc->mclk_fb_div, sc->vclk_fb_div,
1210 sc->mclk_post_div, sc->vclk_post_div); 1233 sc->mclk_post_div, sc->vclk_post_div);
1211#endif 1234#endif
1212 1235 DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF));
 1236 DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG));
1213 regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF)); 1237 regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF));
1214 regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) | 1238 regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) |
1215 ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) | 1239 ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) |
1216 (dsp_xclks_per_qw & DSP_XCLKS_PER_QW)); 1240 (dsp_xclks_per_qw & DSP_XCLKS_PER_QW));
 1241 DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF));
 1242 DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG));
1217} 1243}
1218 1244
1219static void 1245static void
1220mach64_set_pll(struct mach64_softc *sc, int clock) 1246mach64_set_pll(struct mach64_softc *sc, int clock)
1221{ 1247{
1222 uint32_t q, clockreg; 1248 uint32_t q, clockreg;
1223 int clockshift = sc->sc_clock << 1; 1249 int clockshift = sc->sc_clock << 1;
1224 uint8_t reg, vclk_ctl; 1250 uint8_t reg, vclk_ctl;
1225 1251
1226 q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq); 1252 q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
1227#ifdef MACHFB_DEBUG 1253#ifdef MACHFB_DEBUG
1228 printf("q = %d\n", q); 1254 printf("q = %d\n", q);
1229#endif 1255#endif
@@ -1240,35 +1266,35 @@ mach64_set_pll(struct mach64_softc *sc,  @@ -1240,35 +1266,35 @@ mach64_set_pll(struct mach64_softc *sc,
1240 sc->log2_vclk_post_div = 1; 1266 sc->log2_vclk_post_div = 1;
1241 } else if (q > 3150) { 1267 } else if (q > 3150) {
1242 sc->vclk_post_div = 4; 1268 sc->vclk_post_div = 4;
1243 sc->log2_vclk_post_div = 2; 1269 sc->log2_vclk_post_div = 2;
1244 } else if (q >= 1600) { 1270 } else if (q >= 1600) {
1245 sc->vclk_post_div = 8; 1271 sc->vclk_post_div = 8;
1246 sc->log2_vclk_post_div = 3; 1272 sc->log2_vclk_post_div = 3;
1247 } else { 1273 } else {
1248 aprint_error_dev(sc->sc_dev, "Warning: q < 1600\n"); 1274 aprint_error_dev(sc->sc_dev, "Warning: q < 1600\n");
1249 sc->vclk_post_div = 8; 1275 sc->vclk_post_div = 8;
1250 sc->log2_vclk_post_div = 3; 1276 sc->log2_vclk_post_div = 3;
1251 } 1277 }
1252 sc->vclk_fb_div = q * sc->vclk_post_div / 100; 1278 sc->vclk_fb_div = q * sc->vclk_post_div / 100;
1253 aprint_error("post_div: %d log2_post_div: %d mclk_div: %d\n", 1279 DPRINTF("post_div: %d log2_post_div: %d mclk_div: %d\n",
1254 sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div); 1280 sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div);
1255 1281
1256 vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL); 1282 vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL);
1257 aprint_debug("vclk_ctl: %02x\n", vclk_ctl); 1283 aprint_debug("vclk_ctl: %02x\n", vclk_ctl);
1258 vclk_ctl |= PLL_VCLK_RESET; 1284 vclk_ctl |= PLL_VCLK_RESET;
1259 regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); 1285 regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
1260 1286
1261 aprint_error("target: %d output: %d\n", clock,  1287 DPRINTF("target: %d output: %d\n", clock,
1262 (2 * sc->ref_freq * sc->vclk_fb_div) /  1288 (2 * sc->ref_freq * sc->vclk_fb_div) /
1263 (sc->ref_div * sc->vclk_post_div)); 1289 (sc->ref_div * sc->vclk_post_div));
1264  1290
1265 regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div); 1291 regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
1266 reg = regrb_pll(sc, VCLK_POST_DIV); 1292 reg = regrb_pll(sc, VCLK_POST_DIV);
1267 reg &= ~(3 << clockshift); 1293 reg &= ~(3 << clockshift);
1268 reg |= (sc->log2_vclk_post_div << clockshift); 1294 reg |= (sc->log2_vclk_post_div << clockshift);
1269 regwb_pll(sc, VCLK_POST_DIV, reg); 1295 regwb_pll(sc, VCLK_POST_DIV, reg);
1270 regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div); 1296 regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div);
1271 1297
1272 vclk_ctl &= ~PLL_VCLK_RESET; 1298 vclk_ctl &= ~PLL_VCLK_RESET;
1273 regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); 1299 regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
1274 1300
@@ -1841,27 +1867,28 @@ mach64_ioctl(void *v, void *vs, u_long c @@ -1841,27 +1867,28 @@ mach64_ioctl(void *v, void *vs, u_long c
1841 sc->sc_pcitag, data); 1867 sc->sc_pcitag, data);
1842 1868
1843 case WSDISPLAYIO_SMODE: { 1869 case WSDISPLAYIO_SMODE: {
1844 int new_mode = *(int*)data; 1870 int new_mode = *(int*)data;
1845 if (new_mode != sc->sc_mode) { 1871 if (new_mode != sc->sc_mode) {
1846 sc->sc_mode = new_mode; 1872 sc->sc_mode = new_mode;
1847 if ((new_mode == WSDISPLAYIO_MODE_EMUL) 1873 if ((new_mode == WSDISPLAYIO_MODE_EMUL)
1848 && (ms != NULL)) 1874 && (ms != NULL))
1849 { 1875 {
1850 /* restore initial video mode */ 1876 /* restore initial video mode */
1851 mach64_init(sc); 1877 mach64_init(sc);
1852 mach64_init_engine(sc); 1878 mach64_init_engine(sc);
1853 mach64_init_lut(sc); 1879 mach64_init_lut(sc);
1854 mach64_modeswitch(sc, sc->sc_my_mode); 1880 if (sc->sc_setmode)
 1881 mach64_modeswitch(sc, sc->sc_my_mode);
1855 mach64_clearscreen(sc); 1882 mach64_clearscreen(sc);
1856 glyphcache_wipe(&sc->sc_gc); 1883 glyphcache_wipe(&sc->sc_gc);
1857 vcons_redraw_screen(ms); 1884 vcons_redraw_screen(ms);
1858 } 1885 }
1859 } 1886 }
1860 } 1887 }
1861 return 0; 1888 return 0;
1862 case WSDISPLAYIO_GET_EDID: { 1889 case WSDISPLAYIO_GET_EDID: {
1863 struct wsdisplayio_edid_info *d = data; 1890 struct wsdisplayio_edid_info *d = data;
1864 return wsdisplayio_get_edid(sc->sc_dev, d); 1891 return wsdisplayio_get_edid(sc->sc_dev, d);
1865 } 1892 }
1866 1893
1867 case WSDISPLAYIO_GET_FBINFO: { 1894 case WSDISPLAYIO_GET_FBINFO: {