1 /* 2 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdbool.h> 9 #include <stddef.h> 10 11 #include <lib/mmio.h> 12 #include <lib/utils_def.h> 13 14 #include "uniphier.h" 15 16 #define UNIPHIER_PINMON0 0x0 17 #define UNIPHIER_PINMON2 0x8 18 19 static const uintptr_t uniphier_pinmon_base[] = { 20 [UNIPHIER_SOC_LD11] = 0x5f900100, 21 [UNIPHIER_SOC_LD20] = 0x5f900100, 22 [UNIPHIER_SOC_PXS3] = 0x5f900100, 23 }; 24 25 static bool uniphier_ld11_is_usb_boot(uint32_t pinmon) 26 { 27 return !!(~pinmon & 0x00000080); 28 } 29 30 static bool uniphier_ld20_is_usb_boot(uint32_t pinmon) 31 { 32 return !!(~pinmon & 0x00000780); 33 } 34 35 static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon) 36 { 37 uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3]; 38 uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2); 39 40 return !!(pinmon2 & BIT(31)); 41 } 42 43 static const unsigned int uniphier_ld11_boot_device_table[] = { 44 UNIPHIER_BOOT_DEVICE_NAND, 45 UNIPHIER_BOOT_DEVICE_NAND, 46 UNIPHIER_BOOT_DEVICE_NAND, 47 UNIPHIER_BOOT_DEVICE_NAND, 48 UNIPHIER_BOOT_DEVICE_NAND, 49 UNIPHIER_BOOT_DEVICE_NAND, 50 UNIPHIER_BOOT_DEVICE_NAND, 51 UNIPHIER_BOOT_DEVICE_NAND, 52 UNIPHIER_BOOT_DEVICE_NAND, 53 UNIPHIER_BOOT_DEVICE_NAND, 54 UNIPHIER_BOOT_DEVICE_NAND, 55 UNIPHIER_BOOT_DEVICE_NAND, 56 UNIPHIER_BOOT_DEVICE_NAND, 57 UNIPHIER_BOOT_DEVICE_NAND, 58 UNIPHIER_BOOT_DEVICE_NAND, 59 UNIPHIER_BOOT_DEVICE_NAND, 60 UNIPHIER_BOOT_DEVICE_NAND, 61 UNIPHIER_BOOT_DEVICE_NAND, 62 UNIPHIER_BOOT_DEVICE_NAND, 63 UNIPHIER_BOOT_DEVICE_NAND, 64 UNIPHIER_BOOT_DEVICE_NAND, 65 UNIPHIER_BOOT_DEVICE_NAND, 66 UNIPHIER_BOOT_DEVICE_NAND, 67 UNIPHIER_BOOT_DEVICE_NAND, 68 UNIPHIER_BOOT_DEVICE_EMMC, 69 UNIPHIER_BOOT_DEVICE_EMMC, 70 UNIPHIER_BOOT_DEVICE_EMMC, 71 UNIPHIER_BOOT_DEVICE_EMMC, 72 UNIPHIER_BOOT_DEVICE_EMMC, 73 UNIPHIER_BOOT_DEVICE_EMMC, 74 UNIPHIER_BOOT_DEVICE_EMMC, 75 UNIPHIER_BOOT_DEVICE_NOR, 76 }; 77 78 static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon) 79 { 80 unsigned int boot_sel = (pinmon >> 1) & 0x1f; 81 82 assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table)); 83 84 return uniphier_ld11_boot_device_table[boot_sel]; 85 } 86 87 static const unsigned int uniphier_pxs3_boot_device_table[] = { 88 UNIPHIER_BOOT_DEVICE_NAND, 89 UNIPHIER_BOOT_DEVICE_NAND, 90 UNIPHIER_BOOT_DEVICE_NAND, 91 UNIPHIER_BOOT_DEVICE_NAND, 92 UNIPHIER_BOOT_DEVICE_NAND, 93 UNIPHIER_BOOT_DEVICE_NAND, 94 UNIPHIER_BOOT_DEVICE_NAND, 95 UNIPHIER_BOOT_DEVICE_NAND, 96 UNIPHIER_BOOT_DEVICE_EMMC, 97 UNIPHIER_BOOT_DEVICE_EMMC, 98 UNIPHIER_BOOT_DEVICE_EMMC, 99 UNIPHIER_BOOT_DEVICE_EMMC, 100 UNIPHIER_BOOT_DEVICE_EMMC, 101 UNIPHIER_BOOT_DEVICE_EMMC, 102 UNIPHIER_BOOT_DEVICE_NAND, 103 UNIPHIER_BOOT_DEVICE_NAND, 104 }; 105 106 static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) 107 { 108 unsigned int boot_sel = (pinmon >> 1) & 0xf; 109 110 assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table)); 111 112 return uniphier_pxs3_boot_device_table[boot_sel]; 113 } 114 115 struct uniphier_boot_device_info { 116 bool have_boot_swap; 117 bool (*is_sd_boot)(uint32_t pinmon); 118 bool (*is_usb_boot)(uint32_t pinmon); 119 unsigned int (*get_boot_device)(uint32_t pinmon); 120 }; 121 122 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 123 [UNIPHIER_SOC_LD11] = { 124 .have_boot_swap = true, 125 .is_usb_boot = uniphier_ld11_is_usb_boot, 126 .get_boot_device = uniphier_ld11_get_boot_device, 127 }, 128 [UNIPHIER_SOC_LD20] = { 129 .have_boot_swap = true, 130 .is_usb_boot = uniphier_ld20_is_usb_boot, 131 .get_boot_device = uniphier_ld11_get_boot_device, 132 }, 133 [UNIPHIER_SOC_PXS3] = { 134 .have_boot_swap = true, 135 .is_usb_boot = uniphier_pxs3_is_usb_boot, 136 .get_boot_device = uniphier_pxs3_get_boot_device, 137 }, 138 }; 139 140 unsigned int uniphier_get_boot_device(unsigned int soc) 141 { 142 const struct uniphier_boot_device_info *info; 143 uintptr_t pinmon_base; 144 uint32_t pinmon; 145 146 assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 147 info = &uniphier_boot_device_info[soc]; 148 149 assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 150 pinmon_base = uniphier_pinmon_base[soc]; 151 152 pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0); 153 154 if (info->have_boot_swap && !(pinmon & BIT(29))) 155 return UNIPHIER_BOOT_DEVICE_NOR; 156 157 if (info->is_sd_boot && info->is_sd_boot(pinmon)) 158 return UNIPHIER_BOOT_DEVICE_SD; 159 160 if (info->is_usb_boot && info->is_usb_boot(pinmon)) 161 return UNIPHIER_BOOT_DEVICE_USB; 162 163 return info->get_boot_device(pinmon); 164 } 165 166 static const bool uniphier_have_onchip_scp[] = { 167 [UNIPHIER_SOC_LD11] = true, 168 [UNIPHIER_SOC_LD20] = true, 169 [UNIPHIER_SOC_PXS3] = false, 170 }; 171 172 unsigned int uniphier_get_boot_master(unsigned int soc) 173 { 174 assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); 175 176 if (uniphier_have_onchip_scp[soc]) { 177 uintptr_t pinmon_base; 178 179 assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 180 pinmon_base = uniphier_pinmon_base[soc]; 181 182 if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27)) 183 return UNIPHIER_BOOT_MASTER_THIS; 184 else 185 return UNIPHIER_BOOT_MASTER_SCP; 186 } else { 187 return UNIPHIER_BOOT_MASTER_EXT; 188 } 189 } 190