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