PERFORCE change 96162 for review

Marcel Moolenaar marcel at FreeBSD.org
Wed Apr 26 20:55:13 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=96162

Change 96162 by marcel at marcel_nfs on 2006/04/26 20:55:09

	Setup Quatech boards. Setup includes:
	o  Determining if the SPAD jumper has been set. If so, none
	   of the extra features are enabled. We warn about this.
	   It's better to leave the SPAD jumper unset.
	o  Determine if a fixed clock rate multiplier has been set
	   by jumpers. If so, use that setting. Warn if the fixed
	   setting is less than maximum.
	o  Program the clock rate multiplier if it's under software
	   control. We select the highest possible multiplier.

Affected files ...

.. //depot/projects/uart/dev/puc/pucdata.c#27 edit

Differences ...

==== //depot/projects/uart/dev/puc/pucdata.c#27 (text+ko) ====

@@ -39,7 +39,14 @@
  */
 
 #include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
 
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <dev/puc/puc_bfe.h>
 #include <dev/puc/puc_cfg.h>
 
 static puc_config_f puc_config_cronyx;
@@ -366,71 +373,71 @@
 	},
 
 	{   0x135c, 0x0010, 0xffff, 0,
-	    "Quatech - QSC-100",
-	    DEFAULT_RCLK,
+	    "Quatech QSC-100",
+	    -3,	/* max 8x clock rate */
 	    PUC_PORT_4S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0020, 0xffff, 0,
-	    "Quatech - DSC-100",
-	    DEFAULT_RCLK,
+	    "Quatech DSC-100",
+	    -1, /* max 2x clock rate */
 	    PUC_PORT_2S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0030, 0xffff, 0,
-	    "Quatech - DSC-200/300",
-	    DEFAULT_RCLK,
+	    "Quatech DSC-200/300",
+	    -1, /* max 2x clock rate */
 	    PUC_PORT_2S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0040, 0xffff, 0,
-	    "Quatech - QSC-200/300",
-	    DEFAULT_RCLK,
+	    "Quatech QSC-200/300",
+	    -3, /* max 8x clock rate */
 	    PUC_PORT_4S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0050, 0xffff, 0,
-	    "Quatech - ESC-100D",
-	    DEFAULT_RCLK,
+	    "Quatech ESC-100D",
+	    -3, /* max 8x clock rate */
 	    PUC_PORT_8S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0060, 0xffff, 0,
-	    "Quatech - ESC-100M",
-	    DEFAULT_RCLK,
+	    "Quatech ESC-100M",
+	    -3, /* max 8x clock rate */
 	    PUC_PORT_8S, 0x14, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0170, 0xffff, 0,
-	    "Quatech - QSCLP-100",
-	    DEFAULT_RCLK,
+	    "Quatech QSCLP-100",
+	    -1, /* max 2x clock rate */
 	    PUC_PORT_4S, 0x18, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x0180, 0xffff, 0,
-	    "Quatech - DSCLP-100",
-	    DEFAULT_RCLK,
+	    "Quatech DSCLP-100",
+	    -1, /* max 3x clock rate */
 	    PUC_PORT_2S, 0x18, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x01b0, 0xffff, 0,
-	    "Quatech - DSCLP-200/300",
-	    DEFAULT_RCLK,
+	    "Quatech DSCLP-200/300",
+	    -1, /* max 2x clock rate */
 	    PUC_PORT_2S, 0x18, 0, 8,
 	    .config_function = puc_config_quatech
 	},
 
 	{   0x135c, 0x01e0, 0xffff, 0,
-	    "Quatech - ESCLP-100",
-	    DEFAULT_RCLK,
+	    "Quatech ESCLP-100",
+	    -3, /* max 8x clock rate */
 	    PUC_PORT_8S, 0x10, 0, 8,
 	    .config_function = puc_config_quatech
 	},
@@ -710,6 +717,92 @@
 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
     intptr_t *res)
 {
+	const struct puc_cfg *cfg = sc->sc_cfg;
+	struct puc_bar *bar;
+	uint8_t v0, v1;
+
+	switch (cmd) {
+	case PUC_CFG_SETUP:
+		/*
+		 * Check if the scratchpad register is enabled or if the
+		 * interrupt status and options registers are active.
+		 */
+		bar = puc_get_bar(sc, cfg->rid);
+		if (bar == NULL)
+			return (ENXIO);
+		/* Set DLAB in the LCR register of UART 0. */
+		bus_write_1(bar->b_res, 3, 0x80);
+		/* Write 0 to the SPR register of UART 0. */
+		bus_write_1(bar->b_res, 7, 0);
+		/* Read back the contents of the SPR register of UART 0. */
+		v0 = bus_read_1(bar->b_res, 7);
+		/* Write a specific value to the SPR register of UART 0. */
+		bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
+		/* Read back the contents of the SPR register of UART 0. */
+		v1 = bus_read_1(bar->b_res, 7);
+		/* Clear DLAB in the LCR register of UART 0. */
+		bus_write_1(bar->b_res, 3, 0);
+		/* Save the two values read-back from the SPR register. */
+		sc->sc_cfg_data = (v1 << 8) | v0;
+		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
+			/*
+			 * The SPR register echoed the two values written
+			 * by us. This means that the SPAD jumper is set.
+			 */
+			device_printf(sc->sc_dev, "warning: extra features "
+			    "not usable -- SPAD compatibility enabled\n");
+			return (0);
+		}
+		if (v0 != 0) {
+			/*
+			 * The first value doesn't match. This can only mean
+			 * that the SPAD jumper is not set and that a non-
+			 * standard fixed clock multiplier jumper is set.
+			 */
+			if (bootverbose)
+				device_printf(sc->sc_dev, "fixed clock rate "
+				    "multiplier of %d\n", 1 << v0);
+			if (v0 < -cfg->clock)
+				device_printf(sc->sc_dev, "warning: "
+				    "suboptimal fixed clock rate multiplier "
+				    "setting\n");
+			return (0);
+		}
+		/*
+		 * The first value matched, but the second didn't. We know
+		 * that the SPAD jumper is not set. We also know that the
+		 * clock rate multiplier is software controlled *and* that
+		 * we just programmed it to the maximum allowed.
+		 */
+		if (bootverbose)
+			device_printf(sc->sc_dev, "clock rate multiplier of "
+			    "%d selected\n", 1 << -cfg->clock);
+		return (0);
+	case PUC_CFG_GET_CLOCK:
+		v0 = sc->sc_cfg_data & 0xff;
+		v1 = (sc->sc_cfg_data >> 8) & 0xff;
+		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
+			/*
+			 * XXX With the SPAD jumper applied, there's no
+			 * easy way of knowing if there's also a clock
+			 * rate multiplier jumper installed. Let's hope
+			 * not...
+			 */
+			*res = DEFAULT_RCLK;
+		} else if (v0 == 0) {
+			/*
+			 * No clock rate multiplier jumper installed,
+			 * so we programmed the board with the maximum
+			 * multiplier allowed as given to us in the
+			 * clock field of the config record (negated).
+			 */
+			*res = DEFAULT_RCLK << -cfg->clock;
+		} else
+			*res = DEFAULT_RCLK << v0;
+		return (0);
+	default:
+		break;
+	}
 	return (ENXIO);
 }
 


More information about the p4-projects mailing list