Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
@@ -0,0 +1,210 @@
From 1c5b450a068583f2407767451ef636d0661071da Mon Sep 17 00:00:00 2001
From: Alexander Filippov <a.filippov@yadro.com>
Date: Tue, 7 Apr 2020 16:45:41 +0300
Subject: [PATCH] Add system reset status support
This is backport of patch file from intel-bmc/openbmc repository.
https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
Will display the reset reasons in u-boot,
and save the reset reasons into kernel command line,
for applications to query.
Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
---
arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 +-
arch/arm/include/asm/arch-aspeed/platform.h | 2 +
arch/arm/mach-aspeed/Makefile | 1 +
arch/arm/mach-aspeed/ast-late-init.c | 114 ++++++++++++++++++++
arch/arm/mach-aspeed/ast-scu.c | 6 +-
5 files changed, 123 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/mach-aspeed/ast-late-init.c
diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
index dcbc6730d4..b428f386d6 100644
--- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
+++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
@@ -29,7 +29,7 @@
#define __AST_SCU_H
extern void ast_scu_show_system_info (void);
-extern void ast_scu_sys_rest_info(void);
+extern u32 ast_scu_sys_rest_info(void);
extern void ast_scu_security_info(void);
extern u32 ast_scu_revision_id(void);
extern u32 ast_scu_get_vga_memsize(void);
diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
index 1c02914fcb..b9207c492f 100644
--- a/arch/arm/include/asm/arch-aspeed/platform.h
+++ b/arch/arm/include/asm/arch-aspeed/platform.h
@@ -31,4 +31,6 @@
#err "No define for platform.h"
#endif
+#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */
+
#endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 7d8930beb9..4af2a7c96a 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -15,3 +15,4 @@ obj-y += timer.o reset.o cpuinfo.o ast-scu.o ast-ahbc.o ast-sdmc.o
obj-$(CONFIG_AST_SPI_NOR) += flash.o
obj-$(CONFIG_ARCH_AST2500) += platform_g5.o
obj-$(CONFIG_ARCH_AST2400) += platform_g4.o
+obj-$(CONFIG_BOARD_LATE_INIT) += ast-late-init.o
diff --git a/arch/arm/mach-aspeed/ast-late-init.c b/arch/arm/mach-aspeed/ast-late-init.c
new file mode 100644
index 0000000000..5646c0e882
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast-late-init.c
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright (C) 2020 YADRO.
+ */
+
+#include <common.h>
+
+#include <asm/arch/ast_scu.h>
+#include <asm/arch/regs-scu.h>
+#include <malloc.h>
+
+static void update_bootargs_cmd(const char *key, const char *value)
+{
+ int buf_len;
+ char *buf;
+ char *cmdline;
+ char *end = NULL;
+
+ if (!key || (key[0] == '\0'))
+ {
+ printf("%s: Empty key not allowed\n", __func__);
+ return;
+ }
+
+ cmdline = getenv("bootargs");
+
+ /* Allocate space for maximum possible new command line */
+ buf_len = (cmdline ? strlen(cmdline) : 0)
+ + 1 /* spacebar as delimiter */
+ + strlen(key)
+ + (value ? 1 /* equal sign */ + strlen(value) : 0)
+ + 1 /* terminating null */;
+
+ buf = calloc(buf_len, sizeof(char));
+ if (!buf)
+ {
+ printf("%s: out of memory\n", __func__);
+ return;
+ }
+
+ if (cmdline)
+ {
+ char *start = strstr(cmdline, key);
+
+ /* Check for full word match. Match should be start of cmdline
+ * or there should be space before match */
+ if (start && ((start == cmdline) || (*(start - 1) == ' ')))
+ {
+ strncat(buf, cmdline, (start - cmdline));
+
+ /* Find the end of the keyword[=value] pair,
+ * including a single training space character, if any.
+ * Skip the found substring, mark the tail of cmdline.
+ */
+ end = strchr(start, ' ');
+ if (end)
+ {
+ end++;
+ }
+ }
+ else
+ {
+ strcat(buf, cmdline);
+ strcat(buf, " ");
+ }
+ }
+
+ strcat(buf, key);
+ if (value)
+ {
+ strcat(buf, "=");
+ strcat(buf, value);
+ }
+
+ if (end)
+ {
+ strcat(buf, " ");
+ strcat(buf, end);
+ }
+
+ setenv("bootargs", buf);
+ free(buf);
+}
+
+static void set_reset_reason(void)
+{
+ u32 reset_reason = ast_scu_sys_rest_info();
+
+ if (reset_reason & SCU_SYS_EXT_RESET_FLAG)
+ {
+ update_bootargs_cmd("resetreason", "external");
+ }
+ else if (reset_reason & SCU_SYS_WDT_RESET_FLAG)
+ {
+ update_bootargs_cmd("resetreason", "watchdog");
+ }
+ else if (reset_reason & SCU_SYS_PWR_RESET_FLAG)
+ {
+ update_bootargs_cmd("resetreason", "power");
+ }
+ else
+ {
+ char value[32];
+ snprintf(value, sizeof(value) - 1, "0x%x", reset_reason);
+ update_bootargs_cmd("resetreason", value);
+ }
+}
+
+int board_late_init(void)
+{
+ set_reset_reason();
+
+ return 0;
+}
diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
index 12de9b8036..5afd3793e3 100644
--- a/arch/arm/mach-aspeed/ast-scu.c
+++ b/arch/arm/mach-aspeed/ast-scu.c
@@ -482,22 +482,26 @@ void ast_scu_security_info(void)
}
}
-void ast_scu_sys_rest_info(void)
+u32 ast_scu_sys_rest_info(void)
{
u32 rest = ast_scu_read(AST_SCU_SYS_CTRL);
if (rest & SCU_SYS_EXT_RESET_FLAG) {
printf("RST : External\n");
ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL);
+ rest = SCU_SYS_EXT_RESET_FLAG;
} else if (rest & SCU_SYS_WDT_RESET_FLAG) {
printf("RST : Watchdog\n");
ast_scu_write(SCU_SYS_WDT_RESET_FLAG, AST_SCU_SYS_CTRL);
+ rest = SCU_SYS_WDT_RESET_FLAG;
} else if (rest & SCU_SYS_PWR_RESET_FLAG) {
printf("RST : Power On\n");
ast_scu_write(SCU_SYS_PWR_RESET_FLAG, AST_SCU_SYS_CTRL);
+ rest = SCU_SYS_PWR_RESET_FLAG;
} else {
printf("RST : CLK en\n");
}
+ return rest;
}
u32 ast_scu_get_vga_memsize(void)
--
2.25.4
@@ -0,0 +1,27 @@
From efc627f4a288ea2e7969407f50fc403bb0264df1 Mon Sep 17 00:00:00 2001
From: Alexander Filippov <a.filippov@yadro.com>
Date: Wed, 23 Oct 2019 15:51:25 +0300
Subject: [PATCH] config/ast-common: set fieldmode to true
Force enables field mode. Our system always in production.
Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
---
include/configs/ast-common.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/configs/ast-common.h b/include/configs/ast-common.h
index a0243083bd..6285fa4037 100644
--- a/include/configs/ast-common.h
+++ b/include/configs/ast-common.h
@@ -117,6 +117,7 @@
#define ASPEED_ENV_SETTINGS \
"verify=yes\0" \
"spi_dma=yes\0" \
+ "fieldmode=true\0" \
""
#endif /* __AST_COMMON_CONFIG_H */
--
2.21.0
@@ -0,0 +1,512 @@
From 9bb68d8820480519e8b331f7a8b866b8718ad7fd Mon Sep 17 00:00:00 2001
From: Alexander Filippov <a.filippov@yadro.com>
Date: Tue, 19 May 2020 18:55:41 +0300
Subject: [PATCH] aspeed: add gpio support
This is an initial support for the parallel GPIO pins directly connected
to the AHB on the Aspeed 2400/2500.
This brings the functions and a shell command to manipulate the GPIO
state. The GPIO value reading and writing work in non interrupt mode
only.
Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
---
arch/arm/include/asm/arch-aspeed/gpio.h | 65 ++++
arch/arm/include/asm/arch-aspeed/platform.h | 1 +
drivers/gpio/Makefile | 2 +
drivers/gpio/aspeed_gpio.c | 386 ++++++++++++++++++++
4 files changed, 454 insertions(+)
create mode 100644 arch/arm/include/asm/arch-aspeed/gpio.h
create mode 100644 drivers/gpio/aspeed_gpio.c
diff --git a/arch/arm/include/asm/arch-aspeed/gpio.h b/arch/arm/include/asm/arch-aspeed/gpio.h
new file mode 100644
index 0000000000..c63987e917
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/gpio.h
@@ -0,0 +1,65 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ * Copyright (C) 2020 YADRO.
+ */
+#ifndef _ASPEED_GPIO_H
+#define _ASPEED_GPIO_H
+
+#define ASPEED_GPIO_PORT_A 0
+#define ASPEED_GPIO_PORT_B 1
+#define ASPEED_GPIO_PORT_C 2
+#define ASPEED_GPIO_PORT_D 3
+#define ASPEED_GPIO_PORT_E 4
+#define ASPEED_GPIO_PORT_F 5
+#define ASPEED_GPIO_PORT_G 6
+#define ASPEED_GPIO_PORT_H 7
+#define ASPEED_GPIO_PORT_I 8
+#define ASPEED_GPIO_PORT_J 9
+#define ASPEED_GPIO_PORT_K 10
+#define ASPEED_GPIO_PORT_L 11
+#define ASPEED_GPIO_PORT_M 12
+#define ASPEED_GPIO_PORT_N 13
+#define ASPEED_GPIO_PORT_O 14
+#define ASPEED_GPIO_PORT_P 15
+#define ASPEED_GPIO_PORT_Q 16
+#define ASPEED_GPIO_PORT_R 17
+#define ASPEED_GPIO_PORT_S 18
+#define ASPEED_GPIO_PORT_T 19
+#define ASPEED_GPIO_PORT_U 20
+#define ASPEED_GPIO_PORT_V 21
+#define ASPEED_GPIO_PORT_W 22
+#define ASPEED_GPIO_PORT_X 23
+#define ASPEED_GPIO_PORT_Y 24
+#define ASPEED_GPIO_PORT_Z 25
+#define ASPEED_GPIO_PORT_AA 26
+#define ASPEED_GPIO_PORT_AB 27
+#define ASPEED_GPIO_PORT_AC 28
+
+#define ASPEED_GPIO_PORT_SHIFT 3
+#define ASPEED_GPIO_PIN_MASK 0x7
+#define ASPEED_GPIO(port, pin) \
+ ((ASPEED_GPIO_PORT_##port << ASPEED_GPIO_PORT_SHIFT) | \
+ (pin & ASPEED_GPIO_PIN_MASK))
+
+/* Direction values */
+#define ASPEED_GPIO_INPUT 0
+#define ASPEED_GPIO_OUTPUT 1
+
+/* Trigger values */
+#define ASPEED_GPIO_FALLING_EDGE 0
+#define ASPEED_GPIO_RISING_EDGE 1
+#define ASPEED_GPIO_LOW_LEVEL 2
+#define ASPEED_GPIO_HIGH_LEVEL 3
+#define ASPEED_GPIO_DUAL_EDGE 4
+
+/* Debounce values */
+#define ASPEED_GPIO_DEBOUNCE_NONE 0
+#define ASPEED_GPIO_DEBOUNCE_1 1
+#define ASPEED_GPIO_DEBOUNCE_2 2
+#define ASPEED_GPIO_DEBOUNCE_3 3
+
+#define gpio_status() gpio_info()
+
+extern void gpio_info(void);
+
+#endif /* #ifndef _ASPEED_GPIO_H */
diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
index b9207c492f..0a05a7a7a0 100644
--- a/arch/arm/include/asm/arch-aspeed/platform.h
+++ b/arch/arm/include/asm/arch-aspeed/platform.h
@@ -32,5 +32,6 @@
#endif
#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */
+#define CONFIG_CMD_GPIO 1 /* Enable gpio command in shell */
#endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 792d19186a..5f043e07ce 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
obj-$(CONFIG_DM_PCA953X) += pca953x_gpio.o
obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
+obj-$(CONFIG_ARCH_AST2400) += aspeed_gpio.o
+obj-$(CONFIG_ARCH_AST2500) += aspeed_gpio.o
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
diff --git a/drivers/gpio/aspeed_gpio.c b/drivers/gpio/aspeed_gpio.c
new file mode 100644
index 0000000000..dc07f5a520
--- /dev/null
+++ b/drivers/gpio/aspeed_gpio.c
@@ -0,0 +1,386 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ * Copyright (C) 2020 YADRO.
+ */
+
+#include <common.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/platform.h>
+#include <asm/io.h>
+#include <linux/ctype.h>
+
+typedef struct _ast_gpio_regs
+{
+ uint32_t base; /* data and direction registers */
+ uint32_t intcfg; /* interrupt config */
+ uint32_t debounce; /* debounce config */
+ uint32_t cmdsrc; /* command source config */
+ uint32_t data; /* data read register */
+} ast_gpio_regs_t;
+
+static ast_gpio_regs_t ast_gpio_regs[] = {
+ /* A/B/C/D */
+ {AST_GPIO_BASE + 0x0000, AST_GPIO_BASE + 0x0008, AST_GPIO_BASE + 0x0040,
+ AST_GPIO_BASE + 0x0060, AST_GPIO_BASE + 0x00C0},
+ /* E/F/G/H */
+ {AST_GPIO_BASE + 0x0020, AST_GPIO_BASE + 0x0028, AST_GPIO_BASE + 0x0048,
+ AST_GPIO_BASE + 0x0068, AST_GPIO_BASE + 0x00C4},
+ /* I/J/K/L */
+ {AST_GPIO_BASE + 0x0070, AST_GPIO_BASE + 0x0098, AST_GPIO_BASE + 0x00B0,
+ AST_GPIO_BASE + 0x0090, AST_GPIO_BASE + 0x00C8},
+ /* M/N/O/P */
+ {AST_GPIO_BASE + 0x0078, AST_GPIO_BASE + 0x00E8, AST_GPIO_BASE + 0x0100,
+ AST_GPIO_BASE + 0x00E0, AST_GPIO_BASE + 0x00CC},
+ /* Q/R/S/T */
+ {AST_GPIO_BASE + 0x0080, AST_GPIO_BASE + 0x0118, AST_GPIO_BASE + 0x0130,
+ AST_GPIO_BASE + 0x0110, AST_GPIO_BASE + 0x00D0},
+ /* U/V/W/X */
+ {AST_GPIO_BASE + 0x0088, AST_GPIO_BASE + 0x0148, AST_GPIO_BASE + 0x0160,
+ AST_GPIO_BASE + 0x0140, AST_GPIO_BASE + 0x00D4},
+ /* Y/Z/AA/AB */
+ {AST_GPIO_BASE + 0x01E0, AST_GPIO_BASE + 0x0178, AST_GPIO_BASE + 0x0190,
+ AST_GPIO_BASE + 0x0170, AST_GPIO_BASE + 0x00D8},
+ /* AC */
+ {AST_GPIO_BASE + 0x01E8, AST_GPIO_BASE + 0x01A8, AST_GPIO_BASE + 0x01C0,
+ AST_GPIO_BASE + 0x01A0, AST_GPIO_BASE + 0x00DC},
+};
+
+#define AST_GPIO_PINS_PER_PORT 8
+#define AST_GPIO_PORTS_PER_REGISTER 4
+
+#define AST_GPIO_PORT(gpio) (gpio >> ASPEED_GPIO_PORT_SHIFT)
+#define AST_GPIO_PIN(gpio) (gpio & ASPEED_GPIO_PIN_MASK)
+#define AST_GPIO_SHIFT(gpio) \
+ ((AST_GPIO_PORT(gpio) % AST_GPIO_PORTS_PER_REGISTER) * \
+ AST_GPIO_PINS_PER_PORT + \
+ AST_GPIO_PIN(gpio))
+
+#define AST_GPIO_REG_INDEX(gpio) \
+ (AST_GPIO_PORT(gpio) / AST_GPIO_PORTS_PER_REGISTER)
+
+/**
+ * @return Pointer to corresponding item from ast_gpio_regs table.
+ */
+#define AST_GPIO_REGS(gpio) \
+ ((AST_GPIO_REG_INDEX(gpio) < ARRAY_SIZE(ast_gpio_regs)) \
+ ? (ast_gpio_regs + AST_GPIO_REG_INDEX(gpio)) \
+ : NULL)
+
+/**
+ * @brief Set a corresponding bit in specified register.
+ *
+ * @param val - Required bit value
+ * @param base - Register address
+ * @param shift - Bit index.
+ */
+#define AST_GPIO_WRITE(val, base, shift) \
+ writel(((val) ? readl(base) | (1 << (shift)) \
+ : readl(base) & ~(1 << (shift))), \
+ base)
+
+/**
+ * @brief Get value of corresponging bit from specified register.
+ *
+ * @param base - Register address
+ * @param shift - Bit index
+ *
+ * @return Bit value
+ */
+#define AST_GPIO_READ(base, shift) ((readl(base) >> (shift)) & 1)
+
+#define IS_VALID_GPIO(gpio) \
+ ((gpio) >= ASPEED_GPIO(A, 0) && (gpio) <= ASPEED_GPIO(AC, 7))
+
+#define AST_GPIO_DIRECTION 0x04
+#define AST_GPIO_INT_SENS0 0x04
+#define AST_GPIO_INT_SENS1 0x08
+#define AST_GPIO_INT_SENS2 0x0C
+#define AST_GPIO_INT_STATUS 0x10
+#define AST_GPIO_DEBOUNCE0 0x00
+#define AST_GPIO_DEBOUNCE1 0x04
+#define AST_GPIO_CMD_SRC0 0x00
+#define AST_GPIO_CMD_SRC1 0x04
+
+/**
+ * @brief Set a GPIO direction
+ *
+ * @param gpio GPIO line
+ * @param direction GPIO direction (0 for input or 1 for output)
+ *
+ * @return 0 if ok, -1 on error
+ */
+static int ast_gpio_set_direction(unsigned gpio, unsigned direction)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (!regs)
+ {
+ printf("%s: Invalid GPIO!\n", __func__);
+ return -1;
+ }
+
+ AST_GPIO_WRITE(direction, regs->base + AST_GPIO_DIRECTION,
+ AST_GPIO_SHIFT(gpio));
+ return 0;
+}
+
+/**
+ * The 6 following functions are generic u-boot gpio implementation.
+ * They are declared in `include/asm-generic/gpio.h`
+ */
+
+int gpio_request(unsigned gpio, const char *label)
+{
+ return (IS_VALID_GPIO(gpio) ? 0 : -1);
+}
+
+int gpio_free(unsigned gpio)
+{
+ return (IS_VALID_GPIO(gpio) ? 0 : -1);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (!regs)
+ {
+ printf("%s: Invalid GPIO!\n", __func__);
+ return -1;
+ }
+
+ return AST_GPIO_READ(regs->base, AST_GPIO_SHIFT(gpio));
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (!regs)
+ {
+ printf("%s: Invalid GPIO!\n", __func__);
+ return -1;
+ }
+
+ AST_GPIO_WRITE(value, regs->base, AST_GPIO_SHIFT(gpio));
+ return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ return ast_gpio_set_direction(gpio, ASPEED_GPIO_INPUT);
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ int rc = ast_gpio_set_direction(gpio, ASPEED_GPIO_OUTPUT);
+ return (rc == 0 ? gpio_set_value(gpio, value) : rc);
+}
+
+/**
+ * @brief Convert a string to GPIO line. Used by `do_gpio()` from `cmd/gpio.c`
+ *
+ * @param str a GPIO name or line number
+ *
+ * @return GPIO line if ok, -1 on error
+ */
+int name_to_gpio(const char *str)
+{
+ int gpio = -1;
+
+ if (str)
+ {
+ if (isalpha(*str))
+ {
+ gpio = (toupper(*str) - 'A') << ASPEED_GPIO_PORT_SHIFT;
+
+ if (toupper(*str) == 'A' && toupper(*(str + 1)) >= 'A' &&
+ toupper(*(str + 1)) <= 'C')
+ {
+ str++;
+ gpio = (ASPEED_GPIO_PORT_AA + toupper(*str) - 'A')
+ << ASPEED_GPIO_PORT_SHIFT;
+ }
+
+ str++;
+ if (*str >= '0' && *str <= '7' && !*(str + 1))
+ {
+ gpio += *str - '0';
+ }
+ else
+ {
+ gpio = -1;
+ }
+ }
+ else if (isdigit(*str))
+ {
+ gpio = simple_strtoul(str, NULL, 0);
+ }
+ }
+
+ return gpio;
+}
+
+/**
+ * @return A GPIO direction in human readable format.
+ */
+static const char *ast_gpio_direction(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (regs)
+ {
+ int direction = AST_GPIO_READ(regs->base + AST_GPIO_DIRECTION,
+ AST_GPIO_SHIFT(gpio));
+ switch (direction)
+ {
+ case ASPEED_GPIO_INPUT:
+ return "input";
+ case ASPEED_GPIO_OUTPUT:
+ return "output";
+ default:
+ break;
+ }
+ }
+ return "error";
+}
+
+/**
+ * @return An interrupt trigger settings in human readable format.
+ */
+static const char *ast_gpio_trigger(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (regs)
+ {
+ unsigned shift = AST_GPIO_SHIFT(gpio);
+ unsigned trigger =
+ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS0, shift) << 0) |
+ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS1, shift) << 1) |
+ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS2, shift) << 2);
+
+ switch (trigger)
+ {
+ case ASPEED_GPIO_FALLING_EDGE:
+ return "fall";
+ case ASPEED_GPIO_RISING_EDGE:
+ return "rise";
+ case ASPEED_GPIO_LOW_LEVEL:
+ return "low ";
+ case ASPEED_GPIO_HIGH_LEVEL:
+ return "high";
+ default:
+ return "both";
+ }
+ }
+ return "error";
+}
+
+/**
+ * @return An interrupt status in human readable format.
+ */
+static const char *ast_gpio_int_status(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (regs)
+ {
+ unsigned shift = AST_GPIO_SHIFT(gpio);
+ if (AST_GPIO_READ(regs->intcfg, shift))
+ {
+ return AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_STATUS, shift)
+ ? "pending"
+ : "cleaned";
+ }
+ return "disabled";
+ }
+
+ return "error";
+}
+
+/**
+ * @return A debounce value in human readable format.
+ */
+static const char *ast_gpio_debounce(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (regs)
+ {
+ unsigned shift = AST_GPIO_SHIFT(gpio);
+ unsigned debounce =
+ (AST_GPIO_READ(regs->debounce + AST_GPIO_DEBOUNCE0, shift) << 0) |
+ (AST_GPIO_READ(regs->debounce + AST_GPIO_DEBOUNCE1, shift) << 1);
+ switch (debounce)
+ {
+ case ASPEED_GPIO_DEBOUNCE_NONE:
+ return "none";
+ case ASPEED_GPIO_DEBOUNCE_1:
+ return "timer1";
+ case ASPEED_GPIO_DEBOUNCE_2:
+ return "timer2";
+ case ASPEED_GPIO_DEBOUNCE_3:
+ return "timer3";
+ default:
+ break;
+ }
+ }
+
+ return "error";
+}
+
+/**
+ * @return A command source value in human readable format.
+ */
+static const char *ast_gpio_command_source(unsigned gpio)
+{
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (regs)
+ {
+ /* Used one bit per gpio port */
+ unsigned shift = AST_GPIO_SHIFT(gpio) - AST_GPIO_PIN(gpio);
+ unsigned cmdsrc =
+ (AST_GPIO_READ(regs->cmdsrc + AST_GPIO_CMD_SRC0, shift) << 0) |
+ (AST_GPIO_READ(regs->cmdsrc + AST_GPIO_CMD_SRC1, shift) << 1);
+
+ switch (cmdsrc)
+ {
+ /* The single place where these values are used is here. */
+ case 0x0:
+ return "ARM";
+ case 0x1:
+ return "LPC";
+ case 0x2:
+ return "CoCPU";
+ default:
+ return "Unknown";
+ }
+ }
+
+ return "error";
+}
+
+/**
+ * @brief Show all GPIO pins statuses. Used by `do_gpio()` in `cmd/gpio.c`
+ */
+void gpio_info(void)
+{
+ unsigned first = ASPEED_GPIO(A, 0);
+ unsigned last = ASPEED_GPIO(AC, 7);
+ for (unsigned gpio = first; gpio <= last; gpio++)
+ {
+ unsigned port = AST_GPIO_PORT(gpio);
+ unsigned pin = AST_GPIO_PIN(gpio);
+ unsigned shift = AST_GPIO_SHIFT(gpio);
+ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio);
+ if (!regs)
+ {
+ printf("gpio %u is invalid!\n", gpio);
+ continue;
+ }
+
+ printf("gpio %c%c%c line %3d: %s, int: %s, %s, deb: %s, src: %s, "
+ "val: %d/%d\n",
+ (port >= ASPEED_GPIO_PORT_AA ? 'A' : ' '),
+ ('A' + port % ASPEED_GPIO_PORT_AA), ('0' + pin), gpio,
+ ast_gpio_direction(gpio), ast_gpio_trigger(gpio),
+ ast_gpio_int_status(gpio), ast_gpio_debounce(gpio),
+ ast_gpio_command_source(gpio), gpio_get_value(gpio),
+ AST_GPIO_READ(regs->data, shift));
+ }
+}
--
2.25.4
@@ -0,0 +1,61 @@
From 8098310be5887bd5e80830f105b63ed59dc10421 Mon Sep 17 00:00:00 2001
From: Alexander Filippov <a.filippov@yadro.com>
Date: Fri, 22 May 2020 11:45:31 +0300
Subject: [PATCH] aspeed: add bmc position support
There are two Nicoles in one chassis in the Tatlin hardware.
The position is encoded by a pin, read by an MCU, and then translated
to the BMC via GPIO pin GPIOE1.
This reads the GPIO pin state and put is as a bootargs item.
Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
---
arch/arm/mach-aspeed/ast-late-init.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-aspeed/ast-late-init.c b/arch/arm/mach-aspeed/ast-late-init.c
index 5646c0e882..7d36dc0d8a 100644
--- a/arch/arm/mach-aspeed/ast-late-init.c
+++ b/arch/arm/mach-aspeed/ast-late-init.c
@@ -7,6 +7,7 @@
#include <asm/arch/ast_scu.h>
#include <asm/arch/regs-scu.h>
+#include <asm/gpio.h>
#include <malloc.h>
static void update_bootargs_cmd(const char *key, const char *value)
@@ -106,9 +107,29 @@ static void set_reset_reason(void)
}
}
+static void set_bmc_position(void)
+{
+ unsigned gpio = ASPEED_GPIO(E, 1);
+
+ /* Init GPIO */
+ if (gpio_request(gpio, "bmcposition") == 0 &&
+ gpio_direction_input(gpio) == 0)
+ {
+ int position = gpio_get_value(gpio);
+ if (position >= 0)
+ {
+ printf("BMC Position: %d\n", position);
+ update_bootargs_cmd("bmcposition", position ? "1" : "0");
+ }
+ }
+
+ gpio_free(gpio);
+}
+
int board_late_init(void)
{
set_reset_reason();
+ set_bmc_position();
return 0;
}
--
2.25.4
@@ -0,0 +1,8 @@
FILESEXTRAPATHS:append := "${THISDIR}/files:"
SRC_URI:append = " \
file://0001-Add-system-reset-status-support.patch \
file://0002-config-ast-common-set-fieldmode-to-true.patch \
file://0003-aspeed-add-gpio-support.patch \
file://0004-aspeed-add-bmc-position-support.patch \
"
@@ -0,0 +1 @@
u-boot-aspeed_%.bbappend