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] = {
 120        "DEVICE",
 121        "THOR",
 122        "UMS",
 123        "DFU",
 124        "EXIT"
 125};
 126
 127static char *
 128mode_info[BOOT_MODE_EXIT + 1] = {
 129        "info",
 130        "downloader",
 131        "mass storage",
 132        "firmware update",
 133        "and run normal boot"
 134};
 135
 136#define MODE_CMD_ARGC   4
 137
 138static char *
 139mode_cmd[BOOT_MODE_EXIT + 1][MODE_CMD_ARGC] = {
 140        {"", "", "", ""},
 141        {"thor", "0", "mmc", "0"},
 142        {"ums", "0", "mmc", "0"},
 143        {"dfu", "0", "mmc", "0"},
 144        {"", "", "", ""},
 145};
 146
 147static void display_board_info(void)
 148{
 149#ifdef CONFIG_GENERIC_MMC
 150        struct mmc *mmc = find_mmc_device(0);
 151#endif
 152        vidinfo_t *vid = &panel_info;
 153
 154        lcd_position_cursor(4, 4);
 155
 156        lcd_printf("%s\n\t", U_BOOT_VERSION);
 157        lcd_puts("\n\t\tBoard Info:\n");
 158#ifdef CONFIG_SYS_BOARD
 159        lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
 160#endif
 161#ifdef CONFIG_REVISION_TAG
 162        lcd_printf("\tBoard rev: %u\n", get_board_rev());
 163#endif
 164        lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
 165        lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
 166
 167#ifdef CONFIG_GENERIC_MMC
 168        if (mmc) {
 169                if (!mmc->capacity)
 170                        mmc_init(mmc);
 171
 172                lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
 173        }
 174#endif
 175        if (vid)
 176                lcd_printf("\tDisplay resolution: %u x % u\n",
 177                           vid->vl_col, vid->vl_row);
 178
 179        lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
 180}
 181
 182static int mode_leave_menu(int mode)
 183{
 184        char *exit_option;
 185        char *exit_boot = "boot";
 186        char *exit_back = "back";
 187        cmd_tbl_t *cmd;
 188        int cmd_result;
 189        int cmd_repeatable;
 190        int leave;
 191
 192        lcd_clear();
 193
 194        switch (mode) {
 195        case BOOT_MODE_EXIT:
 196                return 1;
 197        case BOOT_MODE_INFO:
 198                display_board_info();
 199                exit_option = exit_back;
 200                leave = 0;
 201                break;
 202        default:
 203                cmd = find_cmd(mode_cmd[mode][0]);
 204                if (cmd) {
 205                        printf("Enter: %s %s\n", mode_name[mode],
 206                                                 mode_info[mode]);
 207                        lcd_printf("\n\n\t%s %s\n", mode_name[mode],
 208                                                    mode_info[mode]);
 209                        lcd_puts("\n\tDo not turn off device before finish!\n");
 210
 211                        cmd_result = cmd_process(0, MODE_CMD_ARGC,
 212                                                 *(mode_cmd + mode),
 213                                                 &cmd_repeatable, NULL);
 214
 215                        if (cmd_result == CMD_RET_SUCCESS) {
 216                                printf("Command finished\n");
 217                                lcd_clear();
 218                                lcd_printf("\n\n\t%s finished\n",
 219                                           mode_name[mode]);
 220
 221                                exit_option = exit_boot;
 222                                leave = 1;
 223                        } else {
 224                                printf("Command error\n");
 225                                lcd_clear();
 226                                lcd_printf("\n\n\t%s command error\n",
 227                                           mode_name[mode]);
 228
 229                                exit_option = exit_back;
 230                                leave = 0;
 231                        }
 232                } else {
 233                        lcd_puts("\n\n\tThis mode is not supported.\n");
 234                        exit_option = exit_back;
 235                        leave = 0;
 236                }
 237        }
 238
 239        lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
 240
 241        /* Clear PWR button Rising edge interrupt status flag */
 242        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 243
 244        /* Wait for PWR key */
 245        while (!key_pressed(KEY_POWER))
 246                mdelay(1);
 247
 248        lcd_clear();
 249        return leave;
 250}
 251
 252static void display_download_menu(int mode)
 253{
 254        char *selection[BOOT_MODE_EXIT + 1];
 255        int i;
 256
 257        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 258                selection[i] = "[  ]";
 259
 260        selection[mode] = "[=>]";
 261
 262        lcd_clear();
 263        lcd_printf("\n\t\tDownload Mode Menu\n");
 264
 265        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 266                lcd_printf("\t%s  %s - %s\n\n", selection[i],
 267                                                mode_name[i],
 268                                                mode_info[i]);
 269}
 270
 271static void download_menu(void)
 272{
 273        int mode = 0;
 274        int last_mode = 0;
 275        int run;
 276        int key;
 277
 278        display_download_menu(mode);
 279
 280        while (1) {
 281                run = 0;
 282
 283                if (mode != last_mode)
 284                        display_download_menu(mode);
 285
 286                last_mode = mode;
 287                mdelay(100);
 288
 289                key = check_keys();
 290                switch (key) {
 291                case KEY_POWER:
 292                        run = 1;
 293                        break;
 294                case KEY_VOLUMEUP:
 295                        if (mode > 0)
 296                                mode--;
 297                        break;
 298                case KEY_VOLUMEDOWN:
 299                        if (mode < BOOT_MODE_EXIT)
 300                                mode++;
 301                        break;
 302                default:
 303                        break;
 304                }
 305
 306                if (run) {
 307                        if (mode_leave_menu(mode))
 308                                break;
 309
 310                        display_download_menu(mode);
 311                }
 312        }
 313
 314        lcd_clear();
 315}
 316
 317static void display_mode_info(void)
 318{
 319        lcd_position_cursor(4, 4);
 320        lcd_printf("%s\n", U_BOOT_VERSION);
 321        lcd_puts("\nDownload Mode Menu\n");
 322#ifdef CONFIG_SYS_BOARD
 323        lcd_printf("Board name: %s\n", CONFIG_SYS_BOARD);
 324#endif
 325        lcd_printf("Press POWER KEY to display MENU options.");
 326}
 327
 328static int boot_menu(void)
 329{
 330        int key = 0;
 331        int timeout = 10;
 332
 333        display_mode_info();
 334
 335        while (timeout--) {
 336                lcd_printf("\rNormal boot will start in: %d seconds.", timeout);
 337                mdelay(1000);
 338
 339                key = key_pressed(KEY_POWER);
 340                if (key)
 341                        break;
 342        }
 343
 344        lcd_clear();
 345
 346        /* If PWR pressed - show download menu */
 347        if (key) {
 348                printf("Power pressed - go to download menu\n");
 349                download_menu();
 350                printf("Download mode exit.\n");
 351        }
 352
 353        return 0;
 354}
 355
 356void check_boot_mode(void)
 357{
 358        int pwr_key;
 359
 360        pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
 361        if (!pwr_key)
 362                return;
 363
 364        /* Clear PWR button Rising edge interrupt status flag */
 365        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 366
 367        if (key_pressed(KEY_VOLUMEUP))
 368                boot_menu();
 369        else if (key_pressed(KEY_VOLUMEDOWN))
 370                mode_leave_menu(BOOT_MODE_THOR);
 371}
 372
 373void keys_init(void)
 374{
 375        /* Set direction to input */
 376        gpio_direction_input(KEY_VOL_UP_GPIO);
 377        gpio_direction_input(KEY_VOL_DOWN_GPIO);
 378}
 379#endif /* CONFIG_LCD_MENU */
 380
 381#ifdef CONFIG_CMD_BMP
 382void draw_logo(void)
 383{
 384        int x, y;
 385        ulong addr;
 386
 387        addr = panel_info.logo_addr;
 388        if (!addr) {
 389                error("There is no logo data.");
 390                return;
 391        }
 392
 393        if (panel_info.vl_width >= panel_info.logo_width) {
 394                x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
 395                x += panel_info.logo_x_offset; /* For X center align */
 396        } else {
 397                x = 0;
 398                printf("Warning: image width is bigger than display width\n");
 399        }
 400
 401        if (panel_info.vl_height >= panel_info.logo_height) {
 402                y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
 403                y += panel_info.logo_y_offset; /* For Y center align */
 404        } else {
 405                y = 0;
 406                printf("Warning: image height is bigger than display height\n");
 407        }
 408
 409        bmp_display(addr, x, y);
 410}
 411#endif /* CONFIG_CMD_BMP */
 412