From 2a64b8ae9b952b18b4aef38cb7c41ce6dba16c50 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Mon, 24 May 2021 12:54:37 -0700 Subject: Update to internal 0.52 Signed-off-by: Jason M. Bills --- .../files/0016-Add-LED-control-support.patch | 457 +++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0016-Add-LED-control-support.patch (limited to 'meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0016-Add-LED-control-support.patch') diff --git a/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0016-Add-LED-control-support.patch b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0016-Add-LED-control-support.patch new file mode 100644 index 000000000..bc2007288 --- /dev/null +++ b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0016-Add-LED-control-support.patch @@ -0,0 +1,457 @@ +From d7befc37ba40a248899b5dc8e99bef2746a957d2 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Fri, 2 Apr 2021 09:48:38 -0700 +Subject: [PATCH] Add LED control support + +This commit adds LED control support including customization and improvement +on led-gpio and led-uclass driver to support 'blink' mode. LEDs will behave +like below. + +Normal u-boot : Green LED blinks at 1Hz + ID LED blinks at 3Hz +FFU u-boot : Amber LED solid on + ID LED solid on +MFG detected : Green LED blinks at 3Hz + ID LED blinks at 3Hz +Failure Recovery : Amber LED blinks at 3Hz + ID LED solid on +Jumping to Kernel : Green LED solid on + ID LED solid on + +Signed-off-by: Jae Hyun Yoo +--- + arch/arm/dts/ast2600-intel.dts | 4 +- + board/aspeed/ast2600_intel/intel.c | 66 +++++++++++++++++++++++++++++- + cmd/net.c | 23 +++++++++-- + drivers/led/led-uclass.c | 37 +++++++++++++++++ + drivers/led/led_gpio.c | 62 ++++++++++++++++++++++++++++ + include/led.h | 42 ++++++++++++++++++- + 6 files changed, 226 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/dts/ast2600-intel.dts b/arch/arm/dts/ast2600-intel.dts +index 1f14753056ee..5243d1a0afc3 100644 +--- a/arch/arm/dts/ast2600-intel.dts ++++ b/arch/arm/dts/ast2600-intel.dts +@@ -47,8 +47,8 @@ + }; + hb-led { + label = "hb"; +- gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; +- linux,default-trigger = "heartbeat"; ++ gpios = <&gpio0 173 GPIO_ACTIVE_LOW>; ++ default-state = "on"; + }; + }; + }; +diff --git a/board/aspeed/ast2600_intel/intel.c b/board/aspeed/ast2600_intel/intel.c +index 849e81ff3fef..fb9075f93945 100644 +--- a/board/aspeed/ast2600_intel/intel.c ++++ b/board/aspeed/ast2600_intel/intel.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + /* use GPIOC0 on intel boards */ +@@ -26,7 +27,27 @@ int read_ffuj(void) + return ret; + ret = dm_gpio_get_value(&desc); + dm_gpio_free(desc.dev, &desc); +- return ret; ++ ++ if (ret) { ++ struct udevice *dev; ++ ++ /* FFU mode: ChassisID - Solid Blue, StatusLED - Solid Amber */ ++ ret = led_get_by_label("green", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_OFF); ++ ++ ret = led_get_by_label("amber", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_ON); ++ ++ ret = led_get_by_label("id", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_ON); ++ ++ return 1; ++ } ++ ++ return 0; + } + + /* gpio_abort is a weak symbol in common/autoboot.c */ +@@ -264,6 +285,11 @@ static void timer_callback(void *cookie) + dummy = readl(0x1e78e07c); + dummy = readl(0x1e78f07c); + break; ++#ifdef CONFIG_LED_BLINK ++ case 1: ++ led_blink_update(); ++ break; ++#endif + } + } + +@@ -286,10 +312,20 @@ int board_early_init_f(void) + + int board_early_init_r(void) + { ++ struct udevice *dev; ++ int ret; ++ + debug("board_early_init_r\n"); + + enable_onboard_tpm(); + ++ led_default_state(); ++#ifdef CONFIG_LED_BLINK ++ ret = led_get_by_label("id", &dev); ++ if (!ret) ++ led_set_period(dev, 160); ++#endif ++ + return 0; + } + +@@ -366,6 +402,11 @@ int board_late_init(void) + if (readl(SCU_BASE | SCU_014) == REV_ID_AST2600A0) + timer_enable(0, ONE_MSEC_IN_USEC, timer_callback, (void *)0); + ++#ifdef CONFIG_LED_BLINK ++ timer_enable(1, LED_BLINK_UPDATE_TICK_MS * ONE_MSEC_IN_USEC, ++ timer_callback, (void *)1); ++#endif ++ + espi_init(); + + /* Add reset reason to bootargs */ +@@ -391,6 +432,29 @@ void board_init(void) + } + */ + ++void board_preboot_os(void) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ /* ++ * last second before OS booting ++ * ChassisID - Solid Blue, StatusLED - Solid Green ++ */ ++ ++ ret = led_get_by_label("green", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_ON); ++ ++ ret = led_get_by_label("amber", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_OFF); ++ ++ ret = led_get_by_label("id", &dev); ++ if (!ret) ++ led_set_state(dev, LEDST_ON); ++} ++ + #ifdef CONFIG_WATCHDOG + /* watchdog stuff */ + void watchdog_init(void) +diff --git a/cmd/net.c b/cmd/net.c +index 7d2c21ba4d22..a6b03654cdbf 100644 +--- a/cmd/net.c ++++ b/cmd/net.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []); + +@@ -183,6 +184,10 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, + int size; + ulong addr; + ++#ifdef CONFIG_LED_BLINK ++ led_blink_disable(); ++#endif ++ + net_boot_file_name_explicit = false; + + /* pre-set load_addr */ +@@ -229,7 +234,8 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, + if (strict_strtoul(argv[1], 16, &save_addr) < 0 || + strict_strtoul(argv[2], 16, &save_size) < 0) { + printf("Invalid address/size\n"); +- return CMD_RET_USAGE; ++ rcode = CMD_RET_USAGE; ++ goto exit; + } + net_boot_file_name_explicit = true; + copy_filename(net_boot_file_name, argv[3], +@@ -238,14 +244,16 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, + #endif + default: + bootstage_error(BOOTSTAGE_ID_NET_START); +- return CMD_RET_USAGE; ++ rcode = CMD_RET_USAGE; ++ goto exit; + } + bootstage_mark(BOOTSTAGE_ID_NET_START); + + size = net_loop(proto); + if (size < 0) { + bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK); +- return CMD_RET_FAILURE; ++ rcode = CMD_RET_FAILURE; ++ goto exit; + } + bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK); + +@@ -255,7 +263,8 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, + /* done if no file was loaded (no errors though) */ + if (size == 0) { + bootstage_error(BOOTSTAGE_ID_NET_LOADED); +- return CMD_RET_SUCCESS; ++ rcode = CMD_RET_SUCCESS; ++ goto exit; + } + + bootstage_mark(BOOTSTAGE_ID_NET_LOADED); +@@ -266,6 +275,12 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, + bootstage_mark(BOOTSTAGE_ID_NET_DONE); + else + bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR); ++ ++exit: ++#ifdef CONFIG_LED_BLINK ++ led_blink_enable(); ++#endif ++ + return rcode; + } + +diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c +index 2859475a6b8e..264e0735c815 100644 +--- a/drivers/led/led-uclass.c ++++ b/drivers/led/led-uclass.c +@@ -62,6 +62,39 @@ int led_set_period(struct udevice *dev, int period_ms) + + return ops->set_period(dev, period_ms); + } ++ ++static bool blink_enable = true; ++ ++void led_blink_enable(void) ++{ ++ blink_enable = true; ++} ++ ++void led_blink_disable(void) ++{ ++ blink_enable = false; ++} ++ ++int led_blink_update(void) ++{ ++ struct udevice *dev; ++ ++ if (!blink_enable) ++ return 0; ++ ++ for (uclass_find_first_device(UCLASS_LED, &dev); ++ dev; ++ uclass_find_next_device(&dev)) { ++ if (device_active(dev) && led_get_state(dev) == LEDST_BLINK) { ++ struct led_ops *ops = led_get_ops(dev); ++ ++ if (ops && ops->update_blink) ++ ops->update_blink(dev); ++ } ++ } ++ ++ return 0; ++} + #endif + + int led_default_state(void) +@@ -87,6 +120,10 @@ int led_default_state(void) + led_set_state(dev, LEDST_ON); + else if (!strncmp(default_state, "off", 3)) + led_set_state(dev, LEDST_OFF); ++#ifdef CONFIG_LED_BLINK ++ else if (!strncmp(default_state, "blink", 5)) ++ led_set_state(dev, LEDST_BLINK); ++#endif + /* default-state = "keep" : device is only probed */ + } + +diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c +index 93f6b913c647..a88efde71a69 100644 +--- a/drivers/led/led_gpio.c ++++ b/drivers/led/led_gpio.c +@@ -13,8 +13,45 @@ + + struct led_gpio_priv { + struct gpio_desc gpio; ++#ifdef CONFIG_LED_BLINK ++ int period; ++ int period_tick_count; ++ enum led_state_t state; ++#endif + }; + ++#ifdef CONFIG_LED_BLINK ++static int gpio_led_set_period(struct udevice *dev, int period_ms) ++{ ++ struct led_gpio_priv *priv = dev_get_priv(dev); ++ ++ if (period_ms < LED_BLINK_UPDATE_TICK_MS) ++ period_ms = LED_BLINK_PERIOD_DEFAULT_MS; ++ ++ priv->period = period_ms / LED_BLINK_UPDATE_TICK_MS; ++ priv->period_tick_count = priv->period; ++ ++ return 0; ++} ++ ++static int gpio_led_update_blink(struct udevice *dev) ++{ ++ struct led_gpio_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ if (priv->period_tick_count) { ++ priv->period_tick_count--; ++ } else { ++ ret = dm_gpio_get_value(&priv->gpio); ++ if (ret >= 0) ++ dm_gpio_set_value(&priv->gpio, !ret); ++ priv->period_tick_count = priv->period; ++ } ++ ++ return 0; ++} ++#endif ++ + static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) + { + struct led_gpio_priv *priv = dev_get_priv(dev); +@@ -25,6 +62,9 @@ static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) + switch (state) { + case LEDST_OFF: + case LEDST_ON: ++#ifdef CONFIG_LED_BLINK ++ case LEDST_BLINK: ++#endif + break; + case LEDST_TOGGLE: + ret = dm_gpio_get_value(&priv->gpio); +@@ -36,6 +76,20 @@ static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) + return -ENOSYS; + } + ++#ifdef CONFIG_LED_BLINK ++ priv->state = state; ++ ++ if (priv->state == LEDST_BLINK) { ++ if (priv->period < LED_BLINK_UPDATE_TICK_MS) { ++ priv->period = LED_BLINK_PERIOD_DEFAULT_MS / ++ LED_BLINK_UPDATE_TICK_MS; ++ priv->period_tick_count = priv->period; ++ } ++ ++ return dm_gpio_set_value(&priv->gpio, LEDST_ON); ++ } ++#endif ++ + return dm_gpio_set_value(&priv->gpio, state); + } + +@@ -46,6 +100,10 @@ static enum led_state_t gpio_led_get_state(struct udevice *dev) + + if (!dm_gpio_is_valid(&priv->gpio)) + return -EREMOTEIO; ++#ifdef CONFIG_LED_BLINK ++ if (priv->state == LEDST_BLINK) ++ return LEDST_BLINK; ++#endif + ret = dm_gpio_get_value(&priv->gpio); + if (ret < 0) + return ret; +@@ -117,6 +175,10 @@ static int led_gpio_bind(struct udevice *parent) + static const struct led_ops gpio_led_ops = { + .set_state = gpio_led_set_state, + .get_state = gpio_led_get_state, ++#ifdef CONFIG_LED_BLINK ++ .set_period = gpio_led_set_period, ++ .update_blink = gpio_led_update_blink, ++#endif + }; + + static const struct udevice_id led_gpio_ids[] = { +diff --git a/include/led.h b/include/led.h +index 7bfdddfd6fab..fb072c8b9f1a 100644 +--- a/include/led.h ++++ b/include/led.h +@@ -32,7 +32,6 @@ enum led_state_t { + #ifdef CONFIG_LED_BLINK + LEDST_BLINK, + #endif +- + LEDST_COUNT, + }; + +@@ -66,6 +65,17 @@ struct led_ops { + * @return 0 if OK, -ve on error + */ + int (*set_period)(struct udevice *dev, int period_ms); ++ ++ /** ++ * update_blink() - update blink output of an LED ++ * ++ * This should be called in every tick for updating blink behavior of an ++ * LED. ++ * ++ * @dev: LED device to change ++ * @return 0 if OK, -ve on error ++ */ ++ int (*update_blink)(struct udevice *dev); + #endif + }; + +@@ -115,4 +125,34 @@ int led_set_period(struct udevice *dev, int period_ms); + */ + int led_default_state(void); + ++#ifdef CONFIG_LED_BLINK ++#define LED_BLINK_UPDATE_TICK_MS 10 ++#define LED_BLINK_PERIOD_DEFAULT_MS 500 ++ ++/** ++ * led_blink_enable() - enable blinking for all LEDs that have the blink state ++ * ++ * This enables blinking for all LEDs that have the blink state. ++ * ++ */ ++void led_blink_enable(void); ++ ++/** ++ * led_blink_disable() - disable blinking for all LEDs that have the blink state ++ * ++ * This disables blinking for all LEDs that have the blink state. ++ * ++ */ ++void led_blink_disable(void); ++ ++/** ++ * led_blink_update() - timer tick callback for updating blink behavior ++ * ++ * This should be called on every LED_BLINK_UPDATE_TICK_MS for updating blink ++ * behavior of all LEDs that have the blink state. ++ * ++ */ ++int led_blink_update(void); ++#endif ++ + #endif +-- +2.17.1 + -- cgit v1.2.3