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