1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 4 * Copyright 2017-2019, 2021 NXP 5 * 6 * Peng Fan <peng.fan@nxp.com> 7 */ 8 9 #include <config.h> 10 #include <console.h> 11 #include <io.h> 12 #include <imx.h> 13 #include <mm/core_mmu.h> 14 #include <mm/core_memprot.h> 15 #include <platform_config.h> 16 17 #define SOC_TYPE(reg) (((reg) & (0x00FF0000)) >> 16) 18 #define SOC_REV_MAJOR(reg) (((reg) & (0x0000FF00)) >> 8) 19 #define SOC_REV_MINOR(reg) ((reg) & (0x0000000F)) 20 #define SOC_REV_MINOR_MX7(reg) ((reg) & (0x000000FF)) 21 22 static uint32_t imx_digprog; 23 24 #ifdef ANATOP_BASE imx_get_digprog(void)25uint32_t imx_get_digprog(void) 26 { 27 vaddr_t addr = 0; 28 29 if (imx_digprog) 30 return imx_digprog; 31 32 addr = core_mmu_get_va(ANATOP_BASE, MEM_AREA_IO_SEC, 0x1000); 33 if (!addr) 34 return 0; 35 36 imx_digprog = io_read32(addr + DIGPROG_OFFSET); 37 38 #ifdef CFG_MX8MQ 39 /* 40 * On the i.MX8MQ, the minor revision number must be updated to make 41 * the difference between B0 chip and the newer chips. 42 */ 43 addr = core_mmu_get_va(OCOTP_BASE, MEM_AREA_IO_SEC, OCOTP_SIZE); 44 if (!addr) 45 return 0; 46 47 if (io_read32(addr + OCOTP_SW_INFO_B1) == OCOTP_SW_MAGIC_B1) 48 imx_digprog |= BIT32(0); 49 #endif /* CFG_MX8MQ */ 50 51 return imx_digprog; 52 } 53 #else /* ANATOP_BASE */ imx_get_digprog(void)54uint32_t imx_get_digprog(void) 55 { 56 if (imx_digprog) 57 return imx_digprog; 58 59 if (IS_ENABLED(CFG_MX7ULP)) 60 imx_digprog = SOC_MX7ULP << 16; 61 else if (IS_ENABLED(CFG_MX8QX)) 62 imx_digprog = SOC_MX8QX << 16; 63 else if (IS_ENABLED(CFG_MX8QM)) 64 imx_digprog = SOC_MX8QM << 16; 65 else if (IS_ENABLED(CFG_MX8DXL)) 66 imx_digprog = SOC_MX8DXL << 16; 67 else if (IS_ENABLED(CFG_MX8ULP)) 68 imx_digprog = SOC_MX8ULP << 16; 69 else if (IS_ENABLED(CFG_MX93)) 70 imx_digprog = SOC_MX93 << 16; 71 72 return imx_digprog; 73 } 74 #endif /* ANATOP_BASE */ 75 imx_soc_rev_major(void)76uint32_t imx_soc_rev_major(void) 77 { 78 if (imx_digprog == 0) 79 imx_get_digprog(); 80 81 return SOC_REV_MAJOR(imx_digprog); 82 } 83 imx_soc_rev_minor(void)84uint32_t imx_soc_rev_minor(void) 85 { 86 if (imx_digprog == 0) 87 imx_get_digprog(); 88 89 if (IS_ENABLED(CFG_MX7)) 90 return SOC_REV_MINOR_MX7(imx_digprog); 91 else 92 return SOC_REV_MINOR(imx_digprog); 93 } 94 imx_soc_type(void)95uint32_t imx_soc_type(void) 96 { 97 if (imx_digprog == 0) 98 imx_get_digprog(); 99 100 return SOC_TYPE(imx_digprog); 101 } 102 soc_is_imx6sl(void)103bool soc_is_imx6sl(void) 104 { 105 return imx_soc_type() == SOC_MX6SL; 106 } 107 soc_is_imx6sll(void)108bool soc_is_imx6sll(void) 109 { 110 return imx_soc_type() == SOC_MX6SLL; 111 } 112 soc_is_imx6sx(void)113bool soc_is_imx6sx(void) 114 { 115 return imx_soc_type() == SOC_MX6SX; 116 } 117 soc_is_imx6ul(void)118bool soc_is_imx6ul(void) 119 { 120 return imx_soc_type() == SOC_MX6UL; 121 } 122 soc_is_imx6ull(void)123bool soc_is_imx6ull(void) 124 { 125 return imx_soc_type() == SOC_MX6ULL; 126 } 127 soc_is_imx6sdl(void)128bool soc_is_imx6sdl(void) 129 { 130 return imx_soc_type() == SOC_MX6DL; 131 } 132 soc_is_imx6dq(void)133bool soc_is_imx6dq(void) 134 { 135 return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 0); 136 } 137 soc_is_imx6dqp(void)138bool soc_is_imx6dqp(void) 139 { 140 return (imx_soc_type() == SOC_MX6Q) && (imx_soc_rev_major() == 1); 141 } 142 soc_is_imx6(void)143bool soc_is_imx6(void) 144 { 145 uint32_t soc = imx_soc_type(); 146 147 return (soc == SOC_MX6SLL) || (soc == SOC_MX6SL) || 148 (soc == SOC_MX6D) || (soc == SOC_MX6SX) || 149 (soc == SOC_MX6UL) || (soc == SOC_MX6ULL) || 150 (soc == SOC_MX6DL) || (soc == SOC_MX6Q); 151 } 152 soc_is_imx7ds(void)153bool soc_is_imx7ds(void) 154 { 155 return imx_soc_type() == SOC_MX7D; 156 } 157 soc_is_imx7ulp(void)158bool soc_is_imx7ulp(void) 159 { 160 return imx_soc_type() == SOC_MX7ULP; 161 } 162 soc_is_imx8mq(void)163bool soc_is_imx8mq(void) 164 { 165 return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x40; 166 } 167 soc_is_imx8mm(void)168bool soc_is_imx8mm(void) 169 { 170 return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x41; 171 } 172 soc_is_imx8mn(void)173bool soc_is_imx8mn(void) 174 { 175 return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x42; 176 } 177 soc_is_imx8mp(void)178bool soc_is_imx8mp(void) 179 { 180 return imx_soc_type() == SOC_MX8M && imx_soc_rev_major() == 0x43; 181 } 182 soc_is_imx8m(void)183bool soc_is_imx8m(void) 184 { 185 return soc_is_imx8mq() || soc_is_imx8mm() || soc_is_imx8mn() || 186 soc_is_imx8mp(); 187 } 188 soc_is_imx8mq_b0_layer(void)189bool soc_is_imx8mq_b0_layer(void) 190 { 191 if (soc_is_imx8mq() && imx_soc_rev_minor() == 0x0) 192 return true; 193 else 194 return false; 195 } 196