summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/arch-mpc85xx/gpio.h8
-rw-r--r--arch/powerpc/include/asm/immap_85xx.h10
-rw-r--r--arch/powerpc/include/asm/mpc8xxx_gpio.h100
-rw-r--r--drivers/gpio/Kconfig9
-rw-r--r--drivers/gpio/Makefile4
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c178
-rw-r--r--include/dm/platform_data/gpio_mpc8xxx.h21
7 files changed, 330 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
index 76faa22..0c72c71 100644
--- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
@@ -14,6 +14,7 @@
#ifndef __ASM_ARCH_MX85XX_GPIO_H
#define __ASM_ARCH_MX85XX_GPIO_H
+<<<<<<< bc5d0384458466ed5b3608d326eec03cd4f13016
#ifndef CONFIG_MPC85XX_GPIO
#include <asm/mpc85xx_gpio.h>
#endif
@@ -23,5 +24,12 @@ struct mpc85xx_gpio_plat {
unsigned long size;
uint ngpios;
};
+=======
+#ifdef CONFIG_MPC8XXX_GPIO
+#include <asm/mpc8xxx_gpio.h>
+#else
+#include <asm/mpc85xx_gpio.h>
+#endif
+>>>>>>> dm: gpio: Add DM GPIO driver for MPC8xxx platforms
#endif
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index ee537f4..184ff5a 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -3200,4 +3200,14 @@ struct ccsr_scfg {
u32 res4[60];
u32 sparecr[8]; /* 0x500 Spare Control register(0-7) */
};
+
+#if defined(CONFIG_PPC_T1013) || defined(CONFIG_PPC_T1014) ||\
+ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) ||\
+ defined(CONFIG_PPC_T1023) || defined(CONFIG_PPC_T1024) ||\
+ defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042) ||\
+#define CONFIG_SYS_MPC8XXX_GPIO1_ADDR (CONFIG_SYS_IMMR + 0x130000)
+#define CONFIG_SYS_MPC8XXX_GPIO2_ADDR (CONFIG_SYS_IMMR + 0x131000)
+#define CONFIG_SYS_MPC8XXX_GPIO3_ADDR (CONFIG_SYS_IMMR + 0x132000)
+#define CONFIG_SYS_MPC8XXX_GPIO4_ADDR (CONFIG_SYS_IMMR + 0x133000)
+#endif
#endif /*__IMMAP_85xx__*/
diff --git a/arch/powerpc/include/asm/mpc8xxx_gpio.h b/arch/powerpc/include/asm/mpc8xxx_gpio.h
new file mode 100644
index 0000000..d4a5b7c
--- /dev/null
+++ b/arch/powerpc/include/asm/mpc8xxx_gpio.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Scalys B.V. <u-boot@scalys.com>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _POWERPC_ASM_MPC8XXX_GPIO_H
+#define _POWERPC_ASM_MPC8XXX_GPIO_H
+
+#define MPC8XXX_GPIO_NR(port, pin) ((((port)-1)*32)+((pin)&31))
+#define MPC8XXX_GPIO_TO_PORT(gpio) (gpio/32)
+#define MPC8XXX_GPIO_TO_PIN(gpio) (gpio&31)
+
+static inline void mpc8xxx_gpio_set(uint32_t gpio, int value)
+{
+ int port, pin;
+ ccsr_gpio_t *gpio_regs;
+ uint32_t regval;
+
+ port = MPC8XXX_GPIO_TO_PORT(gpio);
+ pin = MPC8XXX_GPIO_TO_PIN(gpio);
+
+ switch (port) {
+#ifdef CONFIG_SYS_MPC8XXX_GPIO1_ADDR
+ case 0:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO1_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO2_ADDR
+ case 1:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO2_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO3_ADDR
+ case 2:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO3_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO4_ADDR
+ case 3:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO4_ADDR;
+ break;
+#endif
+ default:
+ return;
+ }
+
+ /* Set output */
+ regval = in_be32(&(gpio_regs->gpdat));
+ regval |= (0x80000000 >> pin);
+ out_be32(&(gpio_regs->gpdat), regval);
+
+ /* Set direction to acivate gpio pin */
+ regval = in_be32(&(gpio_regs->gpdir));
+ regval |= (0x80000000 >> pin);
+ out_be32(&(gpio_regs->gpdir), regval);
+}
+
+static inline int mpc8xxx_gpio_get(uint32_t gpio, int value)
+{
+ int port, pin;
+ ccsr_gpio_t *gpio_regs;
+ uint32_t regval;
+
+ port = MPC8XXX_GPIO_TO_PORT(gpio);
+ pin = MPC8XXX_GPIO_TO_PIN(gpio);
+
+ switch (port) {
+#ifdef CONFIG_SYS_MPC8XXX_GPIO1_ADDR
+ case 0:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO1_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO2_ADDR
+ case 1:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO2_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO3_ADDR
+ case 2:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO3_ADDR;
+ break;
+#endif
+#ifdef CONFIG_SYS_MPC8XXX_GPIO4_ADDR
+ case 3:
+ gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO4_ADDR;
+ break;
+#endif
+ default:
+ return;
+ }
+
+ /* Get inputs */
+ regval = in_be32(&(gpio_regs->gpdat));
+ regval <<= pin;
+ regval &= 1;
+
+ return regval;
+}
+
+#endif /* _POWERPC_ASM_MPC8XXX_GPIO_H */
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ffeda94..34c4a40 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -34,6 +34,7 @@ config DWAPB_GPIO
help
Support for the Designware APB GPIO driver.
+<<<<<<< bc5d0384458466ed5b3608d326eec03cd4f13016
config AT91_GPIO
bool "AT91 PIO GPIO driver"
depends on DM_GPIO
@@ -46,6 +47,14 @@ config AT91_GPIO
The assignment to a function of an embedded peripheral is
the responsibility of AT91 Pinctrl driver. This driver is
responsible for the general-purpose I/O.
+=======
+config MPC8XXX_GPIO
+ bool "NXP (Freescale) MPC8xxx driver"
+ depends on DM_GPIO
+ default n
+ help
+ Support for the NXP (Freescale) MPC/QorIQ GPIO controller
+>>>>>>> dm: gpio: Add DM GPIO driver for MPC8xxx platforms
config ATMEL_PIO4
bool "ATMEL PIO4 driver"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1396467..3209071 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -37,7 +37,11 @@ obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o
obj-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o
obj-$(CONFIG_ALTERA_PIO) += altera_pio.o
obj-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o
+<<<<<<< bc5d0384458466ed5b3608d326eec03cd4f13016
obj-$(CONFIG_MPC85XX_GPIO) += mpc85xx_gpio.o
+=======
+obj-$(CONFIG_MPC8XXX_GPIO) += gpio-mpc8xxx.o
+>>>>>>> dm: gpio: Add DM GPIO driver for MPC8xxx platforms
obj-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o
obj-$(CONFIG_OMAP_GPIO) += omap_gpio.o
obj-$(CONFIG_DB8500_GPIO) += db8500_gpio.o
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
new file mode 100644
index 0000000..c5d72ef
--- /dev/null
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -0,0 +1,178 @@
+
+/*
+ * GPIOs on MPC512x/8349/8572/8610/T-series and compatible
+ *
+ * Driver ported from the linux kernel 4.5 (b562e44f507e863c6792946e4e1b1449fbbac85d)
+ * and removed the interrupt functionallity.
+ *
+ * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
+ * Copyright (c) 2016 Scalys B.V. <u-boot@scalys.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <dm/platform_data/gpio_mpc8xxx.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MPC8XXX_GPIO_PINS 32
+
+static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
+{
+ return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
+}
+
+static int mpc8xxx_dm_gpio_set(struct udevice *dev, unsigned pin, int val)
+{
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536)
+
+ if (val) {
+ plat->data |= mpc8xxx_gpio2mask(pin);
+ } else {
+ plat->data &= ~mpc8xxx_gpio2mask(pin);
+ }
+
+ out_be32(&(plat->regs->gpdat), plat->data);
+#else
+ if (val) {
+ setbits_be32(&(plat->regs->gpdat), mpc8xxx_gpio2mask(pin));
+ } else {
+ clrbits_be32(&(plat->regs->gpdat), mpc8xxx_gpio2mask(pin));
+ }
+#endif
+ return 0;
+}
+
+static int mpc8xxx_dm_gpio_dir_in(struct udevice *dev, unsigned int gpio)
+{
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+ clrbits_be32(&(plat->regs->gpdir), mpc8xxx_gpio2mask(gpio));
+
+ return 0;
+}
+
+static int mpc8xxx_dm_gpio_dir_out(struct udevice *dev, unsigned int gpio,
+ int val)
+{
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+ mpc8xxx_dm_gpio_set(dev, gpio, val);
+
+ setbits_be32(&(plat->regs->gpdir), mpc8xxx_gpio2mask(gpio));
+
+ return 0;
+}
+
+static int mpc8xxx_dm_gpio_get(struct udevice *dev, unsigned int gpio)
+{
+ int ret = 0;
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536)
+ uint32_t data_val, out_mask, out_shadow;
+
+ /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
+ * defined as output cannot be determined by reading GPDAT register,
+ * so we use shadow data register instead. The status of input pins
+ * is determined by reading GPDAT register.
+ */
+ out_mask = in_be32(&plat->regs->gpdir);
+
+ data_val = in_be32(&plat->regs->gpdat) & ~out_mask;
+ out_shadow = plat->data & out_mask;
+
+ ret = ! !((data_val | out_shadow) & mpc8xxx_gpio2mask(gpio));
+#else
+ if (in_be32(&plat->regs->gpdat) & mpc8xxx_gpio2mask(gpio)) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+#endif
+ return ret;
+}
+
+static int mpc8xxx_dm_gpio_get_function(struct udevice *dev, unsigned gpio)
+{
+ int ret = GPIOF_UNUSED;
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+ if (in_be32(&plat->regs->gpdir) & mpc8xxx_gpio2mask(gpio)) {
+ ret = GPIOF_OUTPUT;
+ } else {
+ ret = GPIOF_INPUT;
+ }
+ return ret;
+}
+
+static const struct udevice_id mpc8xxx_gpio_ids[] = {
+ {.compatible = "fsl,mpc8349-gpio",},
+ {.compatible = "fsl,mpc8572-gpio",},
+ {.compatible = "fsl,mpc8610-gpio",},
+ {.compatible = "fsl,mpc5121-gpio",},
+ {.compatible = "fsl,mpc5125-gpio",},
+ {.compatible = "fsl,pq3-gpio",},
+ {.compatible = "fsl,qoriq-gpio",},
+ {}
+};
+
+static const struct dm_gpio_ops mpc8xxx_gpio_ops = {
+ .direction_input = mpc8xxx_dm_gpio_dir_in,
+ .direction_output = mpc8xxx_dm_gpio_dir_out,
+ .get_value = mpc8xxx_dm_gpio_get,
+ .set_value = mpc8xxx_dm_gpio_set,
+ .get_function = mpc8xxx_dm_gpio_get_function,
+};
+
+#ifdef SPL_OF_CONTROL
+static int mpc8xxx_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+ int register_address;
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+ register_address =
+ fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+ if (register_address == -1) {
+ debug("%s: Invalid register offset %d\n", __func__,
+ register_address);
+ return -EINVAL;
+ }
+ plat->regs = map_physmem(register_address, sizeof(ccsr_gpio_t),
+ MAP_NOCACHE);
+ plat->gpio_count = MPC8XXX_GPIO_PINS;
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "bank-name", NULL);
+
+ return 0;
+}
+#endif
+
+static int mpc8xxx_gpio_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev);
+
+ uc_priv->gpio_count = MPC8XXX_GPIO_PINS;
+ uc_priv->bank_name = plat->bank_name;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(gpio_mpc8xxx) = {
+ .name = "gpio-mpc8xxx",.id = UCLASS_GPIO,.of_match =
+ mpc8xxx_gpio_ids,.ops = &mpc8xxx_gpio_ops,
+#ifdef SPL_OF_CONTROL
+ .ofdata_to_platdata = mpc8xxx_gpio_ofdata_to_platdata,
+#endif
+.platdata_auto_alloc_size =
+ sizeof(struct mpc8xxx_gpio_platdata),.probe = mpc8xxx_gpio_probe,};
diff --git a/include/dm/platform_data/gpio_mpc8xxx.h b/include/dm/platform_data/gpio_mpc8xxx.h
new file mode 100644
index 0000000..37e5241
--- /dev/null
+++ b/include/dm/platform_data/gpio_mpc8xxx.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016 Scalys B.V. <u-boot@scalys.com>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MPC8XXX_GPIO_H
+#define _MPC8XXX_GPIO_H
+
+struct mpc8xxx_gpio_platdata {
+ const char *bank_name;
+ ccsr_gpio_t *regs;
+ int gpio_count;
+#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536)
+ /* shadowed data register used to work around errata on
+ * MPC8572 and MPC8535 where it is not possible to read the
+ * state of an output pin */
+ uint32_t data;
+#endif
+};
+
+#endif