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