Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci BUG FIX: change enable sequence for 16-bit pcmci...



details:   https://anonhg.NetBSD.org/src/rev/9d76d980e673
branches:  trunk
changeset: 499746:9d76d980e673
user:      haya <haya%NetBSD.org@localhost>
date:      Tue Nov 28 09:11:36 2000 +0000

description:
BUG FIX: change enable sequence for 16-bit pcmcia cards.  This change
provides better (not perfect) reset sequence.  The most significant
change is asserting output enable reg before power up.  Stop routing
interrupt during reset.

diffstat:

 sys/dev/pci/pccbb.c |  91 +++++++++++++++++++++++++---------------------------
 1 files changed, 43 insertions(+), 48 deletions(-)

diffs (183 lines):

diff -r b05419fb7a55 -r 9d76d980e673 sys/dev/pci/pccbb.c
--- a/sys/dev/pci/pccbb.c       Tue Nov 28 06:23:15 2000 +0000
+++ b/sys/dev/pci/pccbb.c       Tue Nov 28 09:11:36 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pccbb.c,v 1.47 2000/11/27 09:04:32 haya Exp $  */
+/*     $NetBSD: pccbb.c,v 1.48 2000/11/28 09:11:36 haya Exp $  */
 
 /*
  * Copyright (c) 1998, 1999 and 2000
@@ -747,7 +747,7 @@
 
        /* Route functional interrupts to PCI. */
        reg = pci_conf_read(pc, tag, PCI_BCR_INTR);
-       reg &= ~CB_BCR_INTR_IREQ_ENABLE;        /* use PCI Intr */
+       reg |= CB_BCR_INTR_IREQ_ENABLE;         /* disable PCI Intr */
        reg |= CB_BCR_WRITE_POST_ENABLE;        /* enable write post */
        reg |= CB_BCR_RESET_ENABLE;             /* assert reset */
        pci_conf_write(pc, tag, PCI_BCR_INTR, reg);
@@ -1073,6 +1073,9 @@
        struct pcic_handle *ph;
        int reg;
 {
+       bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
+           PCCBB_PCMCIA_OFFSET + reg, 1, BUS_SPACE_BARRIER_READ);
+
        return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h,
            PCCBB_PCMCIA_OFFSET + reg);
 }
@@ -1085,6 +1088,9 @@
 {
        bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg,
            val);
+
+       bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
+           PCCBB_PCMCIA_OFFSET + reg, 1, BUS_SPACE_BARRIER_WRITE);
 }
 
 /*
@@ -1219,13 +1225,6 @@
        bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl);
        status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
 
-       delay(20 * 1000);              /* wait 20 ms: Vcc setup time */
-       /*
-        * XXX delay 200 ms: though the standard defines that the Vcc set-up
-        * time is 20 ms, some PC-Card bridge requires longer duration.
-        */
-       delay(200 * 1000);
-
        if (status & CB_SOCKET_STAT_BADVCC) {   /* bad Vcc request */
                printf
                    ("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
@@ -1265,6 +1264,13 @@
 #endif
                return 0;
        }
+
+       /*
+        * XXX delay 300 ms: though the standard defines that the Vcc set-up
+        * time is 20 ms, some PC-Card bridge requires longer duration.
+        */
+       delay(300 * 1000);
+
        return 1;                      /* power changed correctly */
 }
 
@@ -1653,24 +1659,23 @@
        void *arg;
 {
        struct pccbb_intrhand_list *pil, *newpil;
+       pcireg_t reg;
 
        DPRINTF(("pccbb_intr_establish start. %p\n", sc->sc_pil));
 
        if (sc->sc_pil == NULL) {
                /* initialize bridge intr routing */
+               reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
+               reg &= ~CB_BCR_INTR_IREQ_ENABLE;
+               pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, reg);
 
                switch (sc->sc_chipset) {
                case CB_TI113X:
-                       {
-                               pcireg_t cbctrl =
-                                   pci_conf_read(sc->sc_pc, sc->sc_tag,
-                                   PCI_CBCTRL);
-                               /* functional intr enabled */
-                               cbctrl |= PCI113X_CBCTRL_PCI_INTR;
-                               pci_conf_write(sc->sc_pc, sc->sc_tag,
-                                   PCI_CBCTRL, cbctrl);
-                               break;
-                       }
+                       reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
+                       /* functional intr enabled */
+                       reg |= PCI113X_CBCTRL_PCI_INTR;
+                       pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, reg);
+                       break;
                default:
                        break;
                }
@@ -1715,6 +1720,7 @@
        void *ih;
 {
        struct pccbb_intrhand_list *pil, **pil_prev;
+       pcireg_t reg;
 
        DPRINTF(("pccbb_intr_disestablish start. %p\n", sc->sc_pil));
 
@@ -1735,18 +1741,18 @@
 
                DPRINTF(("pccbb_intr_disestablish: no interrupt handler\n"));
 
+               /* stop routing PCI intr */
+               reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
+               reg |= CB_BCR_INTR_IREQ_ENABLE;
+               pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, reg);
+
                switch (sc->sc_chipset) {
                case CB_TI113X:
-                       {
-                               pcireg_t cbctrl =
-                                   pci_conf_read(sc->sc_pc, sc->sc_tag,
-                                   PCI_CBCTRL);
-                               /* functional intr disabled */
-                               cbctrl &= ~PCI113X_CBCTRL_PCI_INTR;
-                               pci_conf_write(sc->sc_pc, sc->sc_tag,
-                                   PCI_CBCTRL, cbctrl);
-                               break;
-                       }
+                       reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
+                       /* functional intr disabled */
+                       reg &= ~PCI113X_CBCTRL_PCI_INTR;
+                       pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, reg);
+                       break;
                default:
                        break;
                }
@@ -2219,15 +2225,9 @@
                return;
        }
 
-       /* assert reset bit */
-       intr = Pcic_read(ph, PCIC_INTR);
-       intr &= ~(PCIC_INTR_RESET | PCIC_INTR_CARDTYPE_MASK);
-       Pcic_write(ph, PCIC_INTR, intr);
-
        /* disable socket i/o: negate output enable bit */
 
-       power = Pcic_read(ph, PCIC_PWRCTL);
-       power &= ~PCIC_PWRCTL_OE;
+       power = 0;
        Pcic_write(ph, PCIC_PWRCTL, power);
 
        /* power down the socket to reset it, clear the card reset pin */
@@ -2240,21 +2240,16 @@
         */
        /* delay(300*1000); too much */
 
-       /* power up the socket */
-       pccbb_power(sc, voltage);
-
-       /* 
-        * wait 100ms until power raise (Tpr) and 20ms to become
-        * stable (Tsu(Vcc)).
-        *
-        * some machines require some more time to be settled
-        * (another 200ms is added here).
-        */
-       /* delay((100 + 20 + 200)*1000); too much */
-
+       /* assert reset bit */
+       intr = Pcic_read(ph, PCIC_INTR);
+       intr &= ~(PCIC_INTR_RESET | PCIC_INTR_CARDTYPE_MASK);
+       Pcic_write(ph, PCIC_INTR, intr);
+
+       /* power up the socket and output enable */
        power = Pcic_read(ph, PCIC_PWRCTL);
        power |= PCIC_PWRCTL_OE;
        Pcic_write(ph, PCIC_PWRCTL, power);
+       pccbb_power(sc, voltage);
 
        /* 
         * hold RESET at least 10us.



Home | Main Index | Thread Index | Old Index