Subject: Re: CVS commit: syssrc/sys/arch/hp300/dev
To: Jason R Thorpe <thorpej@wasabisystems.com>
From: Gregory McGarry <g.mcgarry@ieee.org>
List: port-hp300
Date: 04/18/2002 12:32:22
Jason R Thorpe wrote:

>  > Log Message:
>  > Don't frob MCR_IEN bit if on a 425e.  Problem initially reported
>  > by Christoph Badura:
>  > 
>  > It looks to me like the 425e uses reverse polarity of the MCR_IEN bit with
>  > respect to the other 4xx models.  That could be because it doesn't have
>  > an inverter wired behind the IEN(OUT2) output of the UART.
> 
> Perhaps it should be frobbed, just in the opposite sense?  And, instead
> of checking for "425E" all over the place, maybe set a flag in the attach
> routine, and check that instead?

Try this:

--- apci.c.orig	Thu Apr 18 12:02:40 2002
+++ apci.c	Thu Apr 18 12:28:57 2002
@@ -136,6 +136,7 @@
 #define	APCI_HASFIFO	0x01		/* unit has a fifo */
 #define	APCI_ISCONSOLE	0x02		/* unit is console */
 #define	APCI_SOFTCAR	0x04		/* soft carrier */
+#define APCI_IENINVERT	0x08		/* invert IEN line */
 
 int	apcimatch __P((struct device *, struct cfdata *, void *));
 void	apciattach __P((struct device *, struct device *, void *));
@@ -152,7 +153,7 @@
 int	apciparam __P((struct tty *, struct termios *));
 void	apcistart __P((struct tty *));
 int	apcimctl __P((struct apci_softc *, int, int));
-void	apciinit __P((struct apciregs *, int));
+void	apciinit __P((struct apciregs *, int, int));
 void	apcitimeout __P((void *));
 
 cdev_decl(apci);
@@ -235,6 +236,13 @@
 	    (struct apciregs *)IIOV(FRODO_BASE + fa->fa_offset);
 	sc->sc_flags = 0;
 
+	if (fa->fa_offset == FRODO_APCI_OFFSET(1)) {
+		/*
+		 * The IEN line is inverted.
+		 */
+		sc->sc_flags |= APCI_IENINVERT;
+	}
+
 	callout_init(&sc->sc_diag_ch);
 
 	/* Are we the console? */
@@ -322,7 +330,8 @@
 		 * The chip might be left in an inconsistent state
 		 * if it is read inadventently.
 		 */
-		apciinit(apci, apcidefaultrate);
+		apciinit(apci, apcidefaultrate,
+			(sc->sc_flags & APCI_IENINVERT) != 0);
 
 		ttychars(tp);
 		tp->t_iflag = TTYDEF_IFLAG;
@@ -737,7 +746,9 @@
 	tp->t_cflag = cflag;
 
 	apci->ap_ier = IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC;
-	if (mmuid != MMUID_425_E)
+	if ((sc->sc_flags & APCI_IENINVERT) != 0)
+		apci->ap_mcr &= ~MCR_IEN;
+	else
 		apci->ap_mcr |= MCR_IEN;
 
 	splx(s);
@@ -802,17 +813,22 @@
 	int bits, how;
 {
 	struct apciregs *apci = sc->sc_apci;
+	int ien = 0;
 	int s;
 
-	if (mmuid != MMUID_425_E) {
-		/*
-		 * Always make sure MCR_IEN is set (unless setting to 0)
-		 */
-		if (how == DMBIS || (how == DMSET && bits))
-			bits |= MCR_IEN;
-		else if (how == DMBIC)
-			bits &= ~MCR_IEN;
-	}
+	/*
+	 * Always make sure MCR_IEN is set (unless setting to 0)
+	 */
+	if (how == DMBIS || (how == DMSET && bits))
+		ien = 1;
+	else if (how == DMBIC)
+		ien = 0;
+
+	if (((sc->sc_flags & APCI_IENINVERT) != 0 && ien) ||
+	    ((sc->sc_flags & APCI_IENINVERT) == 0 && !ien) )
+		bits &= ~MCR_IEN;
+	else
+		bits |= MCR_IEN;
 
 	s = spltty();
 
@@ -839,12 +855,14 @@
 }
 
 void
-apciinit(apci, rate)
+apciinit(apci, rate, invert)
 	struct apciregs *apci;
 	int rate;
+	int invert;
 {
 	int s;
 	short stat;
+	u_int8_t mcr;
 
 	s = splhigh();
 
@@ -857,7 +875,10 @@
 	apci->ap_ier = IER_ERXRDY | IER_ETXRDY;
 	apci->ap_fifo =
 	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1;
-	apci->ap_mcr = MCR_DTR | MCR_RTS;
+	mcr = MCR_DTR | MCR_RTS;
+	if (invert)
+		mcr |= MCR_IEN;
+	apci->ap_mcr = mcr;
 	delay(100);
 	stat = apci->ap_iir;
 	splx(s);
@@ -911,7 +932,7 @@
         va = bus_space_vaddr(bst, bsh);
 	apci = (struct apciregs *)va;
 
-	apciinit(apci, apcidefaultrate);
+	apciinit(apci, apcidefaultrate, 1);
         apciconsinit = 1;
         apci_cn = apci;
 
@@ -964,7 +985,7 @@
 	s = splhigh();
 
 	if (apciconsinit == 0) {
-		apciinit(apci_cn, apcidefaultrate);
+		apciinit(apci_cn, apcidefaultrate, 1);
 		apciconsinit = 1;
 	}
 

	-- Gregory McGarry <g.mcgarry@ieee.org>