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 #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 mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY); 239 } 240 } 241 #endif 242 243 static void enable_high_speed_mode_low_voltage(void) 244 { 245 #if STM32MP13 246 uint32_t idx; 247 248 for (idx = 0U; idx < HSLV_NB_IDX; idx++) { 249 enable_hslv_by_index(idx); 250 } 251 #endif 252 #if STM32MP15 253 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, 254 SYSCFG_IOCTRLSETR_HSLVEN_TRACE | 255 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | 256 SYSCFG_IOCTRLSETR_HSLVEN_ETH | 257 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | 258 SYSCFG_IOCTRLSETR_HSLVEN_SPI); 259 #endif 260 } 261 262 static void stm32mp1_syscfg_set_hslv(void) 263 { 264 uint32_t otp_value; 265 uint32_t vdd_voltage; 266 bool product_below_2v5; 267 268 /* 269 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI 270 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. 271 * It could be disabled for low frequencies or if AFMUX is selected 272 * but the function is not used, typically for TRACE. 273 * If high speed low voltage pad mode is node enable, platform will 274 * over consume. 275 * 276 * WARNING: 277 * Enabling High Speed mode while VDD > 2.7V 278 * with the OTP product_below_2v5 (OTP 18, BIT 13) 279 * erroneously set to 1 can damage the SoC! 280 * => TF-A enables the low power mode only if VDD < 2.7V (in DT) 281 * but this value needs to be consistent with board design. 282 */ 283 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 284 panic(); 285 } 286 287 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U; 288 289 /* Get VDD supply */ 290 vdd_voltage = dt_get_pwr_vdd_voltage(); 291 292 /* Check if VDD is Low Voltage */ 293 if (vdd_voltage == 0U) { 294 WARN("VDD unknown\n"); 295 } else if (vdd_voltage < 2700000U) { 296 enable_high_speed_mode_low_voltage(); 297 298 if (!product_below_2v5) { 299 INFO("Product_below_2v5=0: HSLVEN protected by HW\n"); 300 } 301 } else { 302 if (product_below_2v5) { 303 ERROR("Product_below_2v5=1:\n"); 304 ERROR("\tHSLVEN update is destructive,\n"); 305 ERROR("\tno update as VDD > 2.7V\n"); 306 panic(); 307 } 308 } 309 } 310 311 void stm32mp1_syscfg_init(void) 312 { 313 #if STM32MP15 314 uint32_t bootr; 315 316 /* 317 * Interconnect update : select master using the port 1. 318 * LTDC = AXI_M9. 319 */ 320 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); 321 322 /* Disable Pull-Down for boot pin connected to VDD */ 323 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) & 324 SYSCFG_BOOTR_BOOT_MASK; 325 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, 326 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT); 327 #endif 328 329 stm32mp1_syscfg_set_hslv(); 330 331 stm32mp1_syscfg_enable_io_compensation_start(); 332 } 333 334 void stm32mp1_syscfg_enable_io_compensation_start(void) 335 { 336 /* 337 * Activate automatic I/O compensation. 338 * Warning: need to ensure CSI enabled and ready in clock driver. 339 * Enable non-secure clock, we assume non-secure is suspended. 340 */ 341 clk_enable(SYSCFG); 342 343 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR, 344 SYSCFG_CMPENSETR_MPU_EN); 345 #if STM32MP13 346 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR, 347 SYSCFG_CMPENSETR_MPU_EN); 348 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR, 349 SYSCFG_CMPENSETR_MPU_EN); 350 351 #endif 352 } 353 354 void stm32mp1_syscfg_enable_io_compensation_finish(void) 355 { 356 enable_io_comp_cell_finish(SYSCFG_CMPCR); 357 #if STM32MP13 358 enable_io_comp_cell_finish(SYSCFG_CMPSD1CR); 359 enable_io_comp_cell_finish(SYSCFG_CMPSD2CR); 360 #endif 361 } 362 363 void stm32mp1_syscfg_disable_io_compensation(void) 364 { 365 clk_enable(SYSCFG); 366 367 /* 368 * Deactivate automatic I/O compensation. 369 * Warning: CSI is disabled automatically in STOP if not 370 * requested for other usages and always OFF in STANDBY. 371 * Disable non-secure SYSCFG clock, we assume non-secure is suspended. 372 */ 373 disable_io_comp_cell(SYSCFG_CMPCR); 374 #if STM32MP13 375 disable_io_comp_cell(SYSCFG_CMPSD1CR); 376 disable_io_comp_cell(SYSCFG_CMPSD2CR); 377 #endif 378 379 clk_disable(SYSCFG); 380 } 381 382 /* 383 * @brief Get silicon revision from SYSCFG registers. 384 * @retval chip version (REV_ID). 385 */ 386 uint32_t stm32mp1_syscfg_get_chip_version(void) 387 { 388 return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & 389 SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT; 390 } 391 392 /* 393 * @brief Get device ID from SYSCFG registers. 394 * @retval device ID (DEV_ID). 395 */ 396 uint32_t stm32mp1_syscfg_get_chip_dev_id(void) 397 { 398 return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK; 399 } 400 401 #if STM32MP13 402 void stm32mp1_syscfg_boot_mode_enable(void) 403 { 404 mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN); 405 } 406 407 void stm32mp1_syscfg_boot_mode_disable(void) 408 { 409 mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN); 410 } 411 #endif 412