From patchwork Wed May 20 10:40:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Song X-Patchwork-Id: 246108 List-Id: U-Boot discussion From: hui.song_1 at nxp.com (Hui Song) Date: Wed, 20 May 2020 18:40:18 +0800 Subject: [PATCH 1/3] armv8: gpio: add gpio feature Message-ID: <20200520104020.9013-1-hui.song_1@nxp.com> From: "hui.song" add one struct mpc8xxx_gpio_plat to enable gpio feature. Signed-off-by: hui.song --- .../include/asm/arch-fsl-layerscape/gpio.h | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 arch/arm/include/asm/arch-fsl-layerscape/gpio.h diff --git a/arch/arm/include/asm/arch-fsl-layerscape/gpio.h b/arch/arm/include/asm/arch-fsl-layerscape/gpio.h new file mode 100644 index 0000000000..7ae5eee8b6 --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-layerscape/gpio.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 NXP + */ + +/* + * Dummy header file to enable CONFIG_OF_CONTROL. + * If CONFIG_OF_CONTROL is enabled, lib/fdtdec.c is compiled. + * It includes via , so those SoCs that enable + * OF_CONTROL must have arch/gpio.h. + */ + +#ifndef __ASM_ARCH_MX85XX_GPIO_H +#define __ASM_ARCH_MX85XX_GPIO_H + +struct mpc8xxx_gpio_plat { + ulong addr; + ulong size; + uint ngpios; +}; + +#endif From patchwork Wed May 20 10:40:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Song X-Patchwork-Id: 246109 List-Id: U-Boot discussion From: hui.song_1 at nxp.com (Hui Song) Date: Wed, 20 May 2020 18:40:19 +0800 Subject: [PATCH 2/3] dm: armv8: gpio: include for fsl-layerscape In-Reply-To: <20200520104020.9013-1-hui.song_1@nxp.com> References: <20200520104020.9013-1-hui.song_1@nxp.com> Message-ID: <20200520104020.9013-2-hui.song_1@nxp.com> From: "hui.song" Enable the gpio feature on fsl-layerscape platform. Signed-off-by: hui.song --- arch/arm/include/asm/gpio.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 333e407b66..7715a01706 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -1,12 +1,8 @@ #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \ !defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM68360) && \ !defined(CONFIG_ARCH_BCM6858) && !defined(CONFIG_ARCH_BCM63158) && \ - !defined(CONFIG_ARCH_ROCKCHIP) && !defined(CONFIG_ARCH_LX2160A) && \ - !defined(CONFIG_ARCH_LS1028A) && !defined(CONFIG_ARCH_LS2080A) && \ - !defined(CONFIG_ARCH_LS1088A) && !defined(CONFIG_ARCH_ASPEED) && \ - !defined(CONFIG_ARCH_LS1012A) && !defined(CONFIG_ARCH_LS1043A) && \ - !defined(CONFIG_ARCH_LS1046A) && !defined(CONFIG_ARCH_U8500) && \ - !defined(CONFIG_CORTINA_PLATFORM) + !defined(CONFIG_ARCH_ROCKCHIP) && !defined(CONFIG_ARCH_ASPEED) && \ + !defined(CONFIG_ARCH_U8500) && !defined(CONFIG_CORTINA_PLATFORM) #include #endif #include From patchwork Wed May 20 10:40:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Song X-Patchwork-Id: 246110 List-Id: U-Boot discussion From: hui.song_1 at nxp.com (Hui Song) Date: Wed, 20 May 2020 18:40:20 +0800 Subject: [PATCH 3/3] gpio: mpc8xxx: support fsl-layerscape platform. In-Reply-To: <20200520104020.9013-1-hui.song_1@nxp.com> References: <20200520104020.9013-1-hui.song_1@nxp.com> Message-ID: <20200520104020.9013-3-hui.song_1@nxp.com> From: "hui.song" Make the MPC8XXX gpio driver to support the fsl-layerscape. Signed-off-by: hui.song --- drivers/gpio/mpc8xxx_gpio.c | 108 +++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 21 deletions(-) diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c index 1dfd22522c..41bd2f8374 100644 --- a/drivers/gpio/mpc8xxx_gpio.c +++ b/drivers/gpio/mpc8xxx_gpio.c @@ -6,12 +6,15 @@ * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is * * Copyright 2010 eXMeritus, A Boeing Company + * Copyright 2020 NXP */ #include #include #include #include +#include +#include struct ccsr_gpio { u32 gpdir; @@ -20,6 +23,7 @@ struct ccsr_gpio { u32 gpier; u32 gpimr; u32 gpicr; + u32 gpibe; }; struct mpc8xxx_gpio_data { @@ -35,6 +39,7 @@ struct mpc8xxx_gpio_data { */ u32 dat_shadow; ulong type; + bool little_endian; }; enum { @@ -47,33 +52,56 @@ inline u32 gpio_mask(uint gpio) return (1U << (31 - (gpio))); } -static inline u32 mpc8xxx_gpio_get_val(struct ccsr_gpio *base, u32 mask) +static inline u32 mpc8xxx_gpio_get_val(struct udevice *dev, u32 mask) { - return in_be32(&base->gpdat) & mask; + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); + + if (data->little_endian) + return in_le32(&data->base->gpdat) & mask; + else + return in_be32(&data->base->gpdat) & mask; } -static inline u32 mpc8xxx_gpio_get_dir(struct ccsr_gpio *base, u32 mask) +static inline u32 mpc8xxx_gpio_get_dir(struct udevice *dev, u32 mask) { - return in_be32(&base->gpdir) & mask; + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); + + if (data->little_endian) + return in_le32(&data->base->gpdir) & mask; + else + return in_be32(&data->base->gpdir) & mask; } -static inline int mpc8xxx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask) +static inline int mpc8xxx_gpio_open_drain_val(struct udevice *dev, u32 mask) { - return in_be32(&base->gpodr) & mask; + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); + + if (data->little_endian) + return in_le32(&data->base->gpodr) & mask; + else + return in_be32(&data->base->gpodr) & mask; } -static inline void mpc8xxx_gpio_open_drain_on(struct ccsr_gpio *base, u32 +static inline void mpc8xxx_gpio_open_drain_on(struct udevice *dev, u32 gpios) { + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); /* GPODR register 1 -> open drain on */ - setbits_be32(&base->gpodr, gpios); + if (data->little_endian) + setbits_le32(&data->base->gpodr, gpios); + else + setbits_be32(&data->base->gpodr, gpios); } -static inline void mpc8xxx_gpio_open_drain_off(struct ccsr_gpio *base, +static inline void mpc8xxx_gpio_open_drain_off(struct udevice *dev, u32 gpios) { + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); /* GPODR register 0 -> open drain off (actively driven) */ - clrbits_be32(&base->gpodr, gpios); + if (data->little_endian) + clrbits_le32(&data->base->gpodr, gpios); + else + clrbits_be32(&data->base->gpodr, gpios); } static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio) @@ -82,7 +110,10 @@ static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio) u32 mask = gpio_mask(gpio); /* GPDIR register 0 -> input */ - clrbits_be32(&data->base->gpdir, mask); + if (data->little_endian) + clrbits_le32(&data->base->gpdir, mask); + else + clrbits_be32(&data->base->gpdir, mask); return 0; } @@ -100,10 +131,20 @@ static int mpc8xxx_gpio_set_value(struct udevice *dev, uint gpio, int value) data->dat_shadow &= ~mask; } - gpdir = in_be32(&base->gpdir); + if (data->little_endian) + gpdir = in_le32(&base->gpdir); + else + gpdir = in_be32(&base->gpdir); + gpdir |= gpio_mask(gpio); - out_be32(&base->gpdat, gpdir & data->dat_shadow); - out_be32(&base->gpdir, gpdir); + + if (data->little_endian) { + out_le32(&base->gpdat, gpdir & data->dat_shadow); + out_le32(&base->gpdir, gpdir); + } else { + out_be32(&base->gpdat, gpdir & data->dat_shadow); + out_be32(&base->gpdir, gpdir); + } return 0; } @@ -124,21 +165,20 @@ static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio) { struct mpc8xxx_gpio_data *data = dev_get_priv(dev); - if (!!mpc8xxx_gpio_get_dir(data->base, gpio_mask(gpio))) { + if (!!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio))) { /* Output -> use shadowed value */ return !!(data->dat_shadow & gpio_mask(gpio)); } /* Input -> read value from GPDAT register */ - return !!mpc8xxx_gpio_get_val(data->base, gpio_mask(gpio)); + return !!mpc8xxx_gpio_get_val(dev, gpio_mask(gpio)); } static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio) { - struct mpc8xxx_gpio_data *data = dev_get_priv(dev); int dir; - dir = !!mpc8xxx_gpio_get_dir(data->base, gpio_mask(gpio)); + dir = !!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio)); return dir ? GPIOF_OUTPUT : GPIOF_INPUT; } @@ -146,14 +186,33 @@ static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio) static int mpc8xxx_gpio_ofdata_to_platdata(struct udevice *dev) { struct mpc8xxx_gpio_plat *plat = dev_get_platdata(dev); + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); fdt_addr_t addr; - u32 reg[2]; + u32 i; + u32 reg[4]; + + if (ofnode_read_bool(dev->node, "little-endian")) + data->little_endian = true; + + if (data->little_endian) + dev_read_u32_array(dev, "reg", reg, 4); + else + dev_read_u32_array(dev, "reg", reg, 2); + + if (data->little_endian) { + for (i = 0; i < 2; i++) + reg[i] = be32_to_cpu(reg[i]); + } - dev_read_u32_array(dev, "reg", reg, 2); addr = dev_translate_address(dev, reg); plat->addr = addr; - plat->size = reg[1]; + + if (data->little_endian) + plat->size = reg[3]; + else + plat->size = reg[1]; + plat->ngpios = dev_read_u32_default(dev, "ngpios", 32); return 0; @@ -198,6 +257,13 @@ static int mpc8xxx_gpio_probe(struct udevice *dev) if (!str) return -ENOMEM; + if (ofnode_device_is_compatible(dev->node, "fsl,qoriq-gpio")) { + unsigned long gpibe = data->addr + sizeof(struct ccsr_gpio) + - sizeof(u32); + + out_be32(gpibe, 0xffffffff); + } + uc_priv->bank_name = str; uc_priv->gpio_count = data->gpio_count;