diff options
author | andy.hu <andy.hu@starfivetech.com> | 2023-01-17 14:07:08 +0300 |
---|---|---|
committer | andy.hu <andy.hu@starfivetech.com> | 2023-01-17 14:07:08 +0300 |
commit | ced60104df4f835e1d6bd0697b38394de64e301a (patch) | |
tree | de49b5f39b5fa060683724ec14000dbe62990e7f | |
parent | 7700244f4d334d765ee5d994c3849ade09fb6844 (diff) | |
parent | e9dc3a1cc17ca764edcca93685f2bb14ea29bfa3 (diff) | |
download | opensbi-VF2_v2.10.4.tar.xz |
Merge branch 'CR_3043_add_sbi_gpio_reset_minda' into 'master'VF2_v2.10.4
CR_3043 gpio: add gpio driver and support gpio reset
See merge request sdk/opensbi!4
-rw-r--r-- | lib/utils/gpio/Kconfig | 3 | ||||
-rw-r--r-- | lib/utils/gpio/fdt_gpio_starfive.c | 116 | ||||
-rw-r--r-- | lib/utils/gpio/objects.mk | 3 | ||||
-rw-r--r-- | platform/generic/configs/defconfig | 1 |
4 files changed, 123 insertions, 0 deletions
diff --git a/lib/utils/gpio/Kconfig b/lib/utils/gpio/Kconfig index 38a9d75..1b338a6 100644 --- a/lib/utils/gpio/Kconfig +++ b/lib/utils/gpio/Kconfig @@ -14,6 +14,9 @@ config FDT_GPIO_SIFIVE bool "SiFive GPIO FDT driver" default n +config FDT_GPIO_STARFIVE + bool "StarFive GPIO FDT driver" + default n endif config GPIO diff --git a/lib/utils/gpio/fdt_gpio_starfive.c b/lib/utils/gpio/fdt_gpio_starfive.c new file mode 100644 index 0000000..57a4da7 --- /dev/null +++ b/lib/utils/gpio/fdt_gpio_starfive.c @@ -0,0 +1,116 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Starfive + * + * Authors: + * Minda.chen <Minda.chen@starfivetech.com> + */ + +#include <sbi/riscv_io.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_console.h> +#include <sbi_utils/fdt/fdt_helper.h> +#include <sbi_utils/gpio/fdt_gpio.h> + +#define STARFIVE_GPIO_CHIP_MAX 2 +#define STARFIVE_GPIO_PINS_DEF 64 +#define STARFIVE_GPIO_OUTVAL 0x40 +#define STARFIVE_GPIO_MASK 0xff +#define STARFIVE_GPIO_REG_SHIFT_MASK 0x3 +#define STARFIVE_GPIO_SHIFT_BITS 0x3 + +struct starfive_gpio_chip { + unsigned long addr; + struct gpio_chip chip; +}; + +static unsigned int starfive_gpio_chip_count; +static struct starfive_gpio_chip starfive_gpio_chip_array[STARFIVE_GPIO_CHIP_MAX]; + +static int starfive_gpio_direction_output(struct gpio_pin *gp, int value) +{ + uint32_t val; + unsigned long reg_addr; + uint32_t bit_mask, shift_bits; + struct starfive_gpio_chip *chip = + container_of(gp->chip, struct starfive_gpio_chip, chip); + + /* set out en*/ + reg_addr = chip->addr + gp->offset; + reg_addr &= ~(STARFIVE_GPIO_REG_SHIFT_MASK); + + val = readl((volatile void *)(reg_addr)); + shift_bits = (gp->offset & STARFIVE_GPIO_REG_SHIFT_MASK) + << STARFIVE_GPIO_SHIFT_BITS; + bit_mask = STARFIVE_GPIO_MASK << shift_bits; + + val = readl((volatile void *)reg_addr); + val &= ~bit_mask; + writel(val, (volatile void *)reg_addr); + + return 0; +} + +static void starfive_gpio_set(struct gpio_pin *gp, int value) +{ + uint32_t val; + unsigned long reg_addr; + uint32_t bit_mask, shift_bits; + struct starfive_gpio_chip *chip = + container_of(gp->chip, struct starfive_gpio_chip, chip); + + reg_addr = chip->addr + gp->offset; + reg_addr &= ~(STARFIVE_GPIO_REG_SHIFT_MASK); + + shift_bits = (gp->offset & STARFIVE_GPIO_REG_SHIFT_MASK) + << STARFIVE_GPIO_SHIFT_BITS; + bit_mask = STARFIVE_GPIO_MASK << shift_bits; + /* set output value */ + val = readl((volatile void *)(reg_addr + STARFIVE_GPIO_OUTVAL)); + val &= ~bit_mask; + val |= value << shift_bits; + writel(val, (volatile void *)(reg_addr + STARFIVE_GPIO_OUTVAL)); +} + +extern struct fdt_gpio fdt_gpio_starfive; + +static int starfive_gpio_init(void *fdt, int nodeoff, u32 phandle, + const struct fdt_match *match) +{ + int rc; + struct starfive_gpio_chip *chip; + uint64_t addr; + + if (STARFIVE_GPIO_CHIP_MAX <= starfive_gpio_chip_count) + return SBI_ENOSPC; + chip = &starfive_gpio_chip_array[starfive_gpio_chip_count]; + + rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL); + if (rc) + return rc; + + chip->addr = addr; + chip->chip.driver = &fdt_gpio_starfive; + chip->chip.id = phandle; + chip->chip.ngpio = STARFIVE_GPIO_PINS_DEF; + chip->chip.direction_output = starfive_gpio_direction_output; + chip->chip.set = starfive_gpio_set; + rc = gpio_chip_add(&chip->chip); + if (rc) + return rc; + + starfive_gpio_chip_count++; + return 0; +} + +static const struct fdt_match starfive_gpio_match[] = { + { .compatible = "starfive,jh7110-sys-pinctrl" }, + { }, +}; + +struct fdt_gpio fdt_gpio_starfive = { + .match_table = starfive_gpio_match, + .xlate = fdt_gpio_simple_xlate, + .init = starfive_gpio_init, +}; diff --git a/lib/utils/gpio/objects.mk b/lib/utils/gpio/objects.mk index eedd699..8f4a6a8 100644 --- a/lib/utils/gpio/objects.mk +++ b/lib/utils/gpio/objects.mk @@ -13,4 +13,7 @@ libsbiutils-objs-$(CONFIG_FDT_GPIO) += gpio/fdt_gpio_drivers.o carray-fdt_gpio_drivers-$(CONFIG_FDT_GPIO_SIFIVE) += fdt_gpio_sifive libsbiutils-objs-$(CONFIG_FDT_GPIO_SIFIVE) += gpio/fdt_gpio_sifive.o +carray-fdt_gpio_drivers-$(CONFIG_FDT_GPIO_STARFIVE) += fdt_gpio_starfive +libsbiutils-objs-$(CONFIG_FDT_GPIO_STARFIVE) += gpio/fdt_gpio_starfive.o + libsbiutils-objs-$(CONFIG_GPIO) += gpio/gpio.o diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig index 3db7050..1fece49 100644 --- a/platform/generic/configs/defconfig +++ b/platform/generic/configs/defconfig @@ -6,6 +6,7 @@ CONFIG_PLATFORM_SIFIVE_FU740=y CONFIG_PLATFORM_STARFIVE_JH7110=y CONFIG_FDT_GPIO=y CONFIG_FDT_GPIO_SIFIVE=y +CONFIG_FDT_GPIO_STARFIVE=y CONFIG_FDT_I2C=y CONFIG_FDT_I2C_SIFIVE=y CONFIG_FDT_I2C_STARFIVE=y |