Port-powerpc archive

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

IBM405GP/GPr OPB bus_space endian (powerpc/ibm4xx/dev/opb.c)



Hello,

(I sent again since the previous same mail to port-powerpc@ was denied)

Last week, a GPIO framework was imported from OpenBSD.
This is conflicted with IBM405GP/GPr OPB GPIO device name, "gpio".
I have fixed the above breakage.
I send a patch for this modification (with using GPIO fremework).

The bellow is the subject.
In the current source (sys/arch/powerpc/ibm4xx/dev/opb),
byte-ordering for opb(On-chip Peripheral Bus) bus_space is defined by
Little-Endian (as the following).

 static struct powerpc_bus_space opb_tag = {
        _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
        0x0, IBM405GP_UART0_BASE, 0x1000
 };

Why it is Little-Endian in spite of CPU byte-order (Big-Endian) ?
Is there any special reason?


In the gpio (on opb) driver,
I want to handle some 32-bit registers easily.
If there is no reason, I want to change bus_space byte-order
from Little to Big.
Is it ok?

-- 
Kind Regards,
--- shige
Shigeyuki Fukushima <shige@{FreeBSD,jp.FreeBSD,NetBSD}.org>
Index: sys/arch/evbppc/conf/OPENBLOCKS200
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/OPENBLOCKS200,v
retrieving revision 1.7
diff -u -u -r1.7 OPENBLOCKS200
--- sys/arch/evbppc/conf/OPENBLOCKS200  9 Sep 2005 16:35:29 -0000       1.7
+++ sys/arch/evbppc/conf/OPENBLOCKS200  1 Oct 2005 16:12:51 -0000
@@ -151,7 +151,8 @@
 gpiic0 at opb? addr ? irq ?            # On-chip IIC controller
 iic0   at gpiic?                       # I2C bus
 
-gpio0  at opb? addr ? irq ?            # On-chip GPIO controller
+gpio_opb0 at opb? addr ? irq ?         # On-chip GPIO controller
+gpio*  at gpio_opb?
 
 pchb0  at plb?                         # PCI-Host bridges
 
Index: sys/arch/evbppc/conf/OPENBLOCKS266
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/OPENBLOCKS266,v
retrieving revision 1.25
diff -u -u -r1.25 OPENBLOCKS266
--- sys/arch/evbppc/conf/OPENBLOCKS266  24 Aug 2005 19:54:50 -0000      1.25
+++ sys/arch/evbppc/conf/OPENBLOCKS266  1 Oct 2005 16:12:52 -0000
@@ -166,10 +166,8 @@
 gpiic0 at opb? addr ? irq ?            # On-chip IIC controller
 iic0   at gpiic?                       # I2C bus
 xrtc0  at iic? addr 0x6f               # RTC
-gpio0  at opb? addr ? irq ?            # On-chip GPIO controller
-obsled0        at gpio? addr 0x0c              # OBS LED connected GPIO
-obsled1        at gpio? addr 0x0d              # OBS LED connected GPIO
-obsled2        at gpio? addr 0x0e              # OBS LED connected GPIO
+gpio_opb0 at opb? addr ? irq ?         # On-chip GPIO controller
+gpio*  at gpio_opb?
 
 # PCI bus support
 pci*   at pchb?
Index: sys/arch/evbppc/conf/files.obs405
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.obs405,v
retrieving revision 1.12
diff -u -u -r1.12 files.obs405
--- sys/arch/evbppc/conf/files.obs405   10 Sep 2005 04:34:39 -0000      1.12
+++ sys/arch/evbppc/conf/files.obs405   1 Oct 2005 16:12:52 -0000
@@ -14,9 +14,9 @@
 file   arch/evbppc/obs405/obs405_autoconf.c
 file   arch/evbppc/obs405/obs405_machdep.c
 
-device obsled
-attach  obsled at gpio
-file   arch/evbppc/obs405/dev/obsled.c         obsled
+#device obsled
+#attach  obsled at ibmgpio
+#file  arch/evbppc/obs405/dev/obsled.c         obsled
 
 # Memory Disk for install kernel
 file   dev/md_root.c                           memory_disk_hooks
