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, &regs,
-	    (struct videomode *)des->modecookie))
-		return 1;
-
-	mach64_set_crtcregs(sc, &regs);
-	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);

Reply via email to