1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* 3 * Copyright (c) 2018-2019, STMicroelectronics 4 */ 5 6 #ifndef __STM32_UTIL_H__ 7 #define __STM32_UTIL_H__ 8 9 #include <assert.h> 10 #include <drivers/stm32_bsec.h> 11 #include <kernel/panic.h> 12 #include <stdint.h> 13 14 /* Backup registers and RAM utils */ 15 uintptr_t stm32mp_bkpreg(unsigned int idx); 16 17 /* Platform util for the GIC */ 18 uintptr_t get_gicc_base(void); 19 uintptr_t get_gicd_base(void); 20 21 /* 22 * Platform util functions for the GPIO driver 23 * @bank: Target GPIO bank ID as per DT bindings 24 * 25 * Platform shall implement these functions to provide to stm32_gpio 26 * driver the resource reference for a target GPIO bank. That are 27 * memory mapped interface base address, interface offset (see below) 28 * and clock identifier. 29 * 30 * stm32_get_gpio_bank_offset() returns a bank offset that is used to 31 * check DT configuration matches platform implementation of the banks 32 * description. 33 */ 34 vaddr_t stm32_get_gpio_bank_base(unsigned int bank); 35 unsigned int stm32_get_gpio_bank_offset(unsigned int bank); 36 unsigned int stm32_get_gpio_bank_clock(unsigned int bank); 37 38 /* Power management service */ 39 #ifdef CFG_PSCI_ARM32 40 void stm32mp_register_online_cpu(void); 41 #else 42 static inline void stm32mp_register_online_cpu(void) 43 { 44 } 45 #endif 46 47 /* 48 * Generic spinlock function that bypass spinlock if MMU is disabled or 49 * lock is NULL. 50 */ 51 uint32_t may_spin_lock(unsigned int *lock); 52 void may_spin_unlock(unsigned int *lock, uint32_t exceptions); 53 54 /* 55 * Util for clock gating and to get clock rate for stm32 and platform drivers 56 * @id: Target clock ID, ID used in clock DT bindings 57 */ 58 void stm32_clock_enable(unsigned long id); 59 void stm32_clock_disable(unsigned long id); 60 unsigned long stm32_clock_get_rate(unsigned long id); 61 bool stm32_clock_is_enabled(unsigned long id); 62 63 /* 64 * Util for reset signal assertion/desassertion for stm32 and platform drivers 65 * @id: Target peripheral ID, ID used in reset DT bindings 66 */ 67 void stm32_reset_assert(unsigned int id); 68 void stm32_reset_deassert(unsigned int id); 69 70 /* 71 * Structure and API function for BSEC driver to get some platform data. 72 * 73 * @base: BSEC interface registers physical base address 74 * @upper_start: Base ID for the BSEC upper words in the platform 75 * @max_id: Max value for BSEC word ID for the platform 76 * @closed_device_id: BSEC word ID storing the "closed_device" OTP bit 77 * @closed_device_position: Bit position of "closed_device" bit in the OTP word 78 */ 79 struct stm32_bsec_static_cfg { 80 paddr_t base; 81 unsigned int upper_start; 82 unsigned int max_id; 83 unsigned int closed_device_id; 84 unsigned int closed_device_position; 85 }; 86 87 void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg); 88 89 /* 90 * Shared reference counter: increments by 2 on secure increment 91 * request, decrements by 2 on secure decrement request. Bit #0 92 * is set to 1 on non-secure increment request and reset to 0 on 93 * non-secure decrement request. These counters initialize to 94 * either 0, 1 or 2 upon their expect default state. 95 * Counters saturate to UINT_MAX / 2. 96 */ 97 #define SHREFCNT_NONSECURE_FLAG 0x1ul 98 #define SHREFCNT_SECURE_STEP 0x2ul 99 #define SHREFCNT_MAX (UINT_MAX / 2) 100 101 /* Return 1 if refcnt increments from 0, else return 0 */ 102 static inline int incr_shrefcnt(unsigned int *refcnt, bool secure) 103 { 104 int rc = !*refcnt; 105 106 if (secure) { 107 if (*refcnt < SHREFCNT_MAX) { 108 *refcnt += SHREFCNT_SECURE_STEP; 109 assert(*refcnt < SHREFCNT_MAX); 110 } 111 } else { 112 *refcnt |= SHREFCNT_NONSECURE_FLAG; 113 } 114 115 return rc; 116 } 117 118 /* Return 1 if refcnt decrements to 0, else return 0 */ 119 static inline int decr_shrefcnt(unsigned int *refcnt, bool secure) 120 { 121 int rc = 0; 122 123 if (secure) { 124 if (*refcnt < SHREFCNT_MAX) { 125 if (*refcnt < SHREFCNT_SECURE_STEP) 126 panic(); 127 128 *refcnt -= SHREFCNT_SECURE_STEP; 129 rc = !*refcnt; 130 } 131 } else { 132 rc = (*refcnt == SHREFCNT_NONSECURE_FLAG); 133 *refcnt &= ~SHREFCNT_NONSECURE_FLAG; 134 } 135 136 return rc; 137 } 138 139 static inline int incr_refcnt(unsigned int *refcnt) 140 { 141 return incr_shrefcnt(refcnt, true); 142 } 143 144 static inline int decr_refcnt(unsigned int *refcnt) 145 { 146 return decr_shrefcnt(refcnt, true); 147 } 148 149 #endif /*__STM32_UTIL_H__*/ 150