1 /* 2 * Copyright (c) 2017, 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 0x5f900100 17 #define UNIPHIER_PINMON2 0x5f900108 18 19 static int uniphier_ld11_is_usb_boot(uint32_t pinmon) 20 { 21 return !!(~pinmon & 0x00000080); 22 } 23 24 static int uniphier_ld20_is_usb_boot(uint32_t pinmon) 25 { 26 return !!(~pinmon & 0x00000780); 27 } 28 29 static int uniphier_pxs3_is_usb_boot(uint32_t pinmon) 30 { 31 uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2); 32 33 return !!(pinmon2 & BIT(31)); 34 } 35 36 static const unsigned int uniphier_ld11_boot_device_table[] = { 37 UNIPHIER_BOOT_DEVICE_NAND, 38 UNIPHIER_BOOT_DEVICE_NAND, 39 UNIPHIER_BOOT_DEVICE_NAND, 40 UNIPHIER_BOOT_DEVICE_NAND, 41 UNIPHIER_BOOT_DEVICE_NAND, 42 UNIPHIER_BOOT_DEVICE_NAND, 43 UNIPHIER_BOOT_DEVICE_NAND, 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_EMMC, 62 UNIPHIER_BOOT_DEVICE_EMMC, 63 UNIPHIER_BOOT_DEVICE_EMMC, 64 UNIPHIER_BOOT_DEVICE_EMMC, 65 UNIPHIER_BOOT_DEVICE_EMMC, 66 UNIPHIER_BOOT_DEVICE_EMMC, 67 UNIPHIER_BOOT_DEVICE_EMMC, 68 UNIPHIER_BOOT_DEVICE_NOR, 69 }; 70 71 static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon) 72 { 73 unsigned int boot_sel = (pinmon >> 1) & 0x1f; 74 75 assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table)); 76 77 return uniphier_ld11_boot_device_table[boot_sel]; 78 } 79 80 static const unsigned int uniphier_pxs3_boot_device_table[] = { 81 UNIPHIER_BOOT_DEVICE_NAND, 82 UNIPHIER_BOOT_DEVICE_NAND, 83 UNIPHIER_BOOT_DEVICE_NAND, 84 UNIPHIER_BOOT_DEVICE_NAND, 85 UNIPHIER_BOOT_DEVICE_NAND, 86 UNIPHIER_BOOT_DEVICE_NAND, 87 UNIPHIER_BOOT_DEVICE_NAND, 88 UNIPHIER_BOOT_DEVICE_NAND, 89 UNIPHIER_BOOT_DEVICE_EMMC, 90 UNIPHIER_BOOT_DEVICE_EMMC, 91 UNIPHIER_BOOT_DEVICE_EMMC, 92 UNIPHIER_BOOT_DEVICE_EMMC, 93 UNIPHIER_BOOT_DEVICE_EMMC, 94 UNIPHIER_BOOT_DEVICE_EMMC, 95 UNIPHIER_BOOT_DEVICE_NAND, 96 UNIPHIER_BOOT_DEVICE_NAND, 97 }; 98 99 static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) 100 { 101 unsigned int boot_sel = (pinmon >> 1) & 0xf; 102 103 assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table)); 104 105 return uniphier_pxs3_boot_device_table[boot_sel]; 106 } 107 108 struct uniphier_boot_device_info { 109 int (*is_usb_boot)(uint32_t pinmon); 110 unsigned int (*get_boot_device)(uint32_t pinmon); 111 }; 112 113 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 114 [UNIPHIER_SOC_LD11] = { 115 .is_usb_boot = uniphier_ld11_is_usb_boot, 116 .get_boot_device = uniphier_ld11_get_boot_device, 117 }, 118 [UNIPHIER_SOC_LD20] = { 119 .is_usb_boot = uniphier_ld20_is_usb_boot, 120 .get_boot_device = uniphier_ld11_get_boot_device, 121 }, 122 [UNIPHIER_SOC_PXS3] = { 123 .is_usb_boot = uniphier_pxs3_is_usb_boot, 124 .get_boot_device = uniphier_pxs3_get_boot_device, 125 }, 126 }; 127 128 unsigned int uniphier_get_boot_device(unsigned int soc) 129 { 130 const struct uniphier_boot_device_info *info; 131 uint32_t pinmon; 132 133 assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 134 info = &uniphier_boot_device_info[soc]; 135 136 pinmon = mmio_read_32(UNIPHIER_PINMON0); 137 138 if (!(pinmon & BIT(29))) 139 return UNIPHIER_BOOT_DEVICE_NOR; 140 141 if (info->is_usb_boot(pinmon)) 142 return UNIPHIER_BOOT_DEVICE_USB; 143 144 return info->get_boot_device(pinmon); 145 } 146 147 static const bool uniphier_have_onchip_scp[] = { 148 [UNIPHIER_SOC_LD11] = true, 149 [UNIPHIER_SOC_LD20] = true, 150 [UNIPHIER_SOC_PXS3] = false, 151 }; 152 153 unsigned int uniphier_get_boot_master(unsigned int soc) 154 { 155 assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); 156 157 if (uniphier_have_onchip_scp[soc]) { 158 if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27)) 159 return UNIPHIER_BOOT_MASTER_THIS; 160 else 161 return UNIPHIER_BOOT_MASTER_SCP; 162 } else { 163 return UNIPHIER_BOOT_MASTER_EXT; 164 } 165 } 166