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
 150#ifdef CONFIG_LCD
 151static int check_keys(void)
 152{
 153        int keys = 0;
 154
 155        if (key_pressed(KEY_POWER))
 156                keys += KEY_POWER;
 157        if (key_pressed(KEY_VOLUMEUP))
 158                keys += KEY_VOLUMEUP;
 159        if (key_pressed(KEY_VOLUMEDOWN))
 160                keys += KEY_VOLUMEDOWN;
 161
 162        return keys;
 163}
 164
 165/*
 166 * 0 BOOT_MODE_INFO
 167 * 1 BOOT_MODE_THOR
 168 * 2 BOOT_MODE_UMS
 169 * 3 BOOT_MODE_DFU
 170 * 4 BOOT_MODE_EXIT
 171 */
 172static char *
 173mode_name[BOOT_MODE_EXIT + 1][2] = {
 174        {"DEVICE", ""},
 175        {"THOR", "thor"},
 176        {"UMS", "ums"},
 177        {"DFU", "dfu"},
 178        {"GPT", "gpt"},
 179        {"ENV", "env"},
 180        {"EXIT", ""},
 181};
 182
 183static char *
 184mode_info[BOOT_MODE_EXIT + 1] = {
 185        "info",
 186        "downloader",
 187        "mass storage",
 188        "firmware update",
 189        "restore",
 190        "default",
 191        "and run normal boot"
 192};
 193
 194static char *
 195mode_cmd[BOOT_MODE_EXIT + 1] = {
 196        "",
 197        "thor 0 mmc 0",
 198        "ums 0 mmc 0",
 199        "dfu 0 mmc 0",
 200        "gpt write mmc 0 $partitions",
 201        "env default -a; saveenv",
 202        "",
 203};
 204
 205static void display_board_info(void)
 206{
 207#ifdef CONFIG_GENERIC_MMC
 208        struct mmc *mmc = find_mmc_device(0);
 209#endif
 210        vidinfo_t *vid = &panel_info;
 211
 212        lcd_position_cursor(4, 4);
 213
 214        lcd_printf("%s\n\t", U_BOOT_VERSION);
 215        lcd_puts("\n\t\tBoard Info:\n");
 216#ifdef CONFIG_SYS_BOARD
 217        lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
 218#endif
 219#ifdef CONFIG_REVISION_TAG
 220        lcd_printf("\tBoard rev: %u\n", get_board_rev());
 221#endif
 222        lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
 223        lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
 224
 225#ifdef CONFIG_GENERIC_MMC
 226        if (mmc) {
 227                if (!mmc->capacity)
 228                        mmc_init(mmc);
 229
 230                lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
 231        }
 232#endif
 233        if (vid)
 234                lcd_printf("\tDisplay resolution: %u x % u\n",
 235                           vid->vl_col, vid->vl_row);
 236
 237        lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
 238}
 239#endif
 240
 241static int mode_leave_menu(int mode)
 242{
 243#ifdef CONFIG_LCD
 244        char *exit_option;
 245        char *exit_reset = "reset";
 246        char *exit_back = "back";
 247        cmd_tbl_t *cmd;
 248        int cmd_result;
 249        int leave;
 250
 251        lcd_clear();
 252
 253        switch (mode) {
 254        case BOOT_MODE_EXIT:
 255                return 1;
 256        case BOOT_MODE_INFO:
 257                display_board_info();
 258                exit_option = exit_back;
 259                leave = 0;
 260                break;
 261        default:
 262                cmd = find_cmd(mode_name[mode][1]);
 263                if (cmd) {
 264                        printf("Enter: %s %s\n", mode_name[mode][0],
 265                               mode_info[mode]);
 266                        lcd_printf("\n\n\t%s %s\n", mode_name[mode][0],
 267                                   mode_info[mode]);
 268                        lcd_puts("\n\tDo not turn off device before finish!\n");
 269
 270                        cmd_result = run_command(mode_cmd[mode], 0);
 271
 272                        if (cmd_result == CMD_RET_SUCCESS) {
 273                                printf("Command finished\n");
 274                                lcd_clear();
 275                                lcd_printf("\n\n\t%s finished\n",
 276                                           mode_name[mode][0]);
 277
 278                                exit_option = exit_reset;
 279                                leave = 1;
 280                        } else {
 281                                printf("Command error\n");
 282                                lcd_clear();
 283                                lcd_printf("\n\n\t%s command error\n",
 284                                           mode_name[mode][0]);
 285
 286                                exit_option = exit_back;
 287                                leave = 0;
 288                        }
 289                } else {
 290                        lcd_puts("\n\n\tThis mode is not supported.\n");
 291                        exit_option = exit_back;
 292                        leave = 0;
 293                }
 294        }
 295
 296        lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
 297
 298        /* Clear PWR button Rising edge interrupt status flag */
 299        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 300
 301        /* Wait for PWR key */
 302        while (!key_pressed(KEY_POWER))
 303                mdelay(1);
 304
 305        lcd_clear();
 306        return leave;
 307#else
 308        return 0;
 309#endif
 310}
 311
 312#ifdef CONFIG_LCD
 313static void display_download_menu(int mode)
 314{
 315        char *selection[BOOT_MODE_EXIT + 1];
 316        int i;
 317
 318        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 319                selection[i] = "[  ]";
 320
 321        selection[mode] = "[=>]";
 322
 323        lcd_clear();
 324        lcd_printf("\n\n\t\tDownload Mode Menu\n\n");
 325
 326        for (i = 0; i <= BOOT_MODE_EXIT; i++)
 327                lcd_printf("\t%s  %s - %s\n\n", selection[i],
 328                           mode_name[i][0], mode_info[i]);
 329}
 330#endif
 331
 332static void download_menu(void)
 333{
 334#ifdef CONFIG_LCD
 335        int mode = 0;
 336        int last_mode = 0;
 337        int run;
 338        int key = 0;
 339        int timeout = 15; /* sec */
 340        int i;
 341
 342        display_download_menu(mode);
 343
 344        lcd_puts("\n");
 345
 346        /* Start count if no key is pressed */
 347        while (check_keys())
 348                continue;
 349
 350        while (timeout--) {
 351                lcd_printf("\r\tNormal boot will start in: %2.d seconds.",
 352                           timeout);
 353
 354                /* about 1000 ms in for loop */
 355                for (i = 0; i < 10; i++) {
 356                        mdelay(100);
 357                        key = check_keys();
 358                        if (key)
 359                                break;
 360                }
 361                if (key)
 362                        break;
 363        }
 364
 365        if (!key) {
 366                lcd_clear();
 367                return;
 368        }
 369
 370        while (1) {
 371                run = 0;
 372
 373                if (mode != last_mode)
 374                        display_download_menu(mode);
 375
 376                last_mode = mode;
 377                mdelay(200);
 378
 379                key = check_keys();
 380                switch (key) {
 381                case KEY_POWER:
 382                        run = 1;
 383                        break;
 384                case KEY_VOLUMEUP:
 385                        if (mode > 0)
 386                                mode--;
 387                        break;
 388                case KEY_VOLUMEDOWN:
 389                        if (mode < BOOT_MODE_EXIT)
 390                                mode++;
 391                        break;
 392                default:
 393                        break;
 394                }
 395
 396                if (run) {
 397                        if (mode_leave_menu(mode))
 398                                run_command("reset", 0);
 399
 400                        display_download_menu(mode);
 401                }
 402        }
 403
 404        lcd_clear();
 405#endif
 406}
 407
 408void check_boot_mode(void)
 409{
 410        int pwr_key;
 411
 412        pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
 413        if (!pwr_key)
 414                return;
 415
 416        /* Clear PWR button Rising edge interrupt status flag */
 417        power_key_pressed(KEY_PWR_INTERRUPT_REG);
 418
 419        if (key_pressed(KEY_VOLUMEUP))
 420                download_menu();
 421        else if (key_pressed(KEY_VOLUMEDOWN))
 422                mode_leave_menu(BOOT_MODE_THOR);
 423}
 424
 425void keys_init(void)
 426{
 427        /* Set direction to input */
 428        gpio_request(KEY_VOL_UP_GPIO, "volume-up");
 429        gpio_request(KEY_VOL_DOWN_GPIO, "volume-down");
 430        gpio_direction_input(KEY_VOL_UP_GPIO);
 431        gpio_direction_input(KEY_VOL_DOWN_GPIO);
 432}
 433#endif /* CONFIG_LCD_MENU */
 434
 435#ifdef CONFIG_CMD_BMP
 436void draw_logo(void)
 437{
 438        int x, y;
 439        ulong addr;
 440
 441        addr = panel_info.logo_addr;
 442        if (!addr) {
 443                error("There is no logo data.");
 444                return;
 445        }
 446
 447        if (panel_info.vl_width >= panel_info.logo_width) {
 448                x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
 449                x += panel_info.logo_x_offset; /* For X center align */
 450        } else {
 451                x = 0;
 452                printf("Warning: image width is bigger than display width\n");
 453        }
 454
 455        if (panel_info.vl_height >= panel_info.logo_height) {
 456                y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
 457                y += panel_info.logo_y_offset; /* For Y center align */
 458        } else {
 459                y = 0;
 460                printf("Warning: image height is bigger than display height\n");
 461        }
 462
 463        bmp_display(addr, x, y);
 464}
 465#endif /* CONFIG_CMD_BMP */
 466