xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_syscfg.c (revision de02e9b0ec29548b8ce5ef6ee9adcd9c5edb0518)
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