1 /* 2 * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <drivers/delay_timer.h> 9 #include <drivers/st/bsec.h> 10 #include <drivers/st/stpmic1.h> 11 #include <lib/mmio.h> 12 13 #include <platform_def.h> 14 #include <stm32mp_dt.h> 15 #include <stm32mp1_private.h> 16 17 /* 18 * SYSCFG REGISTER OFFSET (base relative) 19 */ 20 #define SYSCFG_BOOTR 0x00U 21 #define SYSCFG_IOCTRLSETR 0x18U 22 #define SYSCFG_ICNR 0x1CU 23 #define SYSCFG_CMPCR 0x20U 24 #define SYSCFG_CMPENSETR 0x24U 25 #define SYSCFG_CMPENCLRR 0x28U 26 27 /* 28 * SYSCFG_BOOTR Register 29 */ 30 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) 31 #define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4) 32 #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 33 /* 34 * SYSCFG_IOCTRLSETR Register 35 */ 36 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) 37 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) 38 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) 39 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3) 40 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4) 41 42 /* 43 * SYSCFG_ICNR Register 44 */ 45 #define SYSCFG_ICNR_AXI_M9 BIT(9) 46 47 /* 48 * SYSCFG_CMPCR Register 49 */ 50 #define SYSCFG_CMPCR_SW_CTRL BIT(1) 51 #define SYSCFG_CMPCR_READY BIT(8) 52 #define SYSCFG_CMPCR_RANSRC GENMASK(19, 16) 53 #define SYSCFG_CMPCR_RANSRC_SHIFT 16 54 #define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20) 55 #define SYSCFG_CMPCR_ANSRC_SHIFT 24 56 57 #define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U 58 59 /* 60 * SYSCFG_CMPENSETR Register 61 */ 62 #define SYSCFG_CMPENSETR_MPU_EN BIT(0) 63 64 void stm32mp1_syscfg_init(void) 65 { 66 uint32_t bootr; 67 uint32_t otp = 0; 68 uint32_t vdd_voltage; 69 70 /* 71 * Interconnect update : select master using the port 1. 72 * LTDC = AXI_M9. 73 */ 74 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9); 75 76 /* Disable Pull-Down for boot pin connected to VDD */ 77 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) & 78 SYSCFG_BOOTR_BOOT_MASK; 79 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK, 80 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT); 81 82 /* 83 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI 84 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. 85 * It could be disabled for low frequencies or if AFMUX is selected 86 * but the function is not used, typically for TRACE. 87 * If high speed low voltage pad mode is node enable, platform will 88 * over consume. 89 * 90 * WARNING: 91 * Enabling High Speed mode while VDD > 2.7V 92 * with the OTP product_below_2v5 (OTP 18, BIT 13) 93 * erroneously set to 1 can damage the SoC! 94 * => TF-A enables the low power mode only if VDD < 2.7V (in DT) 95 * but this value needs to be consistent with board design. 96 */ 97 if (bsec_read_otp(&otp, HW2_OTP) != BSEC_OK) { 98 panic(); 99 } 100 101 otp = otp & HW2_OTP_PRODUCT_BELOW_2V5; 102 103 /* Get VDD supply */ 104 vdd_voltage = dt_get_pwr_vdd_voltage(); 105 106 /* Check if VDD is Low Voltage */ 107 if (vdd_voltage == 0U) { 108 WARN("VDD unknown"); 109 } else if (vdd_voltage < 2700000U) { 110 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR, 111 SYSCFG_IOCTRLSETR_HSLVEN_TRACE | 112 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | 113 SYSCFG_IOCTRLSETR_HSLVEN_ETH | 114 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | 115 SYSCFG_IOCTRLSETR_HSLVEN_SPI); 116 117 if (otp == 0U) { 118 INFO("Product_below_2v5=0: HSLVEN protected by HW\n"); 119 } 120 } else { 121 if (otp != 0U) { 122 ERROR("Product_below_2v5=1:\n"); 123 ERROR("\tHSLVEN update is destructive,\n"); 124 ERROR("\tno update as VDD > 2.7V\n"); 125 panic(); 126 } 127 } 128 129 stm32mp1_syscfg_enable_io_compensation(); 130 } 131 132 void stm32mp1_syscfg_enable_io_compensation(void) 133 { 134 uint64_t start; 135 136 /* 137 * Activate automatic I/O compensation. 138 * Warning: need to ensure CSI enabled and ready in clock driver. 139 * Enable non-secure clock, we assume non-secure is suspended. 140 */ 141 stm32mp1_clk_enable_non_secure(SYSCFG); 142 143 mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENSETR, 144 SYSCFG_CMPENSETR_MPU_EN); 145 146 start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US); 147 148 while ((mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) & 149 SYSCFG_CMPCR_READY) == 0U) { 150 if (timeout_elapsed(start)) { 151 /* 152 * Failure on IO compensation enable is not a issue: 153 * warn only. 154 */ 155 WARN("IO compensation cell not ready\n"); 156 break; 157 } 158 } 159 160 mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); 161 } 162 163 void stm32mp1_syscfg_disable_io_compensation(void) 164 { 165 uint32_t value; 166 167 /* 168 * Deactivate automatic I/O compensation. 169 * Warning: CSI is disabled automatically in STOP if not 170 * requested for other usages and always OFF in STANDBY. 171 * Disable non-secure SYSCFG clock, we assume non-secure is suspended. 172 */ 173 value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) >> 174 SYSCFG_CMPCR_ANSRC_SHIFT; 175 176 mmio_clrbits_32(SYSCFG_BASE + SYSCFG_CMPCR, 177 SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC); 178 179 value = mmio_read_32(SYSCFG_BASE + SYSCFG_CMPCR) | 180 (value << SYSCFG_CMPCR_RANSRC_SHIFT); 181 182 mmio_write_32(SYSCFG_BASE + SYSCFG_CMPCR, value | SYSCFG_CMPCR_SW_CTRL); 183 184 mmio_setbits_32(SYSCFG_BASE + SYSCFG_CMPENCLRR, SYSCFG_CMPENSETR_MPU_EN); 185 186 stm32mp1_clk_disable_non_secure(SYSCFG); 187 } 188