All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tim Harvey <tharvey@gateworks.com>
To: u-boot@lists.denx.de
Subject: [U-Boot]  [RFC 11/22] gpio: add thunderx gpio driver
Date: Fri, 22 Feb 2019 10:03:08 -0800	[thread overview]
Message-ID: <20190222180319.32221-12-tharvey@gateworks.com> (raw)
In-Reply-To: <20190222180319.32221-1-tharvey@gateworks.com>

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 configs/thunderx_81xx_defconfig |   4 +
 drivers/gpio/Kconfig            |   7 ++
 drivers/gpio/Makefile           |   1 +
 drivers/gpio/thunderx_gpio.c    | 189 ++++++++++++++++++++++++++++++++
 4 files changed, 201 insertions(+)
 create mode 100644 drivers/gpio/thunderx_gpio.c

diff --git a/configs/thunderx_81xx_defconfig b/configs/thunderx_81xx_defconfig
index 3ec7d6cd4f..d07b0e5804 100644
--- a/configs/thunderx_81xx_defconfig
+++ b/configs/thunderx_81xx_defconfig
@@ -21,10 +21,14 @@ CONFIG_SYS_PROMPT="ThunderX_81XX> "
 # CONFIG_CMD_SAVEENV is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
 CONFIG_CMD_PCI=y
 # CONFIG_CMD_NET is not set
 CONFIG_DEFAULT_DEVICE_TREE="thunderx-81xx"
 CONFIG_DM=y
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
 # CONFIG_MMC is not set
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5cd8b34400..b34f66969a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -238,6 +238,13 @@ config PIC32_GPIO
 	help
 	  Say yes here to support Microchip PIC32 GPIOs.
 
+config THUNDERX_GPIO
+	bool "Cavium ThunderX GPIO driver"
+	depends on DM_GPIO
+	default y
+	help
+	  Say yes here to support Cavium ThunderX GPIOs.
+
 config STM32F7_GPIO
 	bool "ST STM32 GPIO driver"
 	depends on DM_GPIO && (STM32 || ARCH_STM32MP)
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f186120684..4c22c5f1d2 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_HIKEY_GPIO)	+= hi6220_gpio.o
 obj-$(CONFIG_HSDK_CREG_GPIO)	+= hsdk-creg-gpio.o
 obj-$(CONFIG_IMX_RGPIO2P)	+= imx_rgpio2p.o
 obj-$(CONFIG_PIC32_GPIO)	+= pic32_gpio.o
+obj-$(CONFIG_THUNDERX_GPIO)	+= thunderx_gpio.o
 obj-$(CONFIG_MVEBU_GPIO)	+= mvebu_gpio.o
 obj-$(CONFIG_MSM_GPIO)		+= msm_gpio.o
 obj-$(CONFIG_$(SPL_)PCF8575_GPIO)	+= pcf8575_gpio.o
