Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / drivers / gpio / kona_gpio.c
diff --git a/qemu/roms/u-boot/drivers/gpio/kona_gpio.c b/qemu/roms/u-boot/drivers/gpio/kona_gpio.c
new file mode 100644 (file)
index 0000000..6511743
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2013 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier:      GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sysmap.h>
+
+#define GPIO_BASE                              (void *)GPIO2_BASE_ADDR
+
+#define GPIO_PASSWD                            0x00a5a501
+#define GPIO_PER_BANK                          32
+#define GPIO_MAX_BANK_NUM                      8
+
+#define GPIO_BANK(gpio)                                ((gpio) >> 5)
+#define GPIO_BITMASK(gpio)     \
+       (1UL << ((gpio) & (GPIO_PER_BANK - 1)))
+
+#define GPIO_OUT_STATUS(bank)                  (0x00000000 + ((bank) << 2))
+#define GPIO_IN_STATUS(bank)                   (0x00000020 + ((bank) << 2))
+#define GPIO_OUT_SET(bank)                     (0x00000040 + ((bank) << 2))
+#define GPIO_OUT_CLEAR(bank)                   (0x00000060 + ((bank) << 2))
+#define GPIO_INT_STATUS(bank)                  (0x00000080 + ((bank) << 2))
+#define GPIO_INT_MASK(bank)                    (0x000000a0 + ((bank) << 2))
+#define GPIO_INT_MSKCLR(bank)                  (0x000000c0 + ((bank) << 2))
+#define GPIO_CONTROL(bank)                     (0x00000100 + ((bank) << 2))
+#define GPIO_PWD_STATUS(bank)                  (0x00000500 + ((bank) << 2))
+
+#define GPIO_GPPWR_OFFSET                      0x00000520
+
+#define GPIO_GPCTR0_DBR_SHIFT                  5
+#define GPIO_GPCTR0_DBR_MASK                   0x000001e0
+
+#define GPIO_GPCTR0_ITR_SHIFT                  3
+#define GPIO_GPCTR0_ITR_MASK                   0x00000018
+#define GPIO_GPCTR0_ITR_CMD_RISING_EDGE                0x00000001
+#define GPIO_GPCTR0_ITR_CMD_FALLING_EDGE       0x00000002
+#define GPIO_GPCTR0_ITR_CMD_BOTH_EDGE          0x00000003
+
+#define GPIO_GPCTR0_IOTR_MASK                  0x00000001
+#define GPIO_GPCTR0_IOTR_CMD_0UTPUT            0x00000000
+#define GPIO_GPCTR0_IOTR_CMD_INPUT             0x00000001
+
+int gpio_request(unsigned gpio, const char *label)
+{
+       unsigned int value, off;
+
+       writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
+       off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
+       value = readl(GPIO_BASE + off) & ~GPIO_BITMASK(gpio);
+       writel(value, GPIO_BASE + off);
+
+       return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+       unsigned int value, off;
+
+       writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
+       off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
+       value = readl(GPIO_BASE + off) | GPIO_BITMASK(gpio);
+       writel(value, GPIO_BASE + off);
+
+       return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+       u32 val;
+
+       val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
+       val &= ~GPIO_GPCTR0_IOTR_MASK;
+       val |= GPIO_GPCTR0_IOTR_CMD_INPUT;
+       writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
+
+       return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+       int bank_id = GPIO_BANK(gpio);
+       int bitmask = GPIO_BITMASK(gpio);
+       u32 val, off;
+
+       val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
+       val &= ~GPIO_GPCTR0_IOTR_MASK;
+       val |= GPIO_GPCTR0_IOTR_CMD_0UTPUT;
+       writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
+       off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
+
+       val = readl(GPIO_BASE + off);
+       val |= bitmask;
+       writel(val, GPIO_BASE + off);
+
+       return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+       int bank_id = GPIO_BANK(gpio);
+       int bitmask = GPIO_BITMASK(gpio);
+       u32 val, off;
+
+       /* determine the GPIO pin direction */
+       val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
+       val &= GPIO_GPCTR0_IOTR_MASK;
+
+       /* read the GPIO bank status */
+       off = (GPIO_GPCTR0_IOTR_CMD_INPUT == val) ?
+           GPIO_IN_STATUS(bank_id) : GPIO_OUT_STATUS(bank_id);
+       val = readl(GPIO_BASE + off);
+
+       /* return the specified bit status */
+       return !!(val & bitmask);
+}
+
+void gpio_set_value(unsigned gpio, int value)
+{
+       int bank_id = GPIO_BANK(gpio);
+       int bitmask = GPIO_BITMASK(gpio);
+       u32 val, off;
+
+       /* determine the GPIO pin direction */
+       val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
+       val &= GPIO_GPCTR0_IOTR_MASK;
+
+       /* this function only applies to output pin */
+       if (GPIO_GPCTR0_IOTR_CMD_INPUT == val) {
+               printf("%s: Cannot set an input pin %d\n", __func__, gpio);
+               return;
+       }
+
+       off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
+
+       val = readl(GPIO_BASE + off);
+       val |= bitmask;
+       writel(val, GPIO_BASE + off);
+}