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