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