123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- * Copyright (C) 2015-2017 Socionext Inc.
- * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <spl.h>
- #include <linux/log2.h>
- #include "../init.h"
- #include "../sbc/sbc-regs.h"
- #include "../sg-regs.h"
- #include "../soc-info.h"
- #include "boot-device.h"
- struct uniphier_boot_device_info {
- unsigned int soc_id;
- unsigned int boot_device_sel_shift;
- const struct uniphier_boot_device *boot_device_table;
- const unsigned int *boot_device_count;
- int (*boot_device_is_usb)(u32 pinmon);
- unsigned int (*boot_device_fixup)(unsigned int mode);
- int have_internal_stm;
- };
- static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
- #if defined(CONFIG_ARCH_UNIPHIER_SLD3)
- {
- .soc_id = UNIPHIER_SLD3_ID,
- .boot_device_sel_shift = 0,
- .boot_device_table = uniphier_sld3_boot_device_table,
- .boot_device_count = &uniphier_sld3_boot_device_count,
- .have_internal_stm = 0,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_LD4)
- {
- .soc_id = UNIPHIER_LD4_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_ld4_boot_device_table,
- .boot_device_count = &uniphier_ld4_boot_device_count,
- .have_internal_stm = 1,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_PRO4)
- {
- .soc_id = UNIPHIER_PRO4_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_ld4_boot_device_table,
- .boot_device_count = &uniphier_ld4_boot_device_count,
- .have_internal_stm = 0,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_SLD8)
- {
- .soc_id = UNIPHIER_SLD8_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_ld4_boot_device_table,
- .boot_device_count = &uniphier_ld4_boot_device_count,
- .have_internal_stm = 1,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_PRO5)
- {
- .soc_id = UNIPHIER_PRO5_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_pro5_boot_device_table,
- .boot_device_count = &uniphier_pro5_boot_device_count,
- .have_internal_stm = 0,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_PXS2)
- {
- .soc_id = UNIPHIER_PXS2_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_pxs2_boot_device_table,
- .boot_device_count = &uniphier_pxs2_boot_device_count,
- .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
- .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
- .have_internal_stm = 0,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_LD6B)
- {
- .soc_id = UNIPHIER_LD6B_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_pxs2_boot_device_table,
- .boot_device_count = &uniphier_pxs2_boot_device_count,
- .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
- .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
- .have_internal_stm = 1, /* STM on A-chip */
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_LD11)
- {
- .soc_id = UNIPHIER_LD11_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_ld11_boot_device_table,
- .boot_device_count = &uniphier_ld11_boot_device_count,
- .boot_device_is_usb = uniphier_ld11_boot_device_is_usb,
- .boot_device_fixup = uniphier_ld11_boot_device_fixup,
- .have_internal_stm = 1,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_LD20)
- {
- .soc_id = UNIPHIER_LD20_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_ld11_boot_device_table,
- .boot_device_count = &uniphier_ld11_boot_device_count,
- .boot_device_is_usb = uniphier_ld20_boot_device_is_usb,
- .boot_device_fixup = uniphier_ld11_boot_device_fixup,
- .have_internal_stm = 1,
- },
- #endif
- #if defined(CONFIG_ARCH_UNIPHIER_PXS3)
- {
- .soc_id = UNIPHIER_PXS3_ID,
- .boot_device_sel_shift = 1,
- .boot_device_table = uniphier_pxs3_boot_device_table,
- .boot_device_count = &uniphier_pxs3_boot_device_count,
- .boot_device_is_usb = uniphier_pxs3_boot_device_is_usb,
- .have_internal_stm = 0,
- },
- #endif
- };
- UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info,
- uniphier_boot_device_info)
- static unsigned int __uniphier_boot_device_raw(
- const struct uniphier_boot_device_info *info)
- {
- u32 pinmon;
- unsigned int boot_sel;
- if (boot_is_swapped())
- return BOOT_DEVICE_NOR;
- pinmon = readl(SG_PINMON0);
- if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon))
- return BOOT_DEVICE_USB;
- boot_sel = pinmon >> info->boot_device_sel_shift;
- BUG_ON(!is_power_of_2(*info->boot_device_count));
- boot_sel &= *info->boot_device_count - 1;
- return info->boot_device_table[boot_sel].boot_device;
- }
- unsigned int uniphier_boot_device_raw(void)
- {
- const struct uniphier_boot_device_info *info;
- info = uniphier_get_boot_device_info();
- if (!info) {
- pr_err("unsupported SoC\n");
- return BOOT_DEVICE_NONE;
- }
- return __uniphier_boot_device_raw(info);
- }
- u32 spl_boot_device(void)
- {
- const struct uniphier_boot_device_info *info;
- u32 raw_mode;
- info = uniphier_get_boot_device_info();
- if (!info) {
- pr_err("unsupported SoC\n");
- return BOOT_DEVICE_NONE;
- }
- raw_mode = __uniphier_boot_device_raw(info);
- return info->boot_device_fixup ?
- info->boot_device_fixup(raw_mode) : raw_mode;
- }
- int uniphier_have_internal_stm(void)
- {
- const struct uniphier_boot_device_info *info;
- info = uniphier_get_boot_device_info();
- if (!info) {
- pr_err("unsupported SoC\n");
- return -ENOTSUPP;
- }
- return info->have_internal_stm;
- }
- int uniphier_boot_from_backend(void)
- {
- return !!(readl(SG_PINMON0) & BIT(27));
- }
- #ifndef CONFIG_SPL_BUILD
- static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
- {
- const struct uniphier_boot_device_info *info;
- u32 pinmon;
- unsigned int boot_device_count, boot_sel;
- int i;
- info = uniphier_get_boot_device_info();
- if (!info) {
- pr_err("unsupported SoC\n");
- return CMD_RET_FAILURE;
- }
- if (uniphier_have_internal_stm())
- printf("STB Micon: %s\n",
- uniphier_boot_from_backend() ? "OFF" : "ON");
- printf("Boot Swap: %s\n", boot_is_swapped() ? "ON" : "OFF");
- pinmon = readl(SG_PINMON0);
- if (info->boot_device_is_usb)
- printf("USB Boot: %s\n",
- info->boot_device_is_usb(pinmon) ? "ON" : "OFF");
- boot_device_count = *info->boot_device_count;
- boot_sel = pinmon >> info->boot_device_sel_shift;
- boot_sel &= boot_device_count - 1;
- printf("\nBoot Mode Sel:\n");
- for (i = 0; i < boot_device_count; i++)
- printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i,
- info->boot_device_table[i].desc);
- return CMD_RET_SUCCESS;
- }
- U_BOOT_CMD(
- pinmon, 1, 1, do_pinmon,
- "pin monitor",
- ""
- );
- #endif /* !CONFIG_SPL_BUILD */
|