Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc/booke/dev The P2020 doesn't have GPIO in th...



details:   https://anonhg.NetBSD.org/src/rev/34ecd9761950
branches:  trunk
changeset: 779307:34ecd9761950
user:      matt <matt%NetBSD.org@localhost>
date:      Thu May 17 16:24:09 2012 +0000

description:
The P2020 doesn't have GPIO in the same place as othe 85xx.  Deal with it.

diffstat:

 sys/arch/powerpc/booke/dev/pq3gpio.c |  136 ++++++++++++++++++++++------------
 1 files changed, 86 insertions(+), 50 deletions(-)

diffs (245 lines):

diff -r 7889d76d44d5 -r 34ecd9761950 sys/arch/powerpc/booke/dev/pq3gpio.c
--- a/sys/arch/powerpc/booke/dev/pq3gpio.c      Thu May 17 16:22:38 2012 +0000
+++ b/sys/arch/powerpc/booke/dev/pq3gpio.c      Thu May 17 16:24:09 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pq3gpio.c,v 1.5 2012/03/29 14:47:09 matt Exp $ */
+/*     $NetBSD: pq3gpio.c,v 1.6 2012/05/17 16:24:09 matt Exp $ */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -41,7 +41,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pq3gpio.c,v 1.5 2012/03/29 14:47:09 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pq3gpio.c,v 1.6 2012/05/17 16:24:09 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -64,10 +64,6 @@
 #include <powerpc/booke/e500reg.h>
 
 struct pq3gpio_group {
-#if 0
-       SIMPLEQ_ENTRY(pq3gpio_group) gc_link;
-       struct pq3gpio_softc *gc_softc;
-#endif
        struct gpio_chipset_tag gc_tag;
        gpio_pin_t gc_pins[32];
        bus_space_tag_t gc_bst;
@@ -106,27 +102,54 @@
        }
 }
 
+#if defined(MPC8548) || defined(MPC8555) || defined(MPC8544)
+static void
+pq3gpio_null_pin_ctl(void *v, int num, int ctl)
+{
+}
+#endif
+
+#if defined(MPC8536) || defined(P2020)
+/*
+ * MPC8536 / P20x0 have controllable input/output pins
+ */
 static void
 pq3gpio_pin_ctl(void *v, int num, int ctl)
 {
        struct pq3gpio_group * const gc = v;
        const u_int mask = 1 << (gc->gc_pins[num].pin_num ^ 31);
-        uint32_t old, new; 
   
-        old = bus_space_read_4(gc->gc_bst, gc->gc_bsh, GPDIR);
-        new = old;
-        switch (ctl & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
-        case GPIO_PIN_OUTPUT:    new |= mask; break;
-        case GPIO_PIN_INPUT:   new &= ~mask; break;
-        default:                return;
-        }
-        if (old != new)
-               bus_space_write_4(gc->gc_bst, gc->gc_bsh, GPDIR, new);
+       uint32_t old_dir = bus_space_read_4(gc->gc_bst, gc->gc_bsh, GPDIR);
+       uint32_t new_dir = old_dir;
+       switch (ctl & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+       case GPIO_PIN_OUTPUT:   new_dir |= mask; break;
+       case GPIO_PIN_INPUT:    new_dir &= ~mask; break;
+       default:                return;
+       }
+       if (old_dir != new_dir)
+               bus_space_write_4(gc->gc_bst, gc->gc_bsh, GPDIR, new_dir);
+
+       /*
+        * Now handle opendrain
+        */
+       uint32_t old_odr = bus_space_read_4(gc->gc_bst, gc->gc_bsh, GPODR);
+       uint32_t new_odr = old_odr;
+
+       if (ctl & GPIO_PIN_OPENDRAIN) {
+               new_odr |= mask;
+       } else {
+               new_odr &= ~mask;
+       }
+
+       if (old_odr != new_odr)
+               bus_space_write_4(gc->gc_bst, gc->gc_bsh, GPODR, new_odr);
 }
