uboot/board/samsung/common/misc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Samsung Electronics
   3 * Przemyslaw Marczak <p.marczak@samsung.com>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <lcd.h>
  10#include <libtizen.h>
  11#include <samsung/misc.h>
  12#include <errno.h>
  13#include <version.h>
  14#include <linux/sizes.h>
  15#include <asm/arch/cpu.h>
  16#include <asm/arch/gpio.h>
  17#include <asm/gpio.h>
  18#include <linux/input.h>
  19#include <power/pmic.h>
  20#include <mmc.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
  25void set_board_info(void)
  26{
  27        char info[64];
  28
  29        snprintf(info, ARRAY_SIZE(info), "%d.%d", s5p_cpu_rev & 0x0f,
  30                 (s5p_cpu_rev & 0xf0) >> 0x04);
  31        setenv("soc_rev", info);
  32
  33        snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);
  34        setenv("soc_id", info);
  35
  36#ifdef CONFIG_REVISION_TAG
  37        snprintf(info, ARRAY_SIZE(info), "%x", get_board_rev());
  38        setenv("board_rev", info);
  39#endif
  40#ifdef CONFIG_OF_LIBFDT
  41        snprintf(info, ARRAY_SIZE(info),  "%s%x-%s.dtb",
  42                 CONFIG_SYS_SOC, s5p_cpu_id, CONFIG_SYS_BOARD);
  43        setenv("fdtfile", info);
  44#endif
  45}
  46#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */
  47
  48#ifdef CONFIG_LCD_MENU
  49static int power_key_pressed(u32 reg)
  50{
  51        struct pmic *pmic;
  52        u32 status;
  53        u32 mask;
  54
  55        pmic = pmic_get(KEY_PWR_PMIC_NAME);
  56        if (!pmic) {
  57                printf("%s: Not found\n", KEY_PWR_PMIC_NAME);
  58                return 0;
  59        }
  60
  61        if (pmic_probe(pmic))
  62                return 0;
  63
  64        if (reg == KEY_PWR_STATUS_REG)
  65                mask = KEY_PWR_STATUS_MASK;
  66        else
  67                mask = KEY_PWR_INTERRUPT_MASK;
  68
  69        if (pmic_reg_read(pmic, reg, &status))
  70                return 0;
  71
  72        return !!(status & mask);
  73}
  74
  75static int key_pressed(int key)
  76{
  77        int value;
  78
  79        switch (key) {
  80        case KEY_POWER:
  81                value = power_key_pressed(KEY_PWR_INTERRUPT_REG);
  82                break;
  83        case KEY_VOLUMEUP:
  84                value = !gpio_get_value(KEY_VOL_UP_GPIO);
  85                break;
  86        case KEY_VOLUMEDOWN:
  87                value = !gpio_get_value(KEY_VOL_DOWN_GPIO);
  88                break;
  89        default:
  90                value = 0;
  91                break;
  92        }
  93
  94        return value;
  95}
  96
  97static int check_keys(void)
  98{
  99        int keys = 0;
 100
 101        if (key_pressed(KEY_POWER))
 102                keys += KEY_POWER;
 103        if (key_pressed(KEY_VOLUMEUP))
 104                keys += KEY_VOLUMEUP;
 105        if (key_pressed(KEY_VOLUMEDOWN))
 106                keys += KEY_VOLUMEDOWN;
 107
 108        return keys;
 109}
 110
 111/*
 112 * 0 BOOT_MODE_INFO
 113 * 1 BOOT_MODE_THOR
 114 * 2 BOOT_MODE_UMS
 115 * 3 BOOT_MODE_DFU
 116 * 4 BOOT_MODE_EXIT
 117 */
 118static char *
 119mode_name[BOOT_MODE_EXIT + 1][2] = {
 120        {"DEVICE", ""},
 121        {"THOR", "thor"},
 122        {"UMS", "ums"},
 123        {"DFU", "dfu"},
 124        {"GPT", "gpt"},
 125        {"ENV", "env"},
 126        {"EXIT", ""},
 127};
 128
 129static char *
 130mode_info[BOOT_MODE_EXIT + 1] = {
 131        "info",
 132        "downloader",
 133        "mass storage",
 134        "firmware update",
 135        "restore",
 136        "default",
 137        "and run normal boot"
 138};
 139
 140static char *
 141mode_cmd[BOOT_MODE_EXIT + 1] = {
 142        "",
 143        "thor 0 mmc 0",
 144        "ums 0 mmc 0",
 145        "dfu 0 mmc 0",
 146        "gpt write mmc 0 $partitions",
 147        "env default -a; saveenv",
 148        "",
 149};
 150
 151static void display_board_info(void)
 152{
 153#ifdef CONFIG_GENERIC_MMC
 154        struct mmc *mmc = find_mmc_device(0);
 155#endif
 156        vidinfo_t *vid = &panel_info;
 157
 158        lcd_position_cursor(4, 4);
 159
 160        lcd_printf("%s\n\t", U_BOOT_VERSION);
 161        lcd_puts("\n\t\tBoard Info:\n");
 162#ifdef CONFIG_SYS_BOARD
 163        lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
 164#endif
 165#ifdef CONFIG_REVISION_TAG
 166        lcd_printf("\tBoard rev: %u\n", get_board_rev());
 167#endif
 168        lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
 169        lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
 170
 171#ifdef CONFIG_GENERIC_MMC
 172        if (mmc) {
 173                if (!mmc->capacity)
 174                        mmc_init(mmc);
 175
 176                lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
 177        }
 178#endif
 179        if (vid)
 180                lcd_printf("\tDisplay resolution: %u x % u\n",
 181                           vid->vl_col, vid->vl_row);
 182
 183        lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
 184}
 185
 186static int mode_leave_menu(int mode)
 187{
 188        char *exit_option;
 189        char *exit_reset = "reset";
 190        char *exit_back = "back";
 191        cmd_tbl_t *cmd;
 192        int cmd_result;
 193        int leave;
 194
 195        lcd_clear();
 196
 197        switch (mode) {
 198        case BOOT_MODE_EXIT:
 199                return 1;
 200        case BOOT_MODE_INFO:
 201                display_board_info();
 202                exit_option = exit_back;
 203                leave = 0;
 204                break;
 205        default:
 206                cmd = find_cmd(mode_name[mode][1]);
 207                if (cmd) {
 208                        printf("Enter: %s %s\n", mode_name[mode][0],
 209                                                 mode_info[mode]);
 210                        lcd_printf("\n\n\t%s %s\n", mode_name[mode][0],
 211                                                    mode_info[mode]);
 212                        lcd_puts("\n\tDo not turn off device before finish!\n");
 213
 214                        cmd_result = run_command(mode_cmd[mode], 0);
 215
 216                        if (cmd_result == CMD_RET_SUCCESS) {
 217                                printf("Command finished\n");
 218                                lcd_clear();
 219                                lcd_printf("\n\n\t%s finished\n",
 220                                           mode_name[mode][0]);
 221
 222                                exit_option = exit_reset;
 223                                leave = 1;
 224                        } else {
 225                                printf("Command error\n");
 226                                lcd_clear();
 227                                lcd_printf("\n\n\t%s command error\n",
 228                                           mode_name[mode][0]);
 229
 230                                exit_option = exit_back;
 231                                leave = 0;
 232                        }
 233                } else {
 234                        lcd_puts("\n\n\tThis mode is not supported.\n");
 235                        exit_option = exit_back;
 236                        leave = 0;
 237                }
 238        }
 239
 240        lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
 241
 242        /* Clear PWR button Rising edge interrupt status flag */
 243        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 244
 245        /* Wait for PWR key */
 246        while (!key_pressed(KEY_POWER))
 247                mdelay(1);
 248
 249        lcd_clear();
 250        return leave;
 251}
 252
 253static void display_download_menu(int mode)
 254{
 255        char *selection[BOOT_MODE_EXIT + 1];
 256        int i;
 257
 258        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 259                selection[i] = "[  ]";
 260
 261        selection[mode] = "[=>]";
 262
 263        lcd_clear();
 264        lcd_printf("\n\n\t\tDownload Mode Menu\n\n");
 265
 266        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 267                lcd_printf("\t%s  %s - %s\n\n", selection[i],
 268                                                mode_name[i][0],
 269                                                mode_info[i]);
 270}
 271
 272static void download_menu(void)
 273{
 274        int mode = 0;
 275        int last_mode = 0;
 276        int run;
 277        int key = 0;
 278        int timeout = 15; /* sec */
 279        int i;
 280
 281        display_download_menu(mode);
 282
 283        lcd_puts("\n");
 284
 285        /* Start count if no key is pressed */
 286        while (check_keys())
 287                continue;
 288
 289        while (timeout--) {
 290                lcd_printf("\r\tNormal boot will start in: %2.d seconds.",
 291                           timeout);
 292
 293                /* about 1000 ms in for loop */
 294                for (i = 0; i < 10; i++) {
 295                        mdelay(100);
 296                        key = check_keys();
 297                        if (key)
 298                                break;
 299                }
 300                if (key)
 301                        break;
 302        }
 303
 304        if (!key) {
 305                lcd_clear();
 306                return;
 307        }
 308
 309        while (1) {
 310                run = 0;
 311
 312                if (mode != last_mode)
 313                        display_download_menu(mode);
 314
 315                last_mode = mode;
 316                mdelay(200);
 317
 318                key = check_keys();
 319                switch (key) {
 320                case KEY_POWER:
 321                        run = 1;
 322                        break;
 323                case KEY_VOLUMEUP:
 324                        if (mode > 0)
 325                                mode--;
 326                        break;
 327                case KEY_VOLUMEDOWN:
 328                        if (mode < BOOT_MODE_EXIT)
 329                                mode++;
 330                        break;
 331                default:
 332                        break;
 333                }
 334
 335                if (run) {
 336                        if (mode_leave_menu(mode))
 337                                run_command("reset", 0);
 338
 339                        display_download_menu(mode);
 340                }
 341        }
 342
 343        lcd_clear();
 344}
 345
 346void check_boot_mode(void)
 347{
 348        int pwr_key;
 349
 350        pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
 351        if (!pwr_key)
 352                return;
 353
 354        /* Clear PWR button Rising edge interrupt status flag */
 355        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 356
 357        if (key_pressed(KEY_VOLUMEUP))
 358                download_menu();
 359        else if (key_pressed(KEY_VOLUMEDOWN))
 360                mode_leave_menu(BOOT_MODE_THOR);
 361}
 362
 363void keys_init(void)
 364{
 365        /* Set direction to input */
 366        gpio_direction_input(KEY_VOL_UP_GPIO);
 367        gpio_direction_input(KEY_VOL_DOWN_GPIO);
 368}
 369#endif /* CONFIG_LCD_MENU */
 370
 371#ifdef CONFIG_CMD_BMP
 372void draw_logo(void)
 373{
 374        int x, y;
 375        ulong addr;
 376
 377        addr = panel_info.logo_addr;
 378        if (!addr) {
 379                error("There is no logo data.");
 380                return;
 381        }
 382
 383        if (panel_info.vl_width >= panel_info.logo_width) {
 384                x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
 385                x += panel_info.logo_x_offset; /* For X center align */
 386        } else {
 387                x = 0;
 388                printf("Warning: image width is bigger than display width\n");
 389        }
 390
 391        if (panel_info.vl_height >= panel_info.logo_height) {
 392                y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
 393                y += panel_info.logo_y_offset; /* For Y center align */
 394        } else {
 395                y = 0;
 396                printf("Warning: image height is bigger than display height\n");
 397        }
 398
 399        bmp_display(addr, x, y);
 400}
 401#endif /* CONFIG_CMD_BMP */
 402