Module Name: src Committed By: macallan Date: Sat Dec 7 01:00:40 UTC 2019
Modified Files: src/sys/dev/pci: machfb.c Log Message: clean up the video mode selection logic, switch modes only when actually necessary while there make some debug output optional To generate a diff of this commit: cvs rdiff -u -r1.97 -r1.98 src/sys/dev/pci/machfb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/machfb.c diff -u src/sys/dev/pci/machfb.c:1.97 src/sys/dev/pci/machfb.c:1.98 --- src/sys/dev/pci/machfb.c:1.97 Tue Feb 5 06:12:39 2019 +++ src/sys/dev/pci/machfb.c Sat Dec 7 01:00:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $ */ +/* $NetBSD: machfb.c,v 1.98 2019/12/07 01:00:40 macallan Exp $ */ /* * Copyright (c) 2002 Bang Jun-Young @@ -34,7 +34,7 @@ #include <sys/cdefs.h> __KERNEL_RCSID(0, - "$NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $"); + "$NetBSD: machfb.c,v 1.98 2019/12/07 01:00:40 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,6 +68,12 @@ __KERNEL_RCSID(0, #include "opt_machfb.h" #include "opt_glyphcache.h" +#ifdef MACHFB_DEBUG +#define DPRINTF printf +#else +#define DPRINTF while (0) printf +#endif + #define MACH64_REG_SIZE 0x800 #define MACH64_REG_OFF 0x7ff800 @@ -140,6 +146,7 @@ struct mach64_softc { int sc_edid_size; uint8_t sc_edid_data[1024]; struct edid_info sc_ei; + int sc_setmode; u_char sc_cmap_red[256]; u_char sc_cmap_green[256]; @@ -221,7 +228,9 @@ static void mach64_init(struct mach64_so static int mach64_get_memsize(struct mach64_softc *); static int mach64_get_max_ramdac(struct mach64_softc *); +#if 0 static void mach64_get_mode(struct mach64_softc *, struct videomode *); +#endif static int mach64_calc_crtcregs(struct mach64_softc *, struct mach64_crtcregs *, @@ -408,7 +417,7 @@ mach64_attach(device_t parent, device_t const char **memtype_names; struct wsemuldisplaydev_attach_args aa; long defattr; - int setmode = 0, width, height; + int width = 1024, height = 768; pcireg_t screg; uint32_t reg; const pcireg_t enables = PCI_COMMAND_MEM_ENABLE; @@ -426,6 +435,7 @@ mach64_attach(device_t parent, device_t sc->sc_iot = pa->pa_iot; sc->sc_accessops.ioctl = mach64_ioctl; sc->sc_accessops.mmap = mach64_mmap; + sc->sc_setmode = 0; pci_aprint_devinfo(pa, "Graphics processor"); #ifdef MACHFB_DEBUG @@ -498,6 +508,9 @@ mach64_attach(device_t parent, device_t prop_dictionary_get_uint32(device_properties(self), "width", &width); prop_dictionary_get_uint32(device_properties(self), "height", &height); + default_mode.hdisplay = width; + default_mode.vdisplay = height; + memset(&sc->sc_ei, 0, sizeof(sc->sc_ei)); if ((edid_data = prop_dictionary_get(device_properties(self), "EDID")) != NULL) { @@ -513,7 +526,6 @@ mach64_attach(device_t parent, device_t edid_print(&sc->sc_ei); #endif } - is_gx = 0; switch(mach64_chip_id) { case PCI_PRODUCT_ATI_MACH64_GX: @@ -561,9 +573,9 @@ mach64_attach(device_t parent, device_t aprint_debug("using clock %d\n", sc->sc_clock); sc->ref_div = regrb_pll(sc, PLL_REF_DIV); - aprint_error("ref_div: %d\n", sc->ref_div); + DPRINTF("ref_div: %d\n", sc->ref_div); sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV); - aprint_error("mclk_fb_div: %d\n", sc->mclk_fb_div); + DPRINTF("mclk_fb_div: %d\n", sc->mclk_fb_div); sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) / (sc->ref_div * 2); sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) / @@ -572,7 +584,7 @@ mach64_attach(device_t parent, device_t { sc->minref = sc->ramdac_freq / 510; sc->m = sc->ref_freq / sc->minref; - aprint_error("minref: %d m: %d\n", sc->minref, sc->m); + DPRINTF("minref: %d m: %d\n", sc->minref, sc->m); } aprint_normal_dev(sc->sc_dev, "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n", @@ -604,10 +616,10 @@ mach64_attach(device_t parent, device_t aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL)); #define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \ - ((m)->hdisplay <= 11280)) + ((m)->hdisplay <= 1280)) /* no mode setting support on ancient chips with external clocks */ - setmode = 0; + sc->sc_setmode = 0; if (!is_gx) { /* * Now pick a mode. @@ -617,7 +629,7 @@ mach64_attach(device_t parent, device_t if (MODE_IS_VALID(m)) { memcpy(&default_mode, m, sizeof(struct videomode)); - setmode = 1; + sc->sc_setmode = 1; } else { aprint_error_dev(sc->sc_dev, "unable to use preferred mode\n"); @@ -627,7 +639,7 @@ mach64_attach(device_t parent, device_t * if we can't use the preferred mode go look for the * best one we can support */ - if (setmode == 0) { + if (sc->sc_setmode == 0) { struct videomode *m = sc->sc_ei.edid_modes; mode = NULL; @@ -642,32 +654,39 @@ mach64_attach(device_t parent, device_t if (mode != NULL) { memcpy(&default_mode, mode, sizeof(struct videomode)); - setmode = 1; + sc->sc_setmode = 1; } } - /* got nothing? try to pick one based on firmware parameters */ - if (setmode == 0 && width > 0 && height > 0) { - /* no EDID data? */ - mode = pick_mode_by_ref(width, height, 60); - memcpy(&default_mode, mode, sizeof(struct videomode)); - setmode = 1; - } - /* still nothing? Grab the default */ - if (setmode == 0) { + } + + /* make sure my_mode points at something sensible if the above fails */ + if (default_mode.dot_clock == 0) { + sc->sc_setmode = 0; + mode = pick_mode_by_ref(width, height, 60); + if (mode != NULL) { + memcpy(&default_mode, mode, sizeof(default_mode)); + } else if ((width > 0) && (height > 0)) { + default_mode.hdisplay = width; + default_mode.vdisplay = height; + } else { + /* + * if we end up here we're probably dealing with + * uninitialized hardware - try to set 1024x768@60 and + * hope for the best... + */ mode = pick_mode_by_ref(1024, 768, 60); - memcpy(&default_mode, mode, sizeof(struct videomode)); - setmode = 1; - } - } else { - /* make sure my_mode points at something sensible */ - mach64_get_mode(sc, &default_mode); - if (default_mode.dot_clock == 0) { - memcpy(&default_mode, pick_mode_by_ref(width, height, 60), - sizeof(default_mode)); - } + if (mode == NULL) return; + memcpy(&default_mode, mode, sizeof(default_mode)); + if (!is_gx) sc->sc_setmode = 1; + } } + sc->sc_my_mode = &default_mode; + if ((width == sc->sc_my_mode->hdisplay) && + (height == sc->sc_my_mode->vdisplay)) + sc->sc_setmode = 0; + sc->bits_per_pixel = 8; sc->virt_x = sc->sc_my_mode->hdisplay; sc->virt_y = sc->sc_my_mode->vdisplay; @@ -679,7 +698,7 @@ mach64_attach(device_t parent, device_t mach64_init_engine(sc); - if (setmode) + if (sc->sc_setmode) mach64_modeswitch(sc, sc->sc_my_mode); aprint_normal_dev(sc->sc_dev, @@ -727,7 +746,6 @@ mach64_attach(device_t parent, device_t * since we're not the console we can postpone the rest * until someone actually allocates a screen for us */ - mach64_modeswitch(sc, sc->sc_my_mode); if (mach64_console_screen.scr_ri.ri_rows == 0) { /* do some minimal setup to avoid weirdnesses later */ vcons_init_screen(&sc->vd, &mach64_console_screen, 1, @@ -882,6 +900,7 @@ mach64_get_max_ramdac(struct mach64_soft return 80000; } +#if 0 static void mach64_get_mode(struct mach64_softc *sc, struct videomode *mode) { @@ -908,6 +927,7 @@ mach64_get_mode(struct mach64_softc *sc, mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal); #endif } +#endif static int mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc, @@ -1147,7 +1167,10 @@ mach64_set_dsp(struct mach64_softc *sc) xclks_per_qw_m = (sc->mem_freq * 64 << 4) / (sc->vclk_freq * sc->bits_per_pixel); - printf("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m); + + DPRINTF("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m); + DPRINTF("mem %dkHz v %dkHz\n", sc->mem_freq, sc->vclk_freq); + y = (xclks_per_qw * fifo_depth) >> 11; while (y) { @@ -1209,11 +1232,14 @@ mach64_set_dsp(struct mach64_softc *sc) sc->mclk_fb_div, sc->vclk_fb_div, sc->mclk_post_div, sc->vclk_post_div); #endif - + DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF)); + DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG)); regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF)); regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) | ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) | (dsp_xclks_per_qw & DSP_XCLKS_PER_QW)); + DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF)); + DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG)); } static void @@ -1250,7 +1276,7 @@ mach64_set_pll(struct mach64_softc *sc, sc->log2_vclk_post_div = 3; } sc->vclk_fb_div = q * sc->vclk_post_div / 100; - aprint_error("post_div: %d log2_post_div: %d mclk_div: %d\n", + DPRINTF("post_div: %d log2_post_div: %d mclk_div: %d\n", sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div); vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL); @@ -1258,7 +1284,7 @@ mach64_set_pll(struct mach64_softc *sc, vclk_ctl |= PLL_VCLK_RESET; regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); - aprint_error("target: %d output: %d\n", clock, + DPRINTF("target: %d output: %d\n", clock, (2 * sc->ref_freq * sc->vclk_fb_div) / (sc->ref_div * sc->vclk_post_div)); @@ -1851,7 +1877,8 @@ mach64_ioctl(void *v, void *vs, u_long c mach64_init(sc); mach64_init_engine(sc); mach64_init_lut(sc); - mach64_modeswitch(sc, sc->sc_my_mode); + if (sc->sc_setmode) + mach64_modeswitch(sc, sc->sc_my_mode); mach64_clearscreen(sc); glyphcache_wipe(&sc->sc_gc); vcons_redraw_screen(ms);