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);