blob: 6d24b0e8578bb98e69064160a432552c14a2fd62 [file] [log] [blame]
Yann Gautier3edc7c32019-05-20 19:17:08 +02001/*
Nicolas Le Bayon36898692019-11-18 17:18:06 +01002 * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
Yann Gautier3edc7c32019-05-20 19:17:08 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautier3edc7c32019-05-20 19:17:08 +02007#include <common/debug.h>
Etienne Carriere1de46d02020-02-07 13:38:30 +01008#include <drivers/clk.h>
Nicolas Le Bayon36898692019-11-18 17:18:06 +01009#include <drivers/delay_timer.h>
Yann Gautier3edc7c32019-05-20 19:17:08 +020010#include <drivers/st/stpmic1.h>
11#include <lib/mmio.h>
12
Nicolas Le Bayon36898692019-11-18 17:18:06 +010013#include <platform_def.h>
Lionel Debievebc2d88d2019-11-04 14:31:38 +010014#include <stm32mp_common.h>
Yann Gautier3edc7c32019-05-20 19:17:08 +020015#include <stm32mp_dt.h>
16#include <stm32mp1_private.h>
17
18/*
19 * SYSCFG REGISTER OFFSET (base relative)
20 */
21#define SYSCFG_BOOTR 0x00U
Yann Gautiercc5f89a2020-02-12 09:36:23 +010022#if STM32MP15
Yann Gautier3edc7c32019-05-20 19:17:08 +020023#define SYSCFG_IOCTRLSETR 0x18U
24#define SYSCFG_ICNR 0x1CU
Yann Gautiercc5f89a2020-02-12 09:36:23 +010025#endif
Yann Gautier3edc7c32019-05-20 19:17:08 +020026#define SYSCFG_CMPCR 0x20U
27#define SYSCFG_CMPENSETR 0x24U
Yann Gautier0315fa02020-10-26 15:21:25 +010028#define SYSCFG_CMPENCLRR 0x28U
Yann Gautier3edc7c32019-05-20 19:17:08 +020029
Yann Gautierb76c61a2020-12-16 10:17:35 +010030#define CMPCR_CMPENSETR_OFFSET 0x4U
31#define CMPCR_CMPENCLRR_OFFSET 0x8U
32
Yann Gautier3edc7c32019-05-20 19:17:08 +020033/*
34 * SYSCFG_BOOTR Register
35 */
36#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
Yann Gautiercc5f89a2020-02-12 09:36:23 +010037#if STM32MP15
Yann Gautier3edc7c32019-05-20 19:17:08 +020038#define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4)
39#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
Yann Gautiercc5f89a2020-02-12 09:36:23 +010040#endif
41
Yann Gautier3edc7c32019-05-20 19:17:08 +020042/*
43 * SYSCFG_IOCTRLSETR Register
44 */
45#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
46#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
47#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
48#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
49#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
50
51/*
52 * SYSCFG_ICNR Register
53 */
54#define SYSCFG_ICNR_AXI_M9 BIT(9)
55
56/*
57 * SYSCFG_CMPCR Register
58 */
59#define SYSCFG_CMPCR_SW_CTRL BIT(1)
60#define SYSCFG_CMPCR_READY BIT(8)
61#define SYSCFG_CMPCR_RANSRC GENMASK(19, 16)
62#define SYSCFG_CMPCR_RANSRC_SHIFT 16
63#define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20)
64#define SYSCFG_CMPCR_ANSRC_SHIFT 24
65
Nicolas Le Bayon36898692019-11-18 17:18:06 +010066#define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U
67
Yann Gautier3edc7c32019-05-20 19:17:08 +020068/*
69 * SYSCFG_CMPENSETR Register
70 */
71#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
72
Yann Gautierb76c61a2020-12-16 10:17:35 +010073static void enable_io_comp_cell_finish(uintptr_t cmpcr_off)
74{
75 uint64_t start;
76
77 start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US);
78
79 while ((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) {
80 if (timeout_elapsed(start)) {
81 /* Failure on IO compensation enable is not a issue: warn only. */
82 WARN("IO compensation cell not ready\n");
83 break;
84 }
85 }
86
87 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_SW_CTRL);
88}
89
90static void disable_io_comp_cell(uintptr_t cmpcr_off)
91{
92 uint32_t value;
93
94 if (((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) ||
95 ((mmio_read_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENSETR_OFFSET) &
96 SYSCFG_CMPENSETR_MPU_EN) == 0U)) {
97 return;
98 }
99
100 value = mmio_read_32(SYSCFG_BASE + cmpcr_off) >> SYSCFG_CMPCR_ANSRC_SHIFT;
101
102 mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC);
103
104 value <<= SYSCFG_CMPCR_RANSRC_SHIFT;
105 value |= mmio_read_32(SYSCFG_BASE + cmpcr_off);
106
107 mmio_write_32(SYSCFG_BASE + cmpcr_off, value | SYSCFG_CMPCR_SW_CTRL);
108
109 mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
110}
111
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100112static void enable_high_speed_mode_low_voltage(void)
Yann Gautier3edc7c32019-05-20 19:17:08 +0200113{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100114#if STM32MP15
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100115 mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
116 SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
117 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
118 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
119 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
120 SYSCFG_IOCTRLSETR_HSLVEN_SPI);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100121#endif
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100122}
123
124static void stm32mp1_syscfg_set_hslv(void)
125{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100126 uint32_t otp_value;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200127 uint32_t vdd_voltage;
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100128 bool product_below_2v5;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200129
130 /*
Yann Gautier3edc7c32019-05-20 19:17:08 +0200131 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
132 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
133 * It could be disabled for low frequencies or if AFMUX is selected
134 * but the function is not used, typically for TRACE.
135 * If high speed low voltage pad mode is node enable, platform will
136 * over consume.
137 *
138 * WARNING:
139 * Enabling High Speed mode while VDD > 2.7V
140 * with the OTP product_below_2v5 (OTP 18, BIT 13)
141 * erroneously set to 1 can damage the SoC!
142 * => TF-A enables the low power mode only if VDD < 2.7V (in DT)
143 * but this value needs to be consistent with board design.
144 */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100145 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200146 panic();
147 }
148
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100149 product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
Yann Gautier3edc7c32019-05-20 19:17:08 +0200150
151 /* Get VDD supply */
152 vdd_voltage = dt_get_pwr_vdd_voltage();
153
154 /* Check if VDD is Low Voltage */
155 if (vdd_voltage == 0U) {
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100156 WARN("VDD unknown\n");
Yann Gautier3edc7c32019-05-20 19:17:08 +0200157 } else if (vdd_voltage < 2700000U) {
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100158 enable_high_speed_mode_low_voltage();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200159
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100160 if (!product_below_2v5) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200161 INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
162 }
163 } else {
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100164 if (product_below_2v5) {
Yann Gautier3edc7c32019-05-20 19:17:08 +0200165 ERROR("Product_below_2v5=1:\n");
166 ERROR("\tHSLVEN update is destructive,\n");
167 ERROR("\tno update as VDD > 2.7V\n");
168 panic();
169 }
170 }
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100171}
172
173void stm32mp1_syscfg_init(void)
174{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100175#if STM32MP15
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100176 uint32_t bootr;
177
178 /*
179 * Interconnect update : select master using the port 1.
180 * LTDC = AXI_M9.
181 */
182 mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9);
183
184 /* Disable Pull-Down for boot pin connected to VDD */
185 bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) &
186 SYSCFG_BOOTR_BOOT_MASK;
187 mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
188 bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100189#endif
Yann Gautiere0a60cb2021-01-12 14:45:02 +0100190
191 stm32mp1_syscfg_set_hslv();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200192
Yann Gautierb76c61a2020-12-16 10:17:35 +0100193 stm32mp1_syscfg_enable_io_compensation_start();
Yann Gautier3edc7c32019-05-20 19:17:08 +0200194}
195
Yann Gautierb76c61a2020-12-16 10:17:35 +0100196void stm32mp1_syscfg_enable_io_compensation_start(void)
Yann Gautier3edc7c32019-05-20 19:17:08 +0200197{
Yann Gautier3edc7c32019-05-20 19:17:08 +0200198 /*
199 * Activate automatic I/O compensation.
200 * Warning: need to ensure CSI enabled and ready in clock driver.
201 * Enable non-secure clock, we assume non-secure is suspended.
202 */
Etienne Carriere1de46d02020-02-07 13:38:30 +0100203 clk_enable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200204
Yann Gautierb76c61a2020-12-16 10:17:35 +0100205 mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
Yann Gautier3edc7c32019-05-20 19:17:08 +0200206 SYSCFG_CMPENSETR_MPU_EN);
Yann Gautierb76c61a2020-12-16 10:17:35 +0100207}
Yann Gautier3edc7c32019-05-20 19:17:08 +0200208
Yann Gautierb76c61a2020-12-16 10:17:35 +0100209void stm32mp1_syscfg_enable_io_compensation_finish(void)
210{
211 enable_io_comp_cell_finish(SYSCFG_CMPCR);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200212}
213
214void stm32mp1_syscfg_disable_io_compensation(void)
215{
Yann Gautierb76c61a2020-12-16 10:17:35 +0100216 clk_enable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200217
218 /*
219 * Deactivate automatic I/O compensation.
220 * Warning: CSI is disabled automatically in STOP if not
221 * requested for other usages and always OFF in STANDBY.
222 * Disable non-secure SYSCFG clock, we assume non-secure is suspended.
223 */
Yann Gautierb76c61a2020-12-16 10:17:35 +0100224 disable_io_comp_cell(SYSCFG_CMPCR);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200225
Etienne Carriere1de46d02020-02-07 13:38:30 +0100226 clk_disable(SYSCFG);
Yann Gautier3edc7c32019-05-20 19:17:08 +0200227}