1*784548efSMasahiro Yamada /* 2*784548efSMasahiro Yamada * Copyright (C) 2015-2017 Socionext Inc. 3*784548efSMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4*784548efSMasahiro Yamada * 5*784548efSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6*784548efSMasahiro Yamada */ 7*784548efSMasahiro Yamada 8*784548efSMasahiro Yamada #include <common.h> 9*784548efSMasahiro Yamada #include <spl.h> 10*784548efSMasahiro Yamada #include <linux/log2.h> 11*784548efSMasahiro Yamada 12*784548efSMasahiro Yamada #include "../init.h" 13*784548efSMasahiro Yamada #include "../sbc/sbc-regs.h" 14*784548efSMasahiro Yamada #include "../sg-regs.h" 15*784548efSMasahiro Yamada #include "../soc-info.h" 16*784548efSMasahiro Yamada #include "boot-device.h" 17*784548efSMasahiro Yamada 18*784548efSMasahiro Yamada struct uniphier_boot_device_info { 19*784548efSMasahiro Yamada unsigned int soc_id; 20*784548efSMasahiro Yamada unsigned int boot_device_sel_shift; 21*784548efSMasahiro Yamada const struct uniphier_boot_device *boot_device_table; 22*784548efSMasahiro Yamada const unsigned int *boot_device_count; 23*784548efSMasahiro Yamada int (*boot_device_is_usb)(u32 pinmon); 24*784548efSMasahiro Yamada unsigned int (*boot_device_fixup)(unsigned int mode); 25*784548efSMasahiro Yamada }; 26*784548efSMasahiro Yamada 27*784548efSMasahiro Yamada static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 28*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_SLD3) 29*784548efSMasahiro Yamada { 30*784548efSMasahiro Yamada .soc_id = UNIPHIER_SLD3_ID, 31*784548efSMasahiro Yamada .boot_device_sel_shift = 0, 32*784548efSMasahiro Yamada .boot_device_table = uniphier_sld3_boot_device_table, 33*784548efSMasahiro Yamada .boot_device_count = &uniphier_sld3_boot_device_count, 34*784548efSMasahiro Yamada }, 35*784548efSMasahiro Yamada #endif 36*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD4) 37*784548efSMasahiro Yamada { 38*784548efSMasahiro Yamada .soc_id = UNIPHIER_LD4_ID, 39*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 40*784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 41*784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 42*784548efSMasahiro Yamada }, 43*784548efSMasahiro Yamada #endif 44*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO4) 45*784548efSMasahiro Yamada { 46*784548efSMasahiro Yamada .soc_id = UNIPHIER_PRO4_ID, 47*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 48*784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 49*784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 50*784548efSMasahiro Yamada }, 51*784548efSMasahiro Yamada #endif 52*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_SLD8) 53*784548efSMasahiro Yamada { 54*784548efSMasahiro Yamada .soc_id = UNIPHIER_SLD8_ID, 55*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 56*784548efSMasahiro Yamada .boot_device_table = uniphier_ld4_boot_device_table, 57*784548efSMasahiro Yamada .boot_device_count = &uniphier_ld4_boot_device_count, 58*784548efSMasahiro Yamada }, 59*784548efSMasahiro Yamada #endif 60*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PRO5) 61*784548efSMasahiro Yamada { 62*784548efSMasahiro Yamada .soc_id = UNIPHIER_PRO5_ID, 63*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 64*784548efSMasahiro Yamada .boot_device_table = uniphier_pro5_boot_device_table, 65*784548efSMasahiro Yamada .boot_device_count = &uniphier_pro5_boot_device_count, 66*784548efSMasahiro Yamada }, 67*784548efSMasahiro Yamada #endif 68*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_PXS2) 69*784548efSMasahiro Yamada { 70*784548efSMasahiro Yamada .soc_id = UNIPHIER_PXS2_ID, 71*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 72*784548efSMasahiro Yamada .boot_device_table = uniphier_pxs2_boot_device_table, 73*784548efSMasahiro Yamada .boot_device_count = &uniphier_pxs2_boot_device_count, 74*784548efSMasahiro Yamada .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb, 75*784548efSMasahiro Yamada .boot_device_fixup = uniphier_pxs2_boot_device_fixup, 76*784548efSMasahiro Yamada }, 77*784548efSMasahiro Yamada #endif 78*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD6B) 79*784548efSMasahiro Yamada { 80*784548efSMasahiro Yamada .soc_id = UNIPHIER_LD6B_ID, 81*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 82*784548efSMasahiro Yamada .boot_device_table = uniphier_pxs2_boot_device_table, 83*784548efSMasahiro Yamada .boot_device_count = &uniphier_pxs2_boot_device_count, 84*784548efSMasahiro Yamada .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb, 85*784548efSMasahiro Yamada .boot_device_fixup = uniphier_pxs2_boot_device_fixup, 86*784548efSMasahiro Yamada }, 87*784548efSMasahiro Yamada #endif 88*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD11) 89*784548efSMasahiro Yamada { 90*784548efSMasahiro Yamada .soc_id = UNIPHIER_LD11_ID, 91*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 92*784548efSMasahiro Yamada .boot_device_table = uniphier_ld11_boot_device_table, 93*784548efSMasahiro Yamada .boot_device_count = &uniphier_ld11_boot_device_count, 94*784548efSMasahiro Yamada .boot_device_is_usb = uniphier_ld11_boot_device_is_usb, 95*784548efSMasahiro Yamada .boot_device_fixup = uniphier_ld11_boot_device_fixup, 96*784548efSMasahiro Yamada }, 97*784548efSMasahiro Yamada #endif 98*784548efSMasahiro Yamada #if defined(CONFIG_ARCH_UNIPHIER_LD20) 99*784548efSMasahiro Yamada { 100*784548efSMasahiro Yamada .soc_id = UNIPHIER_LD20_ID, 101*784548efSMasahiro Yamada .boot_device_sel_shift = 1, 102*784548efSMasahiro Yamada .boot_device_table = uniphier_ld11_boot_device_table, 103*784548efSMasahiro Yamada .boot_device_count = &uniphier_ld11_boot_device_count, 104*784548efSMasahiro Yamada .boot_device_is_usb = uniphier_ld20_boot_device_is_usb, 105*784548efSMasahiro Yamada .boot_device_fixup = uniphier_ld11_boot_device_fixup, 106*784548efSMasahiro Yamada }, 107*784548efSMasahiro Yamada #endif 108*784548efSMasahiro Yamada }; 109*784548efSMasahiro Yamada UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info, 110*784548efSMasahiro Yamada uniphier_boot_device_info) 111*784548efSMasahiro Yamada 112*784548efSMasahiro Yamada static unsigned int __uniphier_boot_device_raw( 113*784548efSMasahiro Yamada const struct uniphier_boot_device_info *info) 114*784548efSMasahiro Yamada { 115*784548efSMasahiro Yamada u32 pinmon; 116*784548efSMasahiro Yamada unsigned int boot_sel; 117*784548efSMasahiro Yamada 118*784548efSMasahiro Yamada if (boot_is_swapped()) 119*784548efSMasahiro Yamada return BOOT_DEVICE_NOR; 120*784548efSMasahiro Yamada 121*784548efSMasahiro Yamada pinmon = readl(SG_PINMON0); 122*784548efSMasahiro Yamada 123*784548efSMasahiro Yamada if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon)) 124*784548efSMasahiro Yamada return BOOT_DEVICE_USB; 125*784548efSMasahiro Yamada 126*784548efSMasahiro Yamada boot_sel = pinmon >> info->boot_device_sel_shift; 127*784548efSMasahiro Yamada 128*784548efSMasahiro Yamada BUG_ON(!is_power_of_2(*info->boot_device_count)); 129*784548efSMasahiro Yamada boot_sel &= *info->boot_device_count - 1; 130*784548efSMasahiro Yamada 131*784548efSMasahiro Yamada return info->boot_device_table[boot_sel].boot_device; 132*784548efSMasahiro Yamada } 133*784548efSMasahiro Yamada 134*784548efSMasahiro Yamada unsigned int uniphier_boot_device_raw(void) 135*784548efSMasahiro Yamada { 136*784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 137*784548efSMasahiro Yamada 138*784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 139*784548efSMasahiro Yamada if (!info) { 140*784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 141*784548efSMasahiro Yamada return BOOT_DEVICE_NONE; 142*784548efSMasahiro Yamada } 143*784548efSMasahiro Yamada 144*784548efSMasahiro Yamada return __uniphier_boot_device_raw(info); 145*784548efSMasahiro Yamada } 146*784548efSMasahiro Yamada 147*784548efSMasahiro Yamada u32 spl_boot_device(void) 148*784548efSMasahiro Yamada { 149*784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 150*784548efSMasahiro Yamada u32 raw_mode; 151*784548efSMasahiro Yamada 152*784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 153*784548efSMasahiro Yamada if (!info) { 154*784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 155*784548efSMasahiro Yamada return BOOT_DEVICE_NONE; 156*784548efSMasahiro Yamada } 157*784548efSMasahiro Yamada 158*784548efSMasahiro Yamada raw_mode = __uniphier_boot_device_raw(info); 159*784548efSMasahiro Yamada 160*784548efSMasahiro Yamada return info->boot_device_fixup ? 161*784548efSMasahiro Yamada info->boot_device_fixup(raw_mode) : raw_mode; 162*784548efSMasahiro Yamada } 163*784548efSMasahiro Yamada 164*784548efSMasahiro Yamada #ifndef CONFIG_SPL_BUILD 165*784548efSMasahiro Yamada 166*784548efSMasahiro Yamada static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 167*784548efSMasahiro Yamada { 168*784548efSMasahiro Yamada const struct uniphier_boot_device_info *info; 169*784548efSMasahiro Yamada u32 pinmon; 170*784548efSMasahiro Yamada unsigned int boot_device_count, boot_sel; 171*784548efSMasahiro Yamada int i; 172*784548efSMasahiro Yamada 173*784548efSMasahiro Yamada info = uniphier_get_boot_device_info(); 174*784548efSMasahiro Yamada if (!info) { 175*784548efSMasahiro Yamada pr_err("unsupported SoC\n"); 176*784548efSMasahiro Yamada return CMD_RET_FAILURE; 177*784548efSMasahiro Yamada } 178*784548efSMasahiro Yamada 179*784548efSMasahiro Yamada printf("Boot Swap: %s\n\n", boot_is_swapped() ? "ON" : "OFF"); 180*784548efSMasahiro Yamada 181*784548efSMasahiro Yamada pinmon = readl(SG_PINMON0); 182*784548efSMasahiro Yamada 183*784548efSMasahiro Yamada if (info->boot_device_is_usb) 184*784548efSMasahiro Yamada printf("USB Boot: %s\n\n", 185*784548efSMasahiro Yamada info->boot_device_is_usb(pinmon) ? "ON" : "OFF"); 186*784548efSMasahiro Yamada 187*784548efSMasahiro Yamada boot_device_count = *info->boot_device_count; 188*784548efSMasahiro Yamada 189*784548efSMasahiro Yamada boot_sel = pinmon >> info->boot_device_sel_shift; 190*784548efSMasahiro Yamada boot_sel &= boot_device_count - 1; 191*784548efSMasahiro Yamada 192*784548efSMasahiro Yamada printf("Boot Mode Sel:\n"); 193*784548efSMasahiro Yamada for (i = 0; i < boot_device_count; i++) 194*784548efSMasahiro Yamada printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i, 195*784548efSMasahiro Yamada info->boot_device_table[i].desc); 196*784548efSMasahiro Yamada 197*784548efSMasahiro Yamada return CMD_RET_SUCCESS; 198*784548efSMasahiro Yamada } 199*784548efSMasahiro Yamada 200*784548efSMasahiro Yamada U_BOOT_CMD( 201*784548efSMasahiro Yamada pinmon, 1, 1, do_pinmon, 202*784548efSMasahiro Yamada "pin monitor", 203*784548efSMasahiro Yamada "" 204*784548efSMasahiro Yamada ); 205*784548efSMasahiro Yamada 206*784548efSMasahiro Yamada #endif /* !CONFIG_SPL_BUILD */ 207