+#endif
 
 static void
 pq3gpio_group_create(device_t self, bus_space_tag_t bst, bus_space_handle_t bsh,
-       bus_size_t reg, uint32_t pinmask, int pincaps)
+       bus_size_t reg, uint32_t pinmask, int pincaps,
+       void (*pin_ctl)(void *, int, int))
 {
        struct pq3gpio_group * const gc = kmem_zalloc(sizeof(*gc), KM_SLEEP);
 
@@ -188,10 +211,10 @@
                [15] = ilog2(PMUXCR_DMA1),
        };
        
-       uint32_t pinmask = ~0;  /* assume all bits are valid */
+       uint32_t pinmask = 0xffff0000;  /* assume all bits are valid */
        uint32_t gpiomask = __BIT(31);
-       size_t pincnt = 32;
-       const uint32_t pmuxcr = bus_space_read_4(bst, bsh, PMUXCR);
+       size_t pincnt = 16;
+       const uint32_t pmuxcr = cpu_read_4(GLOBAL_BASE + PMUXCR);
        for (size_t i = 0; i < __arraycount(gpio2pmuxcr_map);
             i++, gpiomask >>= 1) {
                if (pmuxcr & __BIT(gpio2pmuxcr_map[i])) {
@@ -203,10 +226,11 @@
        /*
         * Create GPIO pin groups
         */
-       aprint_normal_dev(self, "%zu input pins, %zu output pins\n",
+       aprint_normal_dev(self, "%zu input/output/opendrain pins\n",
            pincnt, pincnt);
-       pq3gpio_group_create(self, bst, bsh, GPINDR, pinmask, GPIO_PIN_INPUT);
-       pq3gpio_group_create(self, bst, bsh, GPOUTDR, pinmask, GPIO_PIN_OUTPUT);
+       pq3gpio_group_create(self, bst, bsh, GPDAT, pinmask,
+           GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN,
+           pq3gpio_pin_ctl);
 }
 #endif /* MPC8536 */
 
@@ -227,8 +251,10 @@
        /*
         * Create GPIO pin groups
         */
-       pq3gpio_group_create(self, bst, bsh, GPINDR, 0xff000000, GPIO_PIN_INPUT);
-       pq3gpio_group_create(self, bst, bsh, GPOUTDR, 0xff000000, GPIO_PIN_OUTPUT);
+       pq3gpio_group_create(self, bst, bsh, GPINDR, 0xff000000,
+           GPIO_PIN_INPUT, pq3gpio_null_pin_ctl);
+       pq3gpio_group_create(self, bst, bsh, GPOUTDR, 0xff000000,
+           GPIO_PIN_OUTPUT, pq3gpio_null_pin_ctl);
 }
 #endif /* MPC8544 */
 
@@ -293,9 +319,11 @@
            ipins, opins);
 
        if (inmask)
-               pq3gpio_group_create(self, bst, bsh, GPINDR, inmask, GPIO_PIN_INPUT);
+               pq3gpio_group_create(self, bst, bsh, GPINDR, inmask,
+                   GPIO_PIN_INPUT, pq3gpio_null_pin_ctl);
        if (outmask)
-               pq3gpio_group_create(self, bst, bsh, GPOUTDR, outmask, GPIO_PIN_OUTPUT);
+               pq3gpio_group_create(self, bst, bsh, GPOUTDR, outmask,
+                   GPIO_PIN_OUTPUT, pq3gpio_null_pin_ctl);
 }
 #endif /* MPC8548 */
 
@@ -317,9 +345,9 @@
        
        uint32_t pinmask = 0xffff0000;  /* assume all bits are valid */
        size_t pincnt = 16;