Index: sys/arch/evbppc/obs405/obs266_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/obs405/obs266_machdep.c,v
retrieving revision 1.1
diff -u -u -r1.1 obs266_machdep.c
--- sys/arch/evbppc/obs405/obs266_machdep.c     18 Mar 2005 14:12:34 -0000      
1.1
+++ sys/arch/evbppc/obs405/obs266_machdep.c     1 Oct 2005 16:12:52 -0000
@@ -214,7 +214,7 @@
        static char str[256];
        char *ap = str, *ap1 = ap;
 
-       obs266_led_set(OBS266_LED_ON);
+       /* obs266_led_set(OBS266_LED_ON); */
 
        boothowto = howto;
        if (!cold && !(howto & RB_NOSYNC) && !syncing) {
Index: sys/arch/powerpc/conf/files.ibm4xx
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/conf/files.ibm4xx,v
retrieving revision 1.7
diff -u -u -r1.7 files.ibm4xx
--- sys/arch/powerpc/conf/files.ibm4xx  23 Jan 2005 19:24:31 -0000      1.7
+++ sys/arch/powerpc/conf/files.ibm4xx  1 Oct 2005 16:12:52 -0000
@@ -30,9 +30,9 @@
 file   arch/powerpc/ibm4xx/dev/com_opb.c       com_opb
 
 # On-chip GPIO controller
-device gpio { addr, [size = -1] }
-attach gpio at opb
-file   arch/powerpc/ibm4xx/dev/gpio_opb.c      gpio
+device gpio_opb: gpiobus
+attach gpio_opb at opb
+file   arch/powerpc/ibm4xx/dev/gpio_opb.c      gpio_opb
 
 # On-chip ethernet device(s)
 device emac: ether, ifnet, arp, mii
Index: sys/arch/powerpc/ibm4xx/dev/gpio_opb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/dev/gpio_opb.c,v
retrieving revision 1.2
diff -u -u -r1.2 gpio_opb.c
--- sys/arch/powerpc/ibm4xx/dev/gpio_opb.c      26 Aug 2005 13:19:37 -0000      
1.2
+++ sys/arch/powerpc/ibm4xx/dev/gpio_opb.c      1 Oct 2005 16:12:52 -0000
@@ -35,72 +35,40 @@
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
+#include <sys/gpio.h>
 
-#include <machine/pio.h>
+#include <machine/bus.h>
+
+#include <dev/gpio/gpiovar.h>
 
 #include <powerpc/ibm4xx/dcr405gp.h>
 #include <powerpc/ibm4xx/dev/opbvar.h>
 #include <powerpc/ibm4xx/dev/gpioreg.h>
-#include <powerpc/ibm4xx/dev/gpiovar.h>
 
-struct gpio_softc {
+struct gpio_opb_softc {
        struct device           sc_dev;         /* device generic */
-       struct gpio_controller  sc_gpio;        /* GPIO controller */
-        u_long                 sc_addr;        /* GPIO controller address */
-};
-
-static int     gpio_print(void *, const char *);
-static int     gpio_search(struct device *, struct cfdata *,
-                       const int *ldesc, void *aux);
-static int     gpio_match(struct device *, struct cfdata *, void *);
-static void    gpio_attach(struct device *, struct device *, void *);
-
-static int     gpio_or_read(void *, int);
-static int     gpio_tcr_read(void *, int);
-static int     gpio_odr_read(void *, int);
-static int     gpio_ir_read(void *, int);
-static void    gpio_or_write(void *arg, int addr, int bit);
-static void    gpio_tcr_write(void *arg, int addr, int bit);
-static void    gpio_odr_write(void *arg, int addr, int bit);
-
-static int     gpio_read_bit(void *, int, int);
-static void    gpio_write_bit(void *, int, int, int);
-static uint32_t        gpio_read(void *, int);
-static void    gpio_write(void *, int, uint32_t);
-
-CFATTACH_DECL(gpio, sizeof(struct gpio_softc),
-    gpio_match, gpio_attach, NULL, NULL);
-
-static int
-gpio_print(void *aux, const char *pnp)
-{
-       struct gpio_attach_args *gaa = aux;
 
-       aprint_normal(" addr GPIO#%d", gaa->ga_addr);
-
-       return (UNCONF);
-}
-
-static int
-gpio_search(struct device *parent, struct cfdata *cf,
-       const int *ldesc, void *aux)
-{
-       struct gpio_softc *sc = (void *)parent;
-       struct gpio_attach_args gaa;
+       /* GPIO interface */
+       bus_space_tag_t         sc_gpio_iot;
+       bus_space_handle_t      sc_gpio_ioh;
+       struct gpio_chipset_tag sc_gpio_gc;
+       gpio_pin_t              sc_gpio_pins[GPIO_NPINS];
+};
 
-       gaa.ga_tag = &sc->sc_gpio;
-       gaa.ga_addr = cf->cf_loc[GPIOCF_ADDR];
+int    gpio_opb_match(struct device *, struct cfdata *, void *);
+void   gpio_opb_attach(struct device *, struct device *, void *);
 
-       if (config_match(parent, cf, &gaa) > 0)
-               config_attach(parent, cf, &gaa, gpio_print);
+CFATTACH_DECL(gpio_opb, sizeof(struct gpio_opb_softc),
+       gpio_opb_match, gpio_opb_attach, NULL, NULL);
 
-       return (0);
-}
+int    gpio_opb_pin_read(void *, int);
+void   gpio_opb_pin_write(void *, int, int);
+void   gpio_opb_pin_ctl(void *, int, int);
 
-static int
-gpio_match(struct device *parent, struct cfdata *cf, void *args)
+int
+gpio_opb_match(struct device *parent, struct cfdata *cf, void *aux)
 {
-       struct opb_attach_args *oaa = args;
+       struct opb_attach_args *oaa = aux;
 
        if (strcmp(oaa->opb_name, cf->cf_name) != 0)
                return (0);
@@ -108,109 +76,142 @@
        return (1);
 }
 
-static void
-gpio_attach(struct device *parent, struct device *self, void *aux)
+void
+gpio_opb_attach(struct device *parent, struct device *self, void *aux)
 {
-       struct gpio_softc *sc = (struct gpio_softc *)self;
+       struct gpio_opb_softc *sc = (struct gpio_opb_softc *)self;
        struct opb_attach_args *oaa = aux;
+       struct gpiobus_attach_args gba;
+       int i;
+       u_int32_t reg1, reg2, reg3;
 
        aprint_naive(": GPIO controller\n");
        aprint_normal(": On-Chip GPIO controller\n");
 
-       sc->sc_addr = oaa->opb_addr;
-       sc->sc_gpio.cookie = sc;
-       sc->sc_gpio.io_or_read = gpio_or_read;
-       sc->sc_gpio.io_tcr_read = gpio_tcr_read;
-       sc->sc_gpio.io_odr_read = gpio_odr_read;
-       sc->sc_gpio.io_ir_read = gpio_ir_read;
-       sc->sc_gpio.io_or_write = gpio_or_write;
-       sc->sc_gpio.io_tcr_write = gpio_tcr_write;
-       sc->sc_gpio.io_odr_write = gpio_odr_write;
-
-       (void) config_search_ia(gpio_search, self, "gpio", NULL);
-}
-
-static int
-gpio_or_read(void *arg, int addr)
-{
-       return (gpio_read_bit(arg, GPIO_OR, addr));
-}
-
-static int
-gpio_tcr_read(void *arg, int addr)
-{
-       return (gpio_read_bit(arg, GPIO_TCR, addr));
-}
-
-static int
-gpio_odr_read(void *arg, int addr)
-{
-       return (gpio_read_bit(arg, GPIO_ODR, addr));
-}
-
-static int
-gpio_ir_read(void *arg, int addr)
-{
-       gpio_write_bit(arg, GPIO_ODR, addr, 0);
-       gpio_write_bit(arg, GPIO_TCR, addr, 0);
-       return (gpio_read_bit(arg, GPIO_ODR, addr));
-}
-
-static void
-gpio_or_write(void *arg, int addr, int bit)
-{
-       gpio_write_bit(arg, GPIO_ODR, addr, 0);
-       gpio_write_bit(arg, GPIO_TCR, addr, 1);
-       gpio_write_bit(arg, GPIO_OR, addr, bit);
-}
-
-static void
-gpio_tcr_write(void *arg, int addr, int bit)
-{
-       gpio_write_bit(arg, GPIO_TCR, addr, bit);
-}
+       /* Map GPIO I/O space */
+       sc->sc_gpio_iot = oaa->opb_bt;
+       bus_space_map(sc->sc_gpio_iot, oaa->opb_addr,
+                               GPIO_NREG, 0, &sc->sc_gpio_ioh);
+       /* Read current register status */
+       reg1 = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_IR);
+       reg2 = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_TCR);
+       reg3 = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_ODR);
+
+       /* Initialize pins array */
+       for (i = 0 ; i < GPIO_NPINS ; i++) {
+               int p = i + 1;
+               sc->sc_gpio_pins[i].pin_num = i;
+               sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INOUT
+                                               | GPIO_PIN_OPENDRAIN
+                                               | GPIO_PIN_TRISTATE;
+
+               /* current defaults */
+               sc->sc_gpio_pins[i].pin_flags =
+                       ((reg3 >> GPIO_PIN_SHIFT(p)) & 0x01)
+                       ? GPIO_PIN_OPENDRAIN
+                       : (((reg2 >> GPIO_PIN_SHIFT(p)) & 0x01)
+                               ? GPIO_PIN_INOUT
+                               : GPIO_PIN_TRISTATE);
+               sc->sc_gpio_pins[i].pin_state =
+                       ((reg1 >> GPIO_PIN_SHIFT(p)) & 0x01);
+       }
+
+       /* Create controller tag */
+       sc->sc_gpio_gc.gp_cookie = sc;
+       sc->sc_gpio_gc.gp_pin_read = gpio_opb_pin_read;
+       sc->sc_gpio_gc.gp_pin_write = gpio_opb_pin_write;
+       sc->sc_gpio_gc.gp_pin_ctl = gpio_opb_pin_ctl;
+
+       gba.gba_name = "gpio";
+       gba.gba_gc = &sc->sc_gpio_gc;
+       gba.gba_pins = sc->sc_gpio_pins;
+       gba.gba_npins = GPIO_NPINS;
+
+       /* Attach GPIO framework */
+       (void) config_found(&sc->sc_dev, &gba, gpiobus_print);
+}
+
+int
+gpio_opb_pin_read(void *arg, int pin)
+{
+       struct gpio_opb_softc *sc = arg;
+       u_int32_t data;
+       int p;
 
-static void
-gpio_odr_write(void *arg, int addr, int bit)
-{
-       gpio_write_bit(arg, GPIO_ODR, addr, bit);
-}
+       p = pin % GPIO_NPINS;
+       p = p + 1;
 
-static int
-gpio_read_bit(void *arg, int offset, int addr)
-{
-       uint32_t rv = gpio_read(arg, offset);
-       uint32_t mask = GPIO_SBIT(addr);
+       data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_IR);
 
-       return ((rv & mask) >> GPIO_SHIFT(addr));
+       return ((data >> GPIO_PIN_SHIFT(p)) & 0x1);
 }
 
 void
