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 <mmio.h> 9 #include <stdbool.h> 10 #include <stddef.h> 11 #include <utils_def.h> 12 13 #include "uniphier.h" 14 15 #define UNIPHIER_PINMON0 0x5f900100 16 #define UNIPHIER_PINMON2 0x5f900108 17 18 static int uniphier_ld11_is_usb_boot(uint32_t pinmon) 19 { 20 return !!(~pinmon & 0x00000080); 21 } 22 23 static int uniphier_ld20_is_usb_boot(uint32_t pinmon) 24 { 25 return !!(~pinmon & 0x00000780); 26 } 27 28 static int uniphier_pxs3_is_usb_boot(uint32_t pinmon) 29 { 30 uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2); 31 32 return !!(pinmon2 & BIT(31)); 33 } 34 35 static const unsigned int uniphier_ld11_boot_device_table[] = { 36 UNIPHIER_BOOT_DEVICE_NAND, 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_EMMC, 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_NOR, 68 }; 69 70 static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon) 71 { 72 unsigned int boot_sel = (pinmon >> 1) & 0x1f; 73 74 assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table)); 75 76 return uniphier_ld11_boot_device_table[boot_sel]; 77 } 78 79 static const unsigned int uniphier_pxs3_boot_device_table[] = { 80 UNIPHIER_BOOT_DEVICE_NAND, 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_EMMC, 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_NAND, 95 UNIPHIER_BOOT_DEVICE_NAND, 96 }; 97 98 static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) 99 { 100 unsigned int boot_sel = (pinmon >> 1) & 0xf; 101 102 assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table)); 103 104 return uniphier_pxs3_boot_device_table[boot_sel]; 105 } 106 107 struct uniphier_boot_device_info { 108 int (*is_usb_boot)(uint32_t pinmon); 109 unsigned int (*get_boot_device)(uint32_t pinmon); 110 }; 111 112 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 113 [UNIPHIER_SOC_LD11] = { 114 .is_usb_boot = uniphier_ld11_is_usb_boot, 115 .get_boot_device = uniphier_ld11_get_boot_device, 116 }, 117 [UNIPHIER_SOC_LD20] = { 118 .is_usb_boot = uniphier_ld20_is_usb_boot, 119 .get_boot_device = uniphier_ld11_get_boot_device, 120 }, 121 [UNIPHIER_SOC_PXS3] = { 122 .is_usb_boot = uniphier_pxs3_is_usb_boot, 123 .get_boot_device = uniphier_pxs3_get_boot_device, 124 }, 125 }; 126 127 unsigned int uniphier_get_boot_device(unsigned int soc) 128 { 129 const struct uniphier_boot_device_info *info; 130 uint32_t pinmon; 131 132 assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 133 info = &uniphier_boot_device_info[soc]; 134 135 pinmon = mmio_read_32(UNIPHIER_PINMON0); 136 137 if (!(pinmon & BIT(29))) 138 return UNIPHIER_BOOT_DEVICE_NOR; 139 140 if (info->is_usb_boot(pinmon)) 141 return UNIPHIER_BOOT_DEVICE_USB; 142 143 return info->get_boot_device(pinmon); 144 } 145 146 static const bool uniphier_have_onchip_scp[] = { 147 [UNIPHIER_SOC_LD11] = true, 148 [UNIPHIER_SOC_LD20] = true, 149 [UNIPHIER_SOC_PXS3] = false, 150 }; 151 152 unsigned int uniphier_get_boot_master(unsigned int soc) 153 { 154 assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); 155 156 if (uniphier_have_onchip_scp[soc]) { 157 if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27)) 158 return UNIPHIER_BOOT_MASTER_THIS; 159 else 160 return UNIPHIER_BOOT_MASTER_SCP; 161 } else { 162 return UNIPHIER_BOOT_MASTER_EXT; 163 } 164 } 165