1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2021-2022, Linaro Limited 4 * Copyright (c) 2018-2024, STMicroelectronics 5 */ 6 7 #include <arm.h> 8 #include <drivers/rstctrl.h> 9 #include <drivers/stm32mp1_rcc.h> 10 #include <drivers/stm32mp_dt_bindings.h> 11 #include <io.h> 12 #include <keep.h> 13 #include <kernel/dt.h> 14 #include <kernel/dt_driver.h> 15 #include <stm32_util.h> 16 17 #include "stm32_rstctrl.h" 18 19 #define RESET_ID_MASK GENMASK_32(31, 5) 20 #define RESET_ID_SHIFT U(5) 21 #define RESET_BIT_POS_MASK GENMASK_32(4, 0) 22 #define RESET_OFFSET_MAX U(1024) 23 24 static size_t reset_id2reg_offset(unsigned int id) 25 { 26 size_t offset = (id & RESET_ID_MASK) >> RESET_ID_SHIFT; 27 28 assert(offset < RESET_OFFSET_MAX); 29 return offset * sizeof(uint32_t); 30 } 31 32 static uint32_t reset_id2reg_bit_pos(unsigned int reset_id) 33 { 34 uint32_t pos = reset_id & RESET_BIT_POS_MASK; 35 36 assert(pos < 32); 37 return pos; 38 } 39 40 static TEE_Result reset_assert(struct rstctrl *rstctrl, unsigned int to_us) 41 { 42 unsigned int id = to_stm32_rstline(rstctrl)->id; 43 vaddr_t rcc_base = stm32_rcc_base(); 44 uint32_t bit_mask = 0; 45 size_t offset = 0; 46 47 #ifdef CFG_STM32MP15 48 switch (id) { 49 case MCU_HOLD_BOOT_R: 50 /* 51 * The RCC_MP_GCR is a read/write register. 52 * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit 53 */ 54 io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); 55 56 return TEE_SUCCESS; 57 case MCU_R: 58 /* MCU reset can only be written */ 59 to_us = 0; 60 break; 61 default: 62 break; 63 } 64 #endif 65 66 offset = reset_id2reg_offset(id); 67 bit_mask = BIT(reset_id2reg_bit_pos(id)); 68 69 io_write32(rcc_base + offset, bit_mask); 70 71 if (to_us) { 72 uint32_t value = 0; 73 74 if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value, 75 value & bit_mask, 0, to_us)) 76 return TEE_ERROR_GENERIC; 77 } else { 78 /* Make sure the above write is performed */ 79 dsb(); 80 } 81 82 return TEE_SUCCESS; 83 } 84 85 static TEE_Result reset_deassert(struct rstctrl *rstctrl, unsigned int to_us) 86 { 87 unsigned int id = to_stm32_rstline(rstctrl)->id; 88 vaddr_t rcc_base = stm32_rcc_base(); 89 uint32_t bit_mask = 0; 90 size_t offset = 0; 91 92 #ifdef CFG_STM32MP15 93 switch (id) { 94 case MCU_HOLD_BOOT_R: 95 /* 96 * The RCC_MP_GCR is a read/write register. 97 * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit 98 */ 99 io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); 100 101 return TEE_SUCCESS; 102 case MCU_R: 103 /* MCU reset deasserts by its own */ 104 return TEE_SUCCESS; 105 default: 106 break; 107 } 108 #endif 109 110 offset = reset_id2reg_offset(id) + RCC_MP_RSTCLRR_OFFSET; 111 bit_mask = BIT(reset_id2reg_bit_pos(id)); 112 113 io_write32(rcc_base + offset, bit_mask); 114 115 if (to_us) { 116 uint32_t value = 0; 117 118 if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value, 119 !(value & bit_mask), 0, to_us)) 120 return TEE_ERROR_GENERIC; 121 } else { 122 /* Make sure the above write is performed */ 123 dsb(); 124 } 125 126 return TEE_SUCCESS; 127 } 128 129 static const struct rstctrl_ops stm32_rstctrl_ops = { 130 .assert_level = reset_assert, 131 .deassert_level = reset_deassert, 132 }; 133 DECLARE_KEEP_PAGER(stm32_rstctrl_ops); 134 135 static const struct rstctrl_ops *stm32_reset_get_ops(unsigned int id __unused) 136 { 137 return &stm32_rstctrl_ops; 138 } 139 140 static const struct stm32_reset_data stm32mp1_reset_data = { 141 .get_rstctrl_ops = stm32_reset_get_ops 142 }; 143 144 static const struct dt_device_match stm32_rstctrl_match_table[] = { 145 { 146 .compatible = "st,stm32mp1-rcc", 147 .compat_data = &stm32mp1_reset_data, 148 }, 149 { 150 .compatible = "st,stm32mp1-rcc-secure", 151 .compat_data = &stm32mp1_reset_data, 152 }, 153 { 154 .compatible = "st,stm32mp13-rcc", 155 .compat_data = &stm32mp1_reset_data, 156 }, 157 { } 158 }; 159 160 DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = { 161 .name = "stm32_rstctrl", 162 .type = DT_DRIVER_RSTCTRL, 163 .match_table = stm32_rstctrl_match_table, 164 .probe = stm32_rstctrl_provider_probe, 165 }; 166