-gpio_write_bit(void *arg, int offset, int addr, int bit)
+gpio_opb_pin_write(void *arg, int pin, int value)
 {
-       uint32_t rv = gpio_read(arg, offset);
-       uint32_t mask = GPIO_SBIT(addr);
+       struct gpio_opb_softc *sc = arg;
+       u_int32_t data;
+       int p;
+
+       p = pin % GPIO_NPINS;
+       p = p + 1;
+
+       data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_OR);
+       if (value == 0) {
+               data &= ~(1 << GPIO_PIN_SHIFT(p));
+       } else if (value == 1) {
+               data |= (1 << GPIO_PIN_SHIFT(p));
+       }
 
-       rv = rv & ~mask;
-       rv = rv | ((bit << GPIO_SHIFT(addr)) & mask);
-       gpio_write(arg, offset, rv);
+       bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GPIO_OR, data);
 }
 
-static uint32_t
-gpio_read(void *arg, int offset)
-{
-       struct gpio_softc *sc = arg;
-       uint32_t rv;
-
-        rv = inl(sc->sc_addr + offset);
-
-       return rv;
-}
-
-static void
-gpio_write(void *arg, int offset, uint32_t out)
+void
+gpio_opb_pin_ctl(void *arg, int pin, int flags)
 {
-       struct gpio_softc *sc = arg;
-
-        outl((sc->sc_addr + offset), out);
+       struct gpio_opb_softc *sc = arg;
+       u_int32_t data;
+       int p;
+
+       p = pin % GPIO_NPINS;
+       p = p + 1;
+
+       if (flags & GPIO_PIN_INOUT) {
+               /* GPIOn_ODR register bit is 0 */
+               data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR);
+               data &= ~(1 << GPIO_PIN_SHIFT(p));
+               bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR, data);
+               /* GPIOn_TCR register bit is 1 */
+               data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_TCR);
+               data |= (1 << GPIO_PIN_SHIFT(p));
+               bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_TCR, data);
+       }
+
+       if (flags & GPIO_PIN_TRISTATE) {
+               /* GPIOn_ODR register bit is 0 */
+               data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR);
+               data &= ~(1 << GPIO_PIN_SHIFT(p));
+               bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR, data);
+               /* GPIOn_TCR register bit is 0 */
+               data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_TCR);
+               data &= ~(1 << GPIO_PIN_SHIFT(p));
+               bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_TCR, data);
+       }
+
+       if (flags & GPIO_PIN_OPENDRAIN) {
+               /* GPIOn_ODR register bit is 1 */
+               data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR);
+               data |= (1 << GPIO_PIN_SHIFT(p));
+               bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh,
+                                       GPIO_ODR, data);
+       }
 }
