Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci clean up the video mode selection logic, switch ...
details: https://anonhg.NetBSD.org/src/rev/2528303a2a36
branches: trunk
changeset: 1005408:2528303a2a36
user: macallan <macallan%NetBSD.org@localhost>
date: Sat Dec 07 01:00:40 2019 +0000
description:
clean up the video mode selection logic, switch modes only when actually
necessary
while there make some debug output optional
diffstat:
sys/dev/pci/machfb.c | 103 ++++++++++++++++++++++++++++++++------------------
1 files changed, 65 insertions(+), 38 deletions(-)
diffs (285 lines):
diff -r e28180af1650 -r 2528303a2a36 sys/dev/pci/machfb.c
--- a/sys/dev/pci/machfb.c Fri Dec 06 21:45:14 2019 +0000
+++ b/sys/dev/pci/machfb.c Sat Dec 07 01:00:40 2019 +0000
@@ -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 @@
#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 @@
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 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 @@
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 @@
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 @@
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 @@
edid_print(&sc->sc_ei);
#endif
}
-
is_gx = 0;
switch(mach64_chip_id) {
case PCI_PRODUCT_ATI_MACH64_GX:
@@ -561,9 +573,9 @@
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 @@
{
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 @@
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 @@
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 @@
* 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 @@
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_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 @@
* 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 @@
return 80000;
}
+#if 0
static void
mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
{
@@ -908,6 +927,7 @@
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 @@
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 @@
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 @@
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 @@
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_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);
Home |
Main Index |
Thread Index |
Old Index