diff --git a/drivers/gpio/thunderx_gpio.c b/drivers/gpio/thunderx_gpio.c
new file mode 100644
index 0000000000..5d38ddccdd
--- /dev/null
+++ b/drivers/gpio/thunderx_gpio.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier:	GPL-2.0+
+/*
+ * Copyright (C) 2018, Cavium Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/bitops.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/* Returns the bit value to write or read based on the offset */
+#define GPIO_BIT(x)		(1ULL << ((x) & 0x3f))
+
+#define GPIO_RX_DAT		(0x0)
+#define GPIO_TX_SET		(0x8)
+#define GPIO_TX_CLR		(0x10)
+#define GPIO_CONST		(0x90)
+#define GPIO_RX1_DAT		(0x1400)
+#define GPIO_TX1_SET		(0x1408)
+#define GPIO_TX1_CLR		(0x1410)
+
+/** Returns the offset to the output register based on the offset and value */
+#define GPIO_TX_REG(offset, value)					\
+	((offset) >= 64 ? ((value) ? GPIO_TX1_SET : GPIO_TX1_CLR) :	\
+			  ((value) ? GPIO_TX_SET : GPIO_TX_CLR))
+
+/** Returns the offset to the input data register based on the offset */
+#define GPIO_RX_DAT_REG(offset) ((offset >= 64) ? GPIO_RX1_DAT : GPIO_RX_DAT)
+
+/** Returns the bit configuration register based on the offset */
+#define GPIO_BIT_CFG(x)		(0x400 + 8 * (x))
+#define GPIO_BIT_CFG_FN(x)	(((x) >> 16) & 0x3ff)
+#define GPIO_BIT_CFG_TX_OE(x)	((x) & 0x1)
+#define GPIO_BIT_CFG_RX_DAT(x)	((x) & 0x1)
+
+union gpio_const {
+	u64 u;
+	struct {
+		u64 gpios:8;	/** Number of GPIOs implemented */
+		u64 pp:8;	/** Number of PP vectors */
+		u64:48;	/* Reserved */
+	} s;
+};
+
+struct thunderx_gpio {
+	void __iomem *baseaddr;
+};
+
+static int thunderx_gpio_dir_input(struct udevice *dev, unsigned offset)
+{
+	struct thunderx_gpio *gpio = dev_get_priv(dev);
+	dev_dbg(dev, "%s: offset=%u\n", __func__, offset);
+	clrbits_le64(gpio->baseaddr + GPIO_BIT_CFG(offset),
+		     (0x3ffUL << 16) | 4UL | 1UL);
+	return 0;
+}
+
+static int thunderx_gpio_dir_output(struct udevice *dev, unsigned offset,
+				    int value)
+{
+	struct thunderx_gpio *gpio = dev_get_priv(dev);
+
+	dev_dbg(dev, "%s: offset=%u value=%d\n", __func__, offset, value);
+	writeq(GPIO_BIT(offset), gpio->baseaddr + GPIO_TX_REG(offset, value));
+
+	clrsetbits_le64(gpio->baseaddr + GPIO_BIT_CFG(offset),
+			((0x3ffUL << 16) | 4UL), 1UL);
+	return 0;
+}
+
+static int thunderx_gpio_get_value(struct udevice *dev,
+				   unsigned offset)
+{
+	struct thunderx_gpio *gpio = dev_get_priv(dev);
+	u64 reg = readq(gpio->baseaddr + GPIO_RX_DAT_REG(offset));
+
+	dev_dbg(dev, "%s: offset=%u value=%d\n", __func__, offset,
+	      !!(reg & GPIO_BIT(offset)));
+
+	return !!(reg & GPIO_BIT(offset));
+}
+
+static int thunderx_gpio_set_value(struct udevice *dev,
+				   unsigned offset, int value)
+{
+	struct thunderx_gpio *gpio = dev_get_priv(dev);
+
+	dev_dbg(dev, "%s: offset=%u value=%d\n", __func__, offset, value);
+	writeq(GPIO_BIT(offset), gpio->baseaddr + GPIO_TX_REG(offset, value));
+
+	return 0;
+
+}
+
+static int thunderx_gpio_get_function(struct udevice *dev,
+				      unsigned offset)
+{
+	struct thunderx_gpio *gpio = dev_get_priv(dev);
+	u64 pinsel = readl(gpio->baseaddr + GPIO_BIT_CFG(offset));
+
+	dev_dbg(dev, "%s: offset=%u pinsel:0x%llx\n", __func__, offset, pinsel);
+	if (GPIO_BIT_CFG_FN(pinsel))
+		return GPIOF_FUNC;
+	else if (GPIO_BIT_CFG_TX_OE(pinsel))
+		return GPIOF_OUTPUT;
+	else
+		return GPIOF_INPUT;
+}
+
+static int thunderx_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+			    struct ofnode_phandle_args *args)
+{
+	if (args->args_count < 1)
+		return -EINVAL;
+
+	desc->offset = args->args[0];
+	desc->flags = 0;
+	if (args->args_count > 1) {
+		if (args->args[1] & GPIO_ACTIVE_LOW)
+			desc->flags |= GPIOD_ACTIVE_LOW;
+		/* In the future add tri-state flag support */
+	}
+	return 0;
+}
+
+static const struct dm_gpio_ops thunderx_gpio_ops = {
+	.direction_input	= thunderx_gpio_dir_input,
+	.direction_output	= thunderx_gpio_dir_output,
+	.get_value		= thunderx_gpio_get_value,
+	.set_value		= thunderx_gpio_set_value,
+	.get_function		= thunderx_gpio_get_function,
+	.xlate			= thunderx_gpio_xlate,
+};
+
+static int thunderx_pci_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct thunderx_gpio *priv = dev_get_priv(dev);
+	pci_dev_t bdf = dm_pci_get_bdf(dev);
+	union gpio_const gpio_const;
+	size_t size;
+
+	dev->req_seq = PCI_FUNC(bdf);
+	priv->baseaddr = dm_pci_map_bar(dev, 0, &size, PCI_REGION_MEM);
+	if (!priv->baseaddr) {
+		dev_err(dev, "%s: Could not get base address\n", __func__);
+		return -EINVAL;
+	}
+
+	gpio_const.u = readq(priv->baseaddr + GPIO_CONST);
+
+	dev_dbg(dev, "%s: base address:%p of_offset:%ld pin count: %d\n",
+	      __func__, priv->baseaddr, dev->node.of_offset,
+	      gpio_const.s.gpios);
+
+	uc_priv->gpio_count = gpio_const.s.gpios;
+	uc_priv->bank_name  = strdup(dev->name);
+
+	return 0;
+}
+
+static const struct udevice_id thunderx_gpio_ids[] = {
+	{ .compatible = "cavium,thunder-8890-gpio" },
+	{ .compatible = "cavium,gpio" },
+	{ .compatible = "cavium,thunderx-gpio" },
+	{ }
+};
+
+U_BOOT_DRIVER(thunderx_pci_gpio) = {
+	.name	= "gpio_thunderx",
+	.id	= UCLASS_GPIO,
+	.of_match = of_match_ptr(thunderx_gpio_ids),
+	.probe = thunderx_pci_gpio_probe,
+	.priv_auto_alloc_size = sizeof(struct thunderx_gpio),
+	.ops	= &thunderx_gpio_ops,
+};
+
+static struct pci_device_id thunderx_pci_gpio_supported[] = {
+	{ PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_THUNDERX_GPIO) },
+	{ },
+};
+
+U_BOOT_PCI_DEVICE(thunderx_pci_gpio, thunderx_pci_gpio_supported);
+
-- 
2.17.1

  parent reply	other threads:[~2019-02-22 18:03 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22 18:02 [U-Boot] [RFC 00/22] Add support for Cavium Octeon-TX CN80XX/CN81XX Tim Harvey
2019-02-22 18:02 ` [U-Boot] [RFC 01/22] arm: introduce ARCH_THUNDERX Tim Harvey
2019-02-24 16:08   ` Alexander Graf
2019-02-24 16:13   ` Alexander Graf
2019-02-22 18:02 ` [U-Boot] [RFC 02/22] arm: add thunderx_81xx Tim Harvey
2019-02-24 16:35   ` Alexander Graf
2019-02-22 18:03 ` [U-Boot] [RFC 03/22] thunderx: add FDT support Tim Harvey
2019-02-24 16:39   ` Alexander Graf
2019-02-22 18:03 ` [U-Boot] [RFC 04/22] thunderx: add thunderx register definitions and misc functions Tim Harvey
2019-02-24 16:42   ` Alexander Graf
2019-02-22 18:03 ` [U-Boot] [RFC 05/22] thunderx: move DRAM prints to debug Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 06/22] dm: pci: add PCI SR-IOV EA support Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 07/22] fdt: add fdtdec_get_pci_bus_range Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 08/22] pci: add thunderx pci/ecam driver Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 09/22] pci: fix pce enumeration on thunderx Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 10/22] arm: include 64bit io accessors Tim Harvey
2019-02-22 18:03 ` Tim Harvey [this message]
2019-02-22 18:03 ` [U-Boot] [RFC 12/22] i2c: add thunderx I2C driver Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 13/22] spi: add thunderx SPI driver Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 14/22] xhci: add support for cavium thunderx XHCI Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 15/22] thunderx_81xx: add support for XHCI Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 16/22] thunderx_81xx: enable usb mass storage and usb ethernet Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 17/22] ahci: support 64bit systems Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 18/22] ahci: set n_ports from host caps Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 19/22] ahci: add support for ThunderX AHCI Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 20/22] thunderx_81xx: add AHCI support Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 21/22] net: add thunderx vnic drivers Tim Harvey
2019-02-22 18:03 ` [U-Boot] [RFC 22/22] pci: auto probe thunderx NIC devices Tim Harvey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190222180319.32221-12-tharvey@gateworks.com \
    --to=tharvey@gateworks.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.