1784548efSMasahiro Yamada /* 2784548efSMasahiro Yamada * Copyright (C) 2015-2017 Socionext Inc. 3784548efSMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4784548efSMasahiro Yamada * 5784548efSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6784548efSMasahiro Yamada */ 7784548efSMasahiro Yamada 8784548efSMasahiro Yamada #include <common.h> 9784548efSMasahiro Yamada #include <spl.h> 10784548efSMasahiro Yamada #include <linux/log2.h> 11784548efSMasahiro Yamada 12784548efSMasahiro Yamada #include "../init.h" 13784548efSMasahiro Yamada #include "../sbc/sbc-regs.h" 14784548efSMasahiro Yamada #include "../sg-regs.h" 15784548efSMasahiro Yamada #include "../soc-info.h" 16784548efSMasahiro Yamada #include "boot-device.h" 17784548efSMasahiro Yamada 18784548efSMasahiro Yamada struct uniphier_boot_device_info { 19784548efSMasahiro Yamada unsigned int soc_id; 20784548efSMasahiro Yamada unsigned int boot_device_sel_shift; 21784548efSMasahiro Yamada const struct uniphier_boot_device *boot_device_table; 22784548efSMasahiro Yamada const unsigned int *boot_device_count; 23784548efSMasahiro Yamada int (*boot_device_is_usb)(u32 pinmon); 24784548efSMasahiro Yamada unsigned int (*boot_device_fixup)(unsigned int mode); 2563754842SMasahiro Yamada int have_internal_stm; 26784548efSMasahiro Yamada }; 27784548efSMasahiro Yamada 28784548efSMasahiro Yamada static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 29784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_SLD3) 30784548efSMasahiro Yamada { 31784548efSMasahiro Yamada .soc_id = UNIPHIER_SLD3_ID, 32784548efSMasahiro Yamada .boot_device_sel_shift = 0, 33784548efSMasahiro Yamada .boot_device_table = uniphier_sld3_boot_device_table, 34784548efSMasahiro Yamada .boot_device_count = &uniphier_sld3_boot_device_count, 3563754842SMasahiro Yamada .have_internal_stm = 0, 36784548efSMasahiro Yamada }, 37784548efSMasahiro Yamada #endif 38784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD4) 39784548efSMasahiro Yamada { 40784548efSMasahiro Yamada .soc_id = UNIPHIER_LD4_ID, 41784548efSMasahiro Yamada .boot_device_sel_shift = 1, 42784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 43784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 4463754842SMasahiro Yamada .have_internal_stm = 1, 45784548efSMasahiro Yamada }, 46784548efSMasahiro Yamada #endif 47784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO4) 48784548efSMasahiro Yamada { 49784548efSMasahiro Yamada .soc_id = UNIPHIER_PRO4_ID, 50784548efSMasahiro Yamada .boot_device_sel_shift = 1, 51784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 52784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 5363754842SMasahiro Yamada .have_internal_stm = 0, 54784548efSMasahiro Yamada }, 55784548efSMasahiro Yamada #endif 56784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_SLD8) 57784548efSMasahiro Yamada { 58784548efSMasahiro Yamada .soc_id = UNIPHIER_SLD8_ID, 59784548efSMasahiro Yamada .boot_device_sel_shift = 1, 60784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 61784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 6263754842SMasahiro Yamada .have_internal_stm = 1, 63784548efSMasahiro Yamada }, 64784548efSMasahiro Yamada #endif 65784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO5) 66784548efSMasahiro Yamada { 67784548efSMasahiro Yamada .soc_id = UNIPHIER_PRO5_ID, 68784548efSMasahiro Yamada .boot_device_sel_shift = 1, 69784548efSMasahiro Yamada .boot_device_table = uniphier_pro5_boot_device_table, 70784548efSMasahiro Yamada .boot_device_count = &uniphier_pro5_boot_device_count, 7163754842SMasahiro Yamada .have_internal_stm = 0, 72784548efSMasahiro Yamada }, 73784548efSMasahiro Yamada #endif 74784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PXS2) 75784548efSMasahiro Yamada { 76784548efSMasahiro Yamada .soc_id = UNIPHIER_PXS2_ID, 77784548efSMasahiro Yamada .boot_device_sel_shift = 1, 78784548efSMasahiro Yamada .boot_device_table = uniphier_pxs2_boot_device_table, 79784548efSMasahiro Yamada .boot_device_count = &uniphier_pxs2_boot_device_count, 80784548efSMasahiro Yamada .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb, 81784548efSMasahiro Yamada .boot_device_fixup = uniphier_pxs2_boot_device_fixup, 8263754842SMasahiro Yamada .have_internal_stm = 0, 83784548efSMasahiro Yamada }, 84784548efSMasahiro Yamada #endif 85784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD6B) 86784548efSMasahiro Yamada { 87784548efSMasahiro Yamada .soc_id = UNIPHIER_LD6B_ID, 88784548efSMasahiro Yamada .boot_device_sel_shift = 1, 89784548efSMasahiro Yamada .boot_device_table = uniphier_pxs2_boot_device_table, 90784548efSMasahiro Yamada .boot_device_count = &uniphier_pxs2_boot_device_count, 91784548efSMasahiro Yamada .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb, 92784548efSMasahiro Yamada .boot_device_fixup = uniphier_pxs2_boot_device_fixup, 9363754842SMasahiro Yamada .have_internal_stm = 1, /* STM on A-chip */ 94784548efSMasahiro Yamada }, 95784548efSMasahiro Yamada #endif 96784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD11) 97784548efSMasahiro Yamada { 98784548efSMasahiro Yamada .soc_id = UNIPHIER_LD11_ID, 99784548efSMasahiro Yamada .boot_device_sel_shift = 1, 100784548efSMasahiro Yamada .boot_device_table = uniphier_ld11_boot_device_table, 101784548efSMasahiro Yamada .boot_device_count = &uniphier_ld11_boot_device_count, 102784548efSMasahiro Yamada .boot_device_is_usb = uniphier_ld11_boot_device_is_usb, 103784548efSMasahiro Yamada .boot_device_fixup = uniphier_ld11_boot_device_fixup, 10463754842SMasahiro Yamada .have_internal_stm = 1, 105784548efSMasahiro Yamada }, 106784548efSMasahiro Yamada #endif 107784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD20) 108784548efSMasahiro Yamada { 109784548efSMasahiro Yamada .soc_id = UNIPHIER_LD20_ID, 110784548efSMasahiro Yamada .boot_device_sel_shift = 1, 111784548efSMasahiro Yamada .boot_device_table = uniphier_ld11_boot_device_table, 112784548efSMasahiro Yamada .boot_device_count = &uniphier_ld11_boot_device_count, 113784548efSMasahiro Yamada .boot_device_is_usb = uniphier_ld20_boot_device_is_usb, 114784548efSMasahiro Yamada .boot_device_fixup = uniphier_ld11_boot_device_fixup, 11563754842SMasahiro Yamada .have_internal_stm = 1, 116784548efSMasahiro Yamada }, 117784548efSMasahiro Yamada #endif 118*81afa9c9SMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PXS3) 119*81afa9c9SMasahiro Yamada { 120*81afa9c9SMasahiro Yamada .soc_id = UNIPHIER_PXS3_ID, 121*81afa9c9SMasahiro Yamada .boot_device_sel_shift = 1, 122*81afa9c9SMasahiro Yamada .boot_device_table = uniphier_pxs3_boot_device_table, 123*81afa9c9SMasahiro Yamada .boot_device_count = &uniphier_pxs3_boot_device_count, 124*81afa9c9SMasahiro Yamada .boot_device_is_usb = uniphier_pxs3_boot_device_is_usb, 125*81afa9c9SMasahiro Yamada .have_internal_stm = 0, 126*81afa9c9SMasahiro Yamada }, 127*81afa9c9SMasahiro Yamada #endif 128784548efSMasahiro Yamada }; 129784548efSMasahiro Yamada UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info, 130784548efSMasahiro Yamada uniphier_boot_device_info) 131784548efSMasahiro Yamada 132784548efSMasahiro Yamada static unsigned int __uniphier_boot_device_raw( 133784548efSMasahiro Yamada const struct uniphier_boot_device_info *info) 134784548efSMasahiro Yamada { 135784548efSMasahiro Yamada u32 pinmon; 136784548efSMasahiro Yamada unsigned int boot_sel; 137784548efSMasahiro Yamada 138784548efSMasahiro Yamada if (boot_is_swapped()) 139784548efSMasahiro Yamada return BOOT_DEVICE_NOR; 140784548efSMasahiro Yamada 141784548efSMasahiro Yamada pinmon = readl(SG_PINMON0); 142784548efSMasahiro Yamada 143784548efSMasahiro Yamada if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon)) 144784548efSMasahiro Yamada return BOOT_DEVICE_USB; 145784548efSMasahiro Yamada 146784548efSMasahiro Yamada boot_sel = pinmon >> info->boot_device_sel_shift; 147784548efSMasahiro Yamada 148784548efSMasahiro Yamada BUG_ON(!is_power_of_2(*info->boot_device_count)); 149784548efSMasahiro Yamada boot_sel &= *info->boot_device_count - 1; 150784548efSMasahiro Yamada 151784548efSMasahiro Yamada return info->boot_device_table[boot_sel].boot_device; 152784548efSMasahiro Yamada } 153784548efSMasahiro Yamada 154784548efSMasahiro Yamada unsigned int uniphier_boot_device_raw(void) 155784548efSMasahiro Yamada { 156784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 157784548efSMasahiro Yamada 158784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 159784548efSMasahiro Yamada if (!info) { 160784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 161784548efSMasahiro Yamada return BOOT_DEVICE_NONE; 162784548efSMasahiro Yamada } 163784548efSMasahiro Yamada 164784548efSMasahiro Yamada return __uniphier_boot_device_raw(info); 165784548efSMasahiro Yamada } 166784548efSMasahiro Yamada 167784548efSMasahiro Yamada u32 spl_boot_device(void) 168784548efSMasahiro Yamada { 169784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 170784548efSMasahiro Yamada u32 raw_mode; 171784548efSMasahiro Yamada 172784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 173784548efSMasahiro Yamada if (!info) { 174784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 175784548efSMasahiro Yamada return BOOT_DEVICE_NONE; 176784548efSMasahiro Yamada } 177784548efSMasahiro Yamada 178784548efSMasahiro Yamada raw_mode = __uniphier_boot_device_raw(info); 179784548efSMasahiro Yamada 180784548efSMasahiro Yamada return info->boot_device_fixup ? 181784548efSMasahiro Yamada info->boot_device_fixup(raw_mode) : raw_mode; 182784548efSMasahiro Yamada } 183784548efSMasahiro Yamada 18463754842SMasahiro Yamada int uniphier_have_internal_stm(void) 18563754842SMasahiro Yamada { 18663754842SMasahiro Yamada const struct uniphier_boot_device_info *info; 18763754842SMasahiro Yamada 18863754842SMasahiro Yamada info = uniphier_get_boot_device_info(); 18963754842SMasahiro Yamada if (!info) { 19063754842SMasahiro Yamada pr_err("unsupported SoC\n"); 19163754842SMasahiro Yamada return -ENOTSUPP; 19263754842SMasahiro Yamada } 19363754842SMasahiro Yamada 19463754842SMasahiro Yamada return info->have_internal_stm; 19563754842SMasahiro Yamada } 19663754842SMasahiro Yamada 19763754842SMasahiro Yamada int uniphier_boot_from_backend(void) 19863754842SMasahiro Yamada { 19963754842SMasahiro Yamada return !!(readl(SG_PINMON0) & BIT(27)); 20063754842SMasahiro Yamada } 20163754842SMasahiro Yamada 202784548efSMasahiro Yamada #ifndef CONFIG_SPL_BUILD 203784548efSMasahiro Yamada 204784548efSMasahiro Yamada static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 205784548efSMasahiro Yamada { 206784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 207784548efSMasahiro Yamada u32 pinmon; 208784548efSMasahiro Yamada unsigned int boot_device_count, boot_sel; 209784548efSMasahiro Yamada int i; 210784548efSMasahiro Yamada 211784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 212784548efSMasahiro Yamada if (!info) { 213784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 214784548efSMasahiro Yamada return CMD_RET_FAILURE; 215784548efSMasahiro Yamada } 216784548efSMasahiro Yamada 21763754842SMasahiro Yamada if (uniphier_have_internal_stm()) 21863754842SMasahiro Yamada printf("STB Micon: %s\n", 21963754842SMasahiro Yamada uniphier_boot_from_backend() ? "OFF" : "ON"); 22063754842SMasahiro Yamada 22163754842SMasahiro Yamada printf("Boot Swap: %s\n", boot_is_swapped() ? "ON" : "OFF"); 222784548efSMasahiro Yamada 223784548efSMasahiro Yamada pinmon = readl(SG_PINMON0); 224784548efSMasahiro Yamada 225784548efSMasahiro Yamada if (info->boot_device_is_usb) 22663754842SMasahiro Yamada printf("USB Boot: %s\n", 227784548efSMasahiro Yamada info->boot_device_is_usb(pinmon) ? "ON" : "OFF"); 228784548efSMasahiro Yamada 229784548efSMasahiro Yamada boot_device_count = *info->boot_device_count; 230784548efSMasahiro Yamada 231784548efSMasahiro Yamada boot_sel = pinmon >> info->boot_device_sel_shift; 232784548efSMasahiro Yamada boot_sel &= boot_device_count - 1; 233784548efSMasahiro Yamada 23463754842SMasahiro Yamada printf("\nBoot Mode Sel:\n"); 235784548efSMasahiro Yamada for (i = 0; i < boot_device_count; i++) 236784548efSMasahiro Yamada printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i, 237784548efSMasahiro Yamada info->boot_device_table[i].desc); 238784548efSMasahiro Yamada 239784548efSMasahiro Yamada return CMD_RET_SUCCESS; 240784548efSMasahiro Yamada } 241784548efSMasahiro Yamada 242784548efSMasahiro Yamada U_BOOT_CMD( 243784548efSMasahiro Yamada pinmon, 1, 1, do_pinmon, 244784548efSMasahiro Yamada "pin monitor", 245784548efSMasahiro Yamada "" 246784548efSMasahiro Yamada ); 247784548efSMasahiro Yamada 248784548efSMasahiro Yamada #endif /* !CONFIG_SPL_BUILD */ 249