Module Name: src Committed By: macallan Date: Sun May 28 05:27:14 UTC 2017
Modified Files: src/sys/dev/pci: machfb.c Log Message: g/c some unused / #if 0-ed goop, support firmware-provided EDID, get rid of private list of video modes tested on macppc, should Just Work(tm) on sparc64 To generate a diff of this commit: cvs rdiff -u -r1.92 -r1.93 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.92 src/sys/dev/pci/machfb.c:1.93 --- src/sys/dev/pci/machfb.c:1.92 Mon Jul 11 11:31:51 2016 +++ src/sys/dev/pci/machfb.c Sun May 28 05:27:13 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machfb.c,v 1.92 2016/07/11 11:31:51 msaitoh Exp $ */ +/* $NetBSD: machfb.c,v 1.93 2017/05/28 05:27:13 macallan Exp $ */ /* * Copyright (c) 2002 Bang Jun-Young @@ -34,7 +34,7 @@ #include <sys/cdefs.h> __KERNEL_RCSID(0, - "$NetBSD: machfb.c,v 1.92 2016/07/11 11:31:51 msaitoh Exp $"); + "$NetBSD: machfb.c,v 1.93 2017/05/28 05:27:13 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -124,6 +124,7 @@ struct mach64_softc { int mem_freq; int ramdac_freq; int ref_freq; + int vclk_freq; int ref_div; int log2_vclk_post_div; @@ -132,10 +133,12 @@ struct mach64_softc { int mclk_post_div; int mclk_fb_div; int sc_clock; /* which clock to use */ + int minref, m; struct videomode *sc_my_mode; int sc_edid_size; uint8_t sc_edid_data[1024]; + struct edid_info sc_ei; u_char sc_cmap_red[256]; u_char sc_cmap_green[256]; @@ -205,24 +208,6 @@ static const char *mach64_memtype_names[ "(unknown type)" }; -static struct videomode mach64_modes[] = { - /* 640x400 @ 70 Hz, 31.5 kHz */ - { 25175, 640, 664, 760, 800, 400, 409, 411, 450, 0, NULL, }, - /* 640x480 @ 72 Hz, 36.5 kHz */ - { 25175, 640, 664, 760, 800, 480, 491, 493, 525, 0, NULL, }, - /* 800x600 @ 72 Hz, 48.0 kHz */ - { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, - VID_PHSYNC | VID_PVSYNC, NULL, }, - /* 1024x768 @ 70 Hz, 56.5 kHz */ - { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, - VID_NHSYNC | VID_NVSYNC, NULL, }, - /* 1152x864 @ 70 Hz, 62.4 kHz */ - { 92000, 1152, 1208, 1368, 1474, 864, 865, 875, 895, 0, NULL, }, - /* 1280x1024 @ 70 Hz, 74.59 kHz */ - { 126500, 1280, 1312, 1472, 1696, 1024, 1032, 1040, 1068, - VID_NHSYNC | VID_NVSYNC, NULL, } -}; - extern const u_char rasops_cmap[768]; static int mach64_match(device_t, cfdata_t, void *); @@ -235,9 +220,7 @@ 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 defined(__sparc__) || defined(__powerpc__) static void mach64_get_mode(struct mach64_softc *, struct videomode *); -#endif static int mach64_calc_crtcregs(struct mach64_softc *, struct mach64_crtcregs *, @@ -256,8 +239,6 @@ static void mach64_adjust_frame(struct m static void mach64_init_lut(struct mach64_softc *); static void mach64_init_screen(void *, struct vcons_screen *, int, long *); -static int mach64_set_screentype(struct mach64_softc *, - const struct wsscreen_descr *); static int mach64_is_console(struct mach64_softc *); static void mach64_cursor(void *, int, int, int); @@ -293,68 +274,13 @@ static struct wsscreen_descr mach64_defa 80, 30, NULL, 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &default_mode -}, mach64_80x25_screen = { - "80x25", 80, 25, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[0] -}, mach64_80x30_screen = { - "80x30", 80, 30, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[1] -}, mach64_80x40_screen = { - "80x40", 80, 40, - NULL, - 8, 10, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[0] -}, mach64_80x50_screen = { - "80x50", 80, 50, - NULL, - 8, 8, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[0] -}, mach64_100x37_screen = { - "100x37", 100, 37, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[2] -}, mach64_128x48_screen = { - "128x48", 128, 48, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[3] -}, mach64_144x54_screen = { - "144x54", 144, 54, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[4] -}, mach64_160x64_screen = { - "160x54", 160, 64, - NULL, - 8, 16, - WSSCREEN_WSCOLORS | WSSCREEN_HILIT, - &mach64_modes[5] + WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE + /* | WSSCREEN_RESIZE */, + NULL }; static const struct wsscreen_descr *_mach64_scrlist[] = { &mach64_defaultscreen, - &mach64_80x25_screen, - &mach64_80x30_screen, - &mach64_80x40_screen, - &mach64_80x50_screen, - &mach64_100x37_screen, - &mach64_128x48_screen, - &mach64_144x54_screen, - &mach64_160x64_screen }; static struct wsscreen_list mach64_screenlist = { @@ -366,11 +292,6 @@ static int mach64_ioctl(void *, void *, struct lwp *); static paddr_t mach64_mmap(void *, void *, off_t, int); -#if 0 -static int mach64_load_font(void *, void *, struct wsdisplay_font *); -#endif - - static struct vcons_screen mach64_console_screen; /* @@ -480,15 +401,13 @@ mach64_attach(device_t parent, device_t struct pci_attach_args *pa = aux; struct rasops_info *ri; prop_data_t edid_data; -#if defined(__sparc__) || defined(__powerpc__) const struct videomode *mode = NULL; -#endif int bar, id, expected_id; int is_gx; const char **memtype_names; struct wsemuldisplaydev_attach_args aa; long defattr; - int setmode, width, height; + int setmode = 0, width, height; pcireg_t screg; uint32_t reg; const pcireg_t enables = PCI_COMMAND_MEM_ENABLE; @@ -578,19 +497,19 @@ 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); + memset(&sc->sc_ei, 0, sizeof(sc->sc_ei)); if ((edid_data = prop_dictionary_get(device_properties(self), "EDID")) != NULL) { - struct edid_info ei; sc->sc_edid_size = min(1024, prop_data_size(edid_data)); memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data)); memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data), sc->sc_edid_size); - edid_parse(sc->sc_edid_data, &ei); + edid_parse(sc->sc_edid_data, &sc->sc_ei); #ifdef MACHFB_DEBUG - edid_print(&ei); + edid_print(&sc->sc_ei); #endif } @@ -640,14 +559,19 @@ 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_debug("ref_div: %d\n", sc->ref_div); + aprint_error("ref_div: %d\n", sc->ref_div); sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV); - aprint_debug("mclk_fb_div: %d\n", sc->mclk_fb_div); + aprint_error("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) / (sc->mem_freq * sc->ref_div); sc->ramdac_freq = mach64_get_max_ramdac(sc); + { + sc->minref = sc->ramdac_freq / 510; + sc->m = sc->ref_freq / sc->minref; + aprint_error("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", (u_long)sc->memsize, @@ -676,34 +600,71 @@ mach64_attach(device_t parent, device_t sc->sc_console = mach64_is_console(sc); aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL)); -#if defined(__sparc__) || defined(__powerpc__) - if (sc->sc_console) { - if (mode != NULL) { + +#define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \ + ((m)->hdisplay <= 11280)) + + /* no mode setting support on ancient chips with external clocks */ + setmode = 0; + if (!is_gx) { + /* + * Now pick a mode. + */ + if ((sc->sc_ei.edid_preferred_mode != NULL)) { + struct videomode *m = sc->sc_ei.edid_preferred_mode; + if (MODE_IS_VALID(m)) { + memcpy(&default_mode, m, + sizeof(struct videomode)); + setmode = 1; + } else { + aprint_error_dev(sc->sc_dev, + "unable to use preferred mode\n"); + } + } + /* + * if we can't use the preferred mode go look for the + * best one we can support + */ + if (setmode == 0) { + struct videomode *m = sc->sc_ei.edid_modes; + + mode = NULL; + sort_modes(sc->sc_ei.edid_modes, + &sc->sc_ei.edid_preferred_mode, + sc->sc_ei.edid_nmodes); + for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) + if (MODE_IS_VALID(&m[n])) { + mode = &m[n]; + break; + } + if (mode != NULL) { + memcpy(&default_mode, mode, + sizeof(struct videomode)); + setmode = 1; + } + } + /* got nothing? try to pick one based on firmware parameters */ + if (setmode == 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) { + mode = pick_mode_by_ref(1024, 768, 60); memcpy(&default_mode, mode, sizeof(struct videomode)); setmode = 1; - } else { - mach64_get_mode(sc, &default_mode); - setmode = 0; } - sc->sc_my_mode = &default_mode; } else { - /* fill in default_mode if it's empty */ + /* make sure my_mode points at something sensible */ mach64_get_mode(sc, &default_mode); if (default_mode.dot_clock == 0) { - memcpy(&default_mode, &mach64_modes[4], + memcpy(&default_mode, pick_mode_by_ref(width, height, 60), sizeof(default_mode)); } - sc->sc_my_mode = &default_mode; - setmode = 1; } -#else - if (default_mode.dot_clock == 0) { - memcpy(&default_mode, &mach64_modes[0], - sizeof(default_mode)); - } - sc->sc_my_mode = &mach64_modes[0]; - setmode = 1; -#endif + sc->sc_my_mode = &default_mode; sc->bits_per_pixel = 8; sc->virt_x = sc->sc_my_mode->hdisplay; @@ -827,30 +788,21 @@ mach64_init_screen(void *cookie, struct struct mach64_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; -/* XXX for now */ -#define setmode 0 - ri->ri_depth = sc->bits_per_pixel; ri->ri_width = sc->sc_my_mode->hdisplay; ri->ri_height = sc->sc_my_mode->vdisplay; ri->ri_stride = ri->ri_width; ri->ri_flg = RI_CENTER | RI_FULLCLEAR; if (ri->ri_depth == 8) - ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA; + ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA | + RI_PREFER_ALPHA; #ifdef VCONS_DRAW_INTR scr->scr_flags |= VCONS_DONT_READ; #endif - if (existing) { - if (setmode && mach64_set_screentype(sc, scr->scr_type)) { - panic("%s: failed to switch video mode", - device_xname(sc->sc_dev)); - } - } - rasops_init(ri, 0, 0); - ri->ri_caps = WSSCREEN_WSCOLORS; + ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE; rasops_reconfig(ri, sc->sc_my_mode->vdisplay / ri->ri_font->fontheight, sc->sc_my_mode->hdisplay / ri->ri_font->fontwidth); @@ -919,7 +871,6 @@ mach64_get_max_ramdac(struct mach64_soft return 80000; } -#if defined(__sparc__) || defined(__powerpc__) static void mach64_get_mode(struct mach64_softc *sc, struct videomode *mode) { @@ -946,7 +897,6 @@ 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, @@ -1073,7 +1023,7 @@ mach64_init_engine(struct mach64_softc * regw(sc, CONTEXT_MASK, 0xffffffff); - regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22); + regw(sc, DST_OFF_PITCH, (pitch_value >> 3) << 22); /* make sure the visible area starts where we're going to draw */ regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22); @@ -1087,7 +1037,7 @@ mach64_init_engine(struct mach64_softc * regw(sc, DST_CNTL, DST_LAST_PEL | DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - regw(sc, SRC_OFF_PITCH, (pitch_value / 8) << 22); + regw(sc, SRC_OFF_PITCH, (pitch_value >> 3) << 22); regw(sc, SRC_Y_X, 0); regw(sc, SRC_HEIGHT1_WIDTH1, 1); @@ -1161,7 +1111,7 @@ mach64_set_dsp(struct mach64_softc *sc) { uint32_t fifo_depth, page_size, dsp_precision, dsp_loop_latency; uint32_t dsp_off, dsp_on, dsp_xclks_per_qw; - uint32_t xclks_per_qw, y; + uint32_t xclks_per_qw, xclks_per_qw_m, y; uint32_t fifo_off, fifo_on; aprint_normal_dev(sc->sc_dev, "initializing the DSP\n"); @@ -1180,9 +1130,15 @@ mach64_set_dsp(struct mach64_softc *sc) } dsp_precision = 0; + xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) / (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel); + + 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); y = (xclks_per_qw * fifo_depth) >> 11; + while (y) { y >>= 1; dsp_precision++; @@ -1206,7 +1162,6 @@ mach64_set_dsp(struct mach64_softc *sc) } break; case SDRAM: - case SGRAM: if (sc->memsize > 1024) { page_size = 8; dsp_loop_latency += 8; @@ -1215,6 +1170,10 @@ mach64_set_dsp(struct mach64_softc *sc) dsp_loop_latency += 9; } break; + case SGRAM: + page_size = 8; + dsp_loop_latency = 8; + break; default: page_size = 10; dsp_loop_latency += 9; @@ -1280,7 +1239,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_debug("post_div: %d log2_post_div: %d mclk_div: %d\n", + aprint_error("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); @@ -1288,6 +1247,10 @@ 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, + (2 * sc->ref_freq * sc->vclk_fb_div) / + (sc->ref_div * sc->vclk_post_div)); + regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div); reg = regrb_pll(sc, VCLK_POST_DIV); reg &= ~(3 << clockshift); @@ -1302,6 +1265,7 @@ mach64_set_pll(struct mach64_softc *sc, clockreg &= ~CLOCK_SEL; clockreg |= sc->sc_clock | CLOCK_STROBE; regw(sc, CLOCK_CNTL, clockreg); + sc->vclk_freq = clock; } static void @@ -1404,19 +1368,6 @@ mach64_getcmap(struct mach64_softc *sc, } static int -mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des) -{ - struct mach64_crtcregs regs; - - if (mach64_calc_crtcregs(sc, ®s, - (struct videomode *)des->modecookie)) - return 1; - - mach64_set_crtcregs(sc, ®s); - return 0; -} - -static int mach64_is_console(struct mach64_softc *sc) { bool console = 0; @@ -1502,6 +1453,8 @@ mach64_putchar_mono(void *cookie, int ro mach64_setup_mono(sc, x, y, wi, he, fg, bg); mach64_feed_bytes(sc, ri->ri_fontscale, data); } + if (attr & 1) + mach64_rectfill(sc, x, y + he - 2, wi, 1, fg); } } @@ -1512,7 +1465,7 @@ mach64_putchar_aa8(void *cookie, int row struct wsdisplay_font *font = PICK_FONT(ri, c); struct vcons_screen *scr = ri->ri_hw; struct mach64_softc *sc = scr->scr_cookie; - uint32_t bg, latch = 0, bg8, fg8, pixel; + uint32_t bg, fg, latch = 0, bg8, fg8, pixel; int i, x, y, wi, he, r, g, b, aval; int r1, g1, b1, r0, g0, b0, fgo, bgo; uint8_t *data8; @@ -1527,11 +1480,14 @@ mach64_putchar_aa8(void *cookie, int row wi = font->fontwidth; he = font->fontheight; bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0x0f]; + fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0x0f]; x = ri->ri_xorigin + col * wi; y = ri->ri_yorigin + row * he; if (c == 0x20) { mach64_rectfill(sc, x, y, wi, he, bg); + if (attr & 1) + mach64_rectfill(sc, x, y + he - 2, wi, 1, fg); return; } @@ -1611,7 +1567,10 @@ mach64_putchar_aa8(void *cookie, int row if (rv == GC_ADD) { glyphcache_add(&sc->sc_gc, c, x, y); + } else if (attr & 1) { + mach64_rectfill(sc, x, y + he - 2, wi, 1, fg); } + } static void @@ -1702,8 +1661,13 @@ mach64_bitblt(void *cookie, int xs, int { struct mach64_softc *sc = cookie; uint32_t dest_ctl = 0; - + +#if 0 + wait_for_idle(sc); +#else wait_for_fifo(sc, 10); +#endif + regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_8BPP | HOST_8BPP); regw(sc, DP_SRC, FRGD_SRC_BLIT); regw(sc, DP_MIX, (rop & 0xffff) << 16);