Commit d0f64bb8286739f9efd656cd2d63539106427f80

Authored by Ji Luo
1 parent 2b5a5ccffc

MA-17159 Implement bootloader menu for imx7ulp

According to the spec of android wear, the device MUST provides a
bootloader menu for debugging purpose.

This commit implements a simple bootloader menu based on imx7ulp_evk
revb board, the menu will show when booting with 'VOL+' key pressed,
users can press "VOL+" to choose the item, then press "ONOFF" key to
confirm.

Test: bootloader menu show on imx7ulp_evk revb.

Change-Id: I80638a43afa17e312e633b05888c62440380b42b
Signed-off-by: Ji Luo <ji.luo@nxp.com>

Showing 2 changed files with 115 additions and 1 deletions Side-by-side Diff

board/freescale/mx7ulp_evk/mx7ulp_evk.c
... ... @@ -14,6 +14,14 @@
14 14 #include <usb.h>
15 15 #include <dm.h>
16 16  
  17 +#ifdef CONFIG_BOOTLOADER_MENU
  18 +#include "video.h"
  19 +#include "dm/uclass.h"
  20 +#include "video_font_data.h"
  21 +#include "video_console.h"
  22 +#include "recovery.h"
  23 +#endif
  24 +
17 25 DECLARE_GLOBAL_DATA_PTR;
18 26  
19 27 #define UART_PAD_CTRL (PAD_CTL_PUS_UP)
... ... @@ -136,6 +144,15 @@
136 144 }
137 145 #endif
138 146  
  147 +#ifdef CONFIG_BOOTLOADER_MENU
  148 +static iomux_cfg_t const vol_pad[] = {
  149 + MX7ULP_PAD_PTA3__PTA3 | MUX_PAD_CTRL(PAD_CTL_IBE_ENABLE),
  150 +};
  151 +#define VOLP_GPIO IMX_GPIO_NR(1, 3)
  152 +bool is_vol_key_pressed(void);
  153 +int show_bootloader_menu(void);
  154 +#endif
  155 +
139 156 int board_late_init(void)
140 157 {
141 158 env_set("tee", "no");
... ... @@ -147,6 +164,16 @@
147 164 board_late_mmc_env_init();
148 165 #endif
149 166  
  167 +#ifdef CONFIG_BOOTLOADER_MENU
  168 + mx7ulp_iomux_setup_multiple_pads(vol_pad, ARRAY_SIZE(vol_pad));
  169 + if (gpio_request(VOLP_GPIO, "volp"))
  170 + printf("request error\n");
  171 + gpio_direction_input(VOLP_GPIO);
  172 +
  173 + if (is_vol_key_pressed())
  174 + show_bootloader_menu();
  175 +#endif
  176 +
150 177 return 0;
151 178 }
152 179  
... ... @@ -164,5 +191,87 @@
164 191 /* the onoff button is 'pressed' by default on evk board */
165 192 return (bool)(!(readl(SNVS_HPSR_REVB) & (0x1 << 6)));
166 193 }
167   -#endif
  194 +
  195 +#ifdef CONFIG_BOOTLOADER_MENU
  196 +char bootloader_menu[4][40] = {
  197 + " * Power off the device\n",
  198 + " * Start the device normally\n",
  199 + " * Restart the bootloader\n",
  200 + " * Boot into recovery mode\n"
  201 +};
  202 +
  203 +bool is_vol_key_pressed(void) {
  204 + int ret = 0;
  205 + ret = gpio_get_value(VOLP_GPIO);
  206 + return (bool)(!!ret);
  207 +}
  208 +
  209 +int show_bootloader_menu(void) {
  210 + struct udevice *dev, *dev_console;
  211 + uint32_t focus = 0, i;
  212 + bool stop_menu = false;
  213 +
  214 + /* clear screen first */
  215 + if (uclass_first_device_err(UCLASS_VIDEO, &dev)) {
  216 + printf("no video device found!\n");
  217 + return -1;
  218 + }
  219 + video_clear(dev);
  220 +
  221 + if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev_console)) {
  222 + printf("no text console device found!\n");
  223 + return -1;
  224 + }
  225 +
  226 + vidconsole_position_cursor(dev_console, 0, 1);
  227 + vidconsole_put_string(dev_console, "Press 'vol+' to choose an item, press\n");
  228 + vidconsole_put_string(dev_console, "power key to confirm:\n");
  229 + while (!stop_menu) {
  230 + /* reset the cursor position. */
  231 + vidconsole_position_cursor(dev_console, 0, 4);
  232 + /* show menu */
  233 + for (i = 0; i < 4; i++) {
  234 + /* reverse color for the 'focus' line. */
  235 + if (i == focus)
  236 + vidconsole_put_string(dev_console, "\x1b[7m");
  237 + /* show text */
  238 + vidconsole_put_string(dev_console, bootloader_menu[i]);
  239 + /* reset color back for the 'next' line. */
  240 + if (i == focus)
  241 + vidconsole_put_string(dev_console, "\x1b[0m");
  242 + }
  243 + /* check button status */
  244 + while (1) {
  245 + if (is_power_key_pressed()) {
  246 + switch (focus) {
  247 + case 0: /*TODO*/
  248 + case 1:
  249 + break;
  250 + case 2:
  251 + do_reset(NULL, 0, 0, NULL);
  252 + case 3:
  253 + board_recovery_setup();
  254 + break;
  255 + default:
  256 + break;
  257 + }
  258 + stop_menu = true;
  259 + break;
  260 + } else if (is_vol_key_pressed()) {
  261 + focus++;
  262 + printf("\nfocus is %d\n", focus);
  263 + if (focus > 3)
  264 + focus = 0;
  265 + mdelay(400);
  266 + break;
  267 + }
  268 + }
  269 + }
  270 +
  271 + /* clear screen before exit */
  272 + video_clear(dev);
  273 + return 0;
  274 +}
  275 +#endif /* CONFIG_BOOTLOADER_MENU */
  276 +#endif /* CONFIG_ANDROID_SUPPORT*/
... ... @@ -358,6 +358,11 @@
358 358 help
359 359 The time of avb warning logo will last (s).
360 360  
  361 +config BOOTLOADER_MENU
  362 + bool "Enable bootloader menu for android device"
  363 + help
  364 + bootloader menu feature for android device.
  365 +
361 366 config APPEND_BOOTARGS
362 367 bool "Append bootargs support"
363 368