-       const uint32_t pmuxcr = bus_space_read_4(bst, bsh, PMUXCR);
+       const uint32_t pmuxcr = cpu_read_4(GLOBAL_BASE + PMUXCR);
        for (size_t i = 0; i < __arraycount(gpio2pmuxcr_map); i++) {
-               if ((pmuxcr & gpio2pmuxcr_map[i][1]) == 0) {
+               if (pmuxcr & gpio2pmuxcr_map[i][1]) {
                        pinmask &= ~gpio2pmuxcr_map[i][0];
                        pincnt--;
                }
@@ -328,31 +356,39 @@
        /*
         * Create GPIO pin groups
         */
-       aprint_normal_dev(self, "%zu input/output pins\n",
+       aprint_normal_dev(self, "%zu input/output/opendrain pins\n",
            pincnt);
        pq3gpio_group_create(self, bst, bsh, GPDAT, pinmask,
-           GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+           GPIO_PIN_INPUT|GPIO_PIN_OUTPUT|GPIO_PIN_OPENDRAIN,
+           pq3gpio_pin_ctl);
 }
 #endif /* P2020 */
 
-static const struct {
-       uint16_t svr;
-       void (*attach)(device_t, bus_space_tag_t, bus_space_handle_t, u_int);
+static const struct pq3gpio_svr_info {
+       uint16_t si_svr;
+       void (*si_attach)(device_t, bus_space_tag_t, bus_space_handle_t, u_int);
+       bus_addr_t si_base;
+       bus_size_t si_size;
 } pq3gpio_svrs[] = {
 #ifdef MPC8548
-       { SVR_MPC8548v2 >> 16, pq3gpio_mpc8548_attach },
+       { SVR_MPC8548v2 >> 16, pq3gpio_mpc8548_attach,
+           GLOBAL_BASE, GLOBAL_SIZE },
 #endif
 #ifdef MPC8555
-       { SVR_MPC8555v1 >> 16, pq3gpio_mpc8548_attach },
+       { SVR_MPC8555v1 >> 16, pq3gpio_mpc8548_attach,
+           GLOBAL_BASE, GLOBAL_SIZE },
 #endif
 #ifdef MPC8544
-       { SVR_MPC8544v1 >> 16, pq3gpio_mpc8544_attach },
+       { SVR_MPC8544v1 >> 16, pq3gpio_mpc8544_attach,
+           GLOBAL_BASE, GLOBAL_SIZE },
 #endif
 #ifdef MPC8536
-       { SVR_MPC8536v1 >> 16, pq3gpio_mpc8536_attach },
+       { SVR_MPC8536v1 >> 16, pq3gpio_mpc8536_attach,
+           GPIO_BASE, GPIO_SIZE },
 #endif
 #ifdef P2020
-       { SVR_P2020v2 >> 16, pq3gpio_p20x0_attach },
+       { SVR_P2020v2 >> 16, pq3gpio_p20x0_attach,
+           GPIO_BASE, GPIO_SIZE },
 #endif
 };
 
@@ -362,20 +398,20 @@
        struct mainbus_attach_args * const ma = aux;
        bus_space_tag_t bst = ma->ma_memt;
        bus_space_handle_t bsh;
-       int error;
-
-       error = bus_space_map(bst, GLOBAL_BASE, GLOBAL_SIZE, 0, &bsh);
-       if (error) {
-               aprint_error_dev(self,
-                   "can't map global registers for gpio: %d\n",
-                   error);
-               return;
-       }
 
        const uint16_t svr = e500_get_svr();
        for (u_int i = 0; i < __arraycount(pq3gpio_svrs); i++) {
-               if (pq3gpio_svrs[i].svr == svr) {
-                       (*pq3gpio_svrs[i].attach)(self, bst, bsh, svr);
+               const struct pq3gpio_svr_info * const si = &pq3gpio_svrs[i];
+               if (si->si_svr == svr) {
+                       int error = bus_space_map(bst, si->si_base,
+                           si->si_size, 0, &bsh);
+                       if (error) {
+                               aprint_error_dev(self,
+                                   "can't map global registers for gpio: %d\n",
+                                   error);
+                               return;
+                       }
+                       (*si->si_attach)(self, bst, bsh, svr);
                        return;
                }
        }



Home | Main Index | Thread Index | Old Index