1 /* 2 * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <common/debug.h> 11 #include <drivers/clk.h> 12 #include <drivers/delay_timer.h> 13 #include <drivers/st/stpmic1.h> 14 #include <lib/mmio.h> 15 #include <lib/utils_def.h> 16 #include <libfdt.h> 17 18 #include <platform_def.h> 19 #include <stm32mp_common.h> 20 #include <stm32mp_dt.h> 21 #include <stm32mp1_private.h> 22 23 /* 24 * SYSCFG REGISTER OFFSET (base relative) 25 */ 26 #define SYSCFG_BOOTR 0x00U 27 #if STM32MP15 28 #define SYSCFG_IOCTRLSETR 0x18U 29 #define SYSCFG_ICNR 0x1CU 30 #endif 31 #define SYSCFG_CMPCR 0x20U 32 #define SYSCFG_CMPENSETR 0x24U 33 #define SYSCFG_CMPENCLRR 0x28U 34 #if STM32MP13 35 #define SYSCFG_CMPSD1CR 0x30U 36 #define SYSCFG_CMPSD1ENSETR 0x34U 37 #define SYSCFG_CMPSD1ENCLRR 0x38U 38 #define SYSCFG_CMPSD2CR 0x40U 39 #define SYSCFG_CMPSD2ENSETR 0x44U 40 #define SYSCFG_CMPSD2ENCLRR 0x48U 41 #define SYSCFG_HSLVEN0R 0x50U 42 #endif 43 #define SYSCFG_IDC 0x380U 44 45 #define CMPCR_CMPENSETR_OFFSET 0x4U 46 #define CMPCR_CMPENCLRR_OFFSET 0x8U 47 48 /* 49 * SYSCFG_BOOTR Register 50 */ 51 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) 52 #if STM32MP15 53 #define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4) 54 #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 55 #endif 56 57 /* 58 * SYSCFG_IOCTRLSETR Register 59 */ 60 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) 61 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) 62 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) 63 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3) 64 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4) 65 66 /* 67 * SYSCFG_ICNR Register 68 */ 69 #define SYSCFG_ICNR_AXI_M9 BIT(9) 70 71 /* 72 * SYSCFG_CMPCR Register 73 */ 74 #define SYSCFG_CMPCR_SW_CTRL BIT(1) 75 #define SYSCFG_CMPCR_READY BIT(8) 76 #define SYSCFG_CMPCR_RANSRC GENMASK(19, 16) 77 #define SYSCFG_CMPCR_RANSRC_SHIFT 16 78 #define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20) 79 #define SYSCFG_CMPCR_ANSRC_SHIFT 24 80 81 #define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U 82 83 /* 84 * SYSCFG_CMPENSETR Register 85 */ 86 #define SYSCFG_CMPENSETR_MPU_EN BIT(0) 87 88 /* 89 * HSLV definitions 90 */ 91 #define HSLV_IDX_TPIU 0U 92 #define HSLV_IDX_QSPI 1U 93 #define HSLV_IDX_ETH1 2U 94 #define HSLV_IDX_ETH2 3U 95 #define HSLV_IDX_SDMMC1 4U 96 #define HSLV_IDX_SDMMC2 5U 97 #define HSLV_IDX_SPI1 6U 98 #define HSLV_IDX_SPI2 7U 99 #define HSLV_IDX_SPI3 8U 100 #define HSLV_IDX_SPI4 9U 101 #define HSLV_IDX_SPI5 10U 102 #define HSLV_IDX_LTDC 11U 103 #define HSLV_NB_IDX 12U 104 105 #define HSLV_KEY 0x1018U 106 107 /* 108 * SYSCFG_IDC Register 109 */ 110 #define SYSCFG_IDC_DEV_ID_MASK GENMASK(11, 0) 111 #define SYSCFG_IDC_REV_ID_MASK GENMASK(31, 16) 112 #define SYSCFG_IDC_REV_ID_SHIFT 16 113 114 static void enable_io_comp_cell_finish(uintptr_t cmpcr_off) 115 { 116 uint64_t start; 117 118 start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US); 119 120 while ((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) { 121 if (timeout_elapsed(start)) { 122 /* Failure on IO compensation enable is not a issue: warn only. */ 123 WARN("IO compensation cell not ready\n"); 124 break; 125 } 126 } 127 128 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_SW_CTRL); 129 } 130 131 static void disable_io_comp_cell(uintptr_t cmpcr_off) 132 { 133 uint32_t value; 134 135 if (((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) || 136 ((mmio_read_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENSETR_OFFSET) & 137 SYSCFG_CMPENSETR_MPU_EN) == 0U)) { 138 return; 139 } 140 141 value = mmio_read_32(SYSCFG_BASE + cmpcr_off) >> SYSCFG_CMPCR_ANSRC_SHIFT; 142 143 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC); 144 145 value <<= SYSCFG_CMPCR_RANSRC_SHIFT; 146 value |= mmio_read_32(SYSCFG_BASE + cmpcr_off); 147 148 mmio_write_32(SYSCFG_BASE + cmpcr_off, value | SYSCFG_CMPCR_SW_CTRL); 149 150 mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN); 151 } 152 153 #if STM32MP13 154 static int get_regu_max_voltage(void *fdt, int sdmmc_node, 155 const char *regu_name, uint32_t *regu_val) 156 { 157 int node; 158 const fdt32_t *cuint; 159 160 cuint = fdt_getprop(fdt, sdmmc_node, regu_name, NULL); 161 if (cuint == NULL) { 162 return -ENODEV; 163 } 164 165 node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 166 if (node < 0) { 167 return -ENODEV; 168 } 169 170 cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL); 171 if (cuint == NULL) { 172 return -ENODEV; 173 } 174 175 *regu_val = fdt32_to_cpu(*cuint); 176 177 return 0; 178 } 179 180 static bool sdmmc_is_low_voltage(uintptr_t sdmmc_base) 181 { 182 int ret; 183 int node; 184 void *fdt = NULL; 185 uint32_t regu_max_val; 186 187 if (fdt_get_address(&fdt) == 0) { 188 return false; 189 } 190 191 if (fdt == NULL) { 192 return false; 193 } 194 195 node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT, sdmmc_base); 196 if (node < 0) { 197 /* No SD or eMMC device on this instance, enable HSLV */ 198 return true; 199 } 200 201 ret = get_regu_max_voltage(fdt, node, "vqmmc-supply", ®u_max_val); 202 if ((ret < 0) || (regu_max_val > 1800000U)) { 203 /* 204 * The vqmmc-supply property should always be present for eMMC. 205 * For SD-card, if it is not, then the card only supports 3.3V. 206 */ 207 return false; 208 } 209 210 return true; 211 } 212 213 static void enable_hslv_by_index(uint32_t index) 214 { 215 bool apply_hslv; 216 217 assert(index < HSLV_NB_IDX); 218 219 switch (index) { 220 case HSLV_IDX_SDMMC1: 221 apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC1_BASE); 222 break; 223 case HSLV_IDX_SDMMC2: 224 apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC2_BASE); 225 break; 226 default: 227 apply_hslv = true; 228 break; 229 } 230 231 if (apply_hslv) { 232 mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY); 233 } 234 } 235 #endif 236 237 static void enable_high_speed_mode_low_voltage(void) 238 { 239 #if STM32MP13 240 uint32_t idx; 241 242 for (idx = 0U; idx < HSLV_NB_IDX; idx++) { 243 enable_hslv_by_index(idx); 244 } 245 #endif 246 #if STM32MP15 247 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, 248 SYSCFG_IOCTRLSETR_HSLVEN_TRACE | 249 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | 250 SYSCFG_IOCTRLSETR_HSLVEN_ETH | 251 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | 252 SYSCFG_IOCTRLSETR_HSLVEN_SPI); 253 #endif 254 } 255 256 static void stm32mp1_syscfg_set_hslv(void) 257 { 258 uint32_t otp_value; 259 uint32_t vdd_voltage; 260 bool product_below_2v5; 261 262 /* 263 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI 264 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. 265 * It could be disabled for low frequencies or if AFMUX is selected 266 * but the function is not used, typically for TRACE. 267 * If high speed low voltage pad mode is node enable, platform will 268 * over consume. 269 * 270 * WARNING: 271 * Enabling High Speed mode while VDD > 2.7V 272 * with the OTP product_below_2v5 (OTP 18, BIT 13) 273 * erroneously set to 1 can damage the SoC! 274 * => TF-A enables the low power mode only if VDD < 2.7V (in DT) 275 * but this value needs to be consistent with board design. 276 */ 277 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 278 panic(); 279 } 280 281 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U; 282 283 /* Get VDD supply */ 284 vdd_voltage = dt_get_pwr_vdd_voltage(); 285 286 /* Check if VDD is Low Voltage */ 287 if (vdd_voltage == 0U) { 288 WARN("VDD unknown\n"); 289 } else if (vdd_voltage < 2700000U) { 290 enable_high_speed_mode_low_voltage(); 291 292 if (!product_below_2v5) { 293 INFO("Product_below_2v5=0: HSLVEN protected by HW\n"); 294 } 295 } else { 296 if (product_below_2v5) { 297 ERROR("Product_below_2v5=1:\n"); 298 ERROR("\tHSLVEN update is destructive,\n"); 299 ERROR("\tno update as VDD > 2.7V\n"); 300 panic(); 301 } 302 } 303 } 304 305 void stm32mp1_syscfg_init(void) 306 { 307 #if STM32MP15 308 uint32_t bootr; 309 310 /* 311 * Interconnect update : select master using the port 1. 312 * LTDC = AXI_M9. 313 */ 314 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); 315 316 /* Disable Pull-Down for boot pin connected to VDD */ 317 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) & 318 SYSCFG_BOOTR_BOOT_MASK; 319 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, 320 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT); 321 #endif 322 323 stm32mp1_syscfg_set_hslv(); 324 325 stm32mp1_syscfg_enable_io_compensation_start(); 326 } 327 328 void stm32mp1_syscfg_enable_io_compensation_start(void) 329 { 330 /* 331 * Activate automatic I/O compensation. 332 * Warning: need to ensure CSI enabled and ready in clock driver. 333 * Enable non-secure clock, we assume non-secure is suspended. 334 */ 335 clk_enable(SYSCFG); 336 337 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR, 338 SYSCFG_CMPENSETR_MPU_EN); 339 #if STM32MP13 340 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR, 341 SYSCFG_CMPENSETR_MPU_EN); 342 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR, 343 SYSCFG_CMPENSETR_MPU_EN); 344 345 #endif 346 } 347 348 void stm32mp1_syscfg_enable_io_compensation_finish(void) 349 { 350 enable_io_comp_cell_finish(SYSCFG_CMPCR); 351 #if STM32MP13 352 enable_io_comp_cell_finish(SYSCFG_CMPSD1CR); 353 enable_io_comp_cell_finish(SYSCFG_CMPSD2CR); 354 #endif 355 } 356 357 void stm32mp1_syscfg_disable_io_compensation(void) 358 { 359 clk_enable(SYSCFG); 360 361 /* 362 * Deactivate automatic I/O compensation. 363 * Warning: CSI is disabled automatically in STOP if not 364 * requested for other usages and always OFF in STANDBY. 365 * Disable non-secure SYSCFG clock, we assume non-secure is suspended. 366 */ 367 disable_io_comp_cell(SYSCFG_CMPCR); 368 #if STM32MP13 369 disable_io_comp_cell(SYSCFG_CMPSD1CR); 370 disable_io_comp_cell(SYSCFG_CMPSD2CR); 371 #endif 372 373 clk_disable(SYSCFG); 374 } 375 376 /* 377 * @brief Get silicon revision from SYSCFG registers. 378 * @retval chip version (REV_ID). 379 */ 380 uint32_t stm32mp1_syscfg_get_chip_version(void) 381 { 382 return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & 383 SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT; 384 } 385 386 /* 387 * @brief Get device ID from SYSCFG registers. 388 * @retval device ID (DEV_ID). 389 */ 390 uint32_t stm32mp1_syscfg_get_chip_dev_id(void) 391 { 392 return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK; 393 } 394