Index: sys/arch/powerpc/ibm4xx/dev/gpioreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/dev/gpioreg.h,v
retrieving revision 1.2
diff -u -u -r1.2 gpioreg.h
--- sys/arch/powerpc/ibm4xx/dev/gpioreg.h       23 Jan 2005 19:22:22 -0000      
1.2
+++ sys/arch/powerpc/ibm4xx/dev/gpioreg.h       1 Oct 2005 16:12:52 -0000
@@ -52,11 +52,13 @@
  *     1       1       0       X       0       Forced to high impedance state
  */
 
+/* GPIO pins */
+#define GPIO_NPINS             (24)
+
 /* GPIO Registers 0x00-0x7f */
 #define GPIO_NREG              (0x80)
 
-#define GPIO_SHIFT(n)          (31 - n)
-#define GPIO_SBIT(n)           (1 << GPIO_SHIFT(n))
+#define GPIO_PIN_SHIFT(n)      (31 - n)
 
 /* Offset */
 #define        GPIO_OR                 (0x00)  /* Output */
Index: sys/arch/powerpc/ibm4xx/dev/opb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/dev/opb.c,v
retrieving revision 1.20
diff -u -u -r1.20 opb.c
--- sys/arch/powerpc/ibm4xx/dev/opb.c   26 Aug 2005 13:19:37 -0000      1.20
+++ sys/arch/powerpc/ibm4xx/dev/opb.c   1 Oct 2005 16:12:52 -0000
@@ -93,7 +93,7 @@
        { IBM405GP,     "com",  IBM405GP_UART0_BASE,     0 },
        { IBM405GP,     "com",  IBM405GP_UART1_BASE,     1 },
        { IBM405GP,     "emac", IBM405GP_EMAC0_BASE,     9 }, /* XXX: really 
irq 9..15 */
-       { IBM405GP,     "gpio", IBM405GP_GPIO0_BASE,    -1 },
+       { IBM405GP,     "gpio_opb",IBM405GP_GPIO0_BASE, -1 },
        { IBM405GP,     "gpiic",IBM405GP_IIC0_BASE,      2 },
        { IBM405GP,     "wdog", -1,                     -1 },
 
@@ -101,7 +101,7 @@
        { IBM405GPR,    "com",  IBM405GP_UART0_BASE,     0 },
        { IBM405GPR,    "com",  IBM405GP_UART1_BASE,     1 },
        { IBM405GPR,    "emac", IBM405GP_EMAC0_BASE,     9 }, /* XXX: really 
irq 9..15 */
-       { IBM405GPR,    "gpio", IBM405GP_GPIO0_BASE,    -1 },
+       { IBM405GPR,    "gpio_opb",IBM405GP_GPIO0_BASE, -1 },
        { IBM405GPR,    "gpiic",IBM405GP_IIC0_BASE,      2 },
        { IBM405GPR,    "wdog", -1,                     -1 },
        { 0,             NULL }
@@ -127,7 +127,7 @@
     opb_match, opb_attach, NULL, NULL);
 
 static struct powerpc_bus_space opb_tag = {
-       _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
+       _BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE,
        0x0, IBM405GP_UART0_BASE, 0x1000
 };
 static char ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)]


Home | Main Index | Thread Index | Old Index