1 /* 2 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * Zynq UltraScale+ MPSoC IPI agent registers access management 9 */ 10 11 #include <errno.h> 12 #include <string.h> 13 14 #include <common/debug.h> 15 #include <common/runtime_svc.h> 16 #include <lib/bakery_lock.h> 17 #include <lib/mmio.h> 18 19 #include <ipi.h> 20 #include <plat_ipi.h> 21 #include <plat_private.h> 22 23 /********************************************************************* 24 * Macros definitions 25 ********************************************************************/ 26 27 /* IPI registers base address */ 28 #define IPI_REGS_BASE 0xFF300000U 29 30 /* IPI registers offsets macros */ 31 #define IPI_TRIG_OFFSET 0x00U 32 #define IPI_OBR_OFFSET 0x04U 33 #define IPI_ISR_OFFSET 0x10U 34 #define IPI_IMR_OFFSET 0x14U 35 #define IPI_IER_OFFSET 0x18U 36 #define IPI_IDR_OFFSET 0x1CU 37 38 /* IPI register start offset */ 39 #define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base) 40 41 /* IPI register bit mask */ 42 #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask) 43 44 /* IPI secure check */ 45 #define IPI_SECURE_MASK 0x1U 46 #define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \ 47 IPI_SECURE_MASK) ? 1 : 0) 48 49 /* IPI configuration table */ 50 const static struct ipi_config *ipi_table; 51 52 /* Total number of IPI */ 53 static uint32_t ipi_total; 54 55 /* Zynqmp ipi configuration table */ 56 const static struct ipi_config zynqmp_ipi_table[] = { 57 /* APU IPI */ 58 { 59 .ipi_bit_mask = 0x1, 60 .ipi_reg_base = 0xFF300000, 61 .secure_only = 0, 62 }, 63 /* RPU0 IPI */ 64 { 65 .ipi_bit_mask = 0x100, 66 .ipi_reg_base = 0xFF310000, 67 .secure_only = 0, 68 }, 69 /* RPU1 IPI */ 70 { 71 .ipi_bit_mask = 0x200, 72 .ipi_reg_base = 0xFF320000, 73 .secure_only = 0, 74 }, 75 /* PMU0 IPI */ 76 { 77 .ipi_bit_mask = 0x10000, 78 .ipi_reg_base = 0xFF330000, 79 .secure_only = IPI_SECURE_MASK, 80 }, 81 /* PMU1 IPI */ 82 { 83 .ipi_bit_mask = 0x20000, 84 .ipi_reg_base = 0xFF331000, 85 .secure_only = 0, 86 }, 87 /* PMU2 IPI */ 88 { 89 .ipi_bit_mask = 0x40000, 90 .ipi_reg_base = 0xFF332000, 91 .secure_only = IPI_SECURE_MASK, 92 }, 93 /* PMU3 IPI */ 94 { 95 .ipi_bit_mask = 0x80000, 96 .ipi_reg_base = 0xFF333000, 97 .secure_only = IPI_SECURE_MASK, 98 }, 99 /* PL0 IPI */ 100 { 101 .ipi_bit_mask = 0x1000000, 102 .ipi_reg_base = 0xFF340000, 103 .secure_only = 0, 104 }, 105 /* PL1 IPI */ 106 { 107 .ipi_bit_mask = 0x2000000, 108 .ipi_reg_base = 0xFF350000, 109 .secure_only = 0, 110 }, 111 /* PL2 IPI */ 112 { 113 .ipi_bit_mask = 0x4000000, 114 .ipi_reg_base = 0xFF360000, 115 .secure_only = 0, 116 }, 117 /* PL3 IPI */ 118 { 119 .ipi_bit_mask = 0x8000000, 120 .ipi_reg_base = 0xFF370000, 121 .secure_only = 0, 122 }, 123 }; 124 125 /** 126 * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data 127 * 128 */ 129 void zynqmp_ipi_config_table_init(void) 130 { 131 ipi_config_table_init(zynqmp_ipi_table, ARRAY_SIZE(zynqmp_ipi_table)); 132 } 133 134 /** 135 * ipi_config_table_init() - Initialize IPI configuration data 136 * 137 * @ipi_config_table - IPI configuration table 138 * @ipi_total - Total number of IPI available 139 * 140 */ 141 void ipi_config_table_init(const struct ipi_config *ipi_config_table, 142 uint32_t total_ipi) 143 { 144 ipi_table = ipi_config_table; 145 ipi_total = total_ipi; 146 } 147 148 /* is_ipi_mb_within_range() - verify if IPI mailbox is within range 149 * 150 * @local - local IPI ID 151 * @remote - remote IPI ID 152 * 153 * return - 1 if within range, 0 if not 154 */ 155 static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote) 156 { 157 int ret = 1; 158 159 if (remote >= ipi_total || local >= ipi_total) 160 ret = 0; 161 162 return ret; 163 } 164 165 /** 166 * ipi_mb_validate() - validate IPI mailbox access 167 * 168 * @local - local IPI ID 169 * @remote - remote IPI ID 170 * @is_secure - indicate if the requester is from secure software 171 * 172 * return - 0 success, negative value for errors 173 */ 174 int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure) 175 { 176 int ret = 0; 177 178 if (!is_ipi_mb_within_range(local, remote)) 179 ret = -EINVAL; 180 else if (IPI_IS_SECURE(local) && !is_secure) 181 ret = -EPERM; 182 else if (IPI_IS_SECURE(remote) && !is_secure) 183 ret = -EPERM; 184 185 return ret; 186 } 187 188 /** 189 * ipi_mb_open() - Open IPI mailbox. 190 * 191 * @local - local IPI ID 192 * @remote - remote IPI ID 193 * 194 */ 195 void ipi_mb_open(uint32_t local, uint32_t remote) 196 { 197 mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 198 IPI_BIT_MASK(remote)); 199 mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET, 200 IPI_BIT_MASK(remote)); 201 } 202 203 /** 204 * ipi_mb_release() - Open IPI mailbox. 205 * 206 * @local - local IPI ID 207 * @remote - remote IPI ID 208 * 209 */ 210 void ipi_mb_release(uint32_t local, uint32_t remote) 211 { 212 mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 213 IPI_BIT_MASK(remote)); 214 } 215 216 /** 217 * ipi_mb_enquire_status() - Enquire IPI mailbox status 218 * 219 * @local - local IPI ID 220 * @remote - remote IPI ID 221 * 222 * return - 0 idle, positive value for pending sending or receiving, 223 * negative value for errors 224 */ 225 int ipi_mb_enquire_status(uint32_t local, uint32_t remote) 226 { 227 int ret = 0; 228 uint32_t status; 229 230 status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET); 231 if (status & IPI_BIT_MASK(remote)) 232 ret |= IPI_MB_STATUS_SEND_PENDING; 233 status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET); 234 if (status & IPI_BIT_MASK(remote)) 235 ret |= IPI_MB_STATUS_RECV_PENDING; 236 237 return ret; 238 } 239 240 /* ipi_mb_notify() - Trigger IPI mailbox notification 241 * 242 * @local - local IPI ID 243 * @remote - remote IPI ID 244 * @is_blocking - if to trigger the notification in blocking mode or not. 245 * 246 * It sets the remote bit in the IPI agent trigger register. 247 * 248 */ 249 void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking) 250 { 251 uint32_t status; 252 253 mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET, 254 IPI_BIT_MASK(remote)); 255 if (is_blocking) { 256 do { 257 status = mmio_read_32(IPI_REG_BASE(local) + 258 IPI_OBR_OFFSET); 259 } while (status & IPI_BIT_MASK(remote)); 260 } 261 } 262 263 /* ipi_mb_ack() - Ack IPI mailbox notification from the other end 264 * 265 * @local - local IPI ID 266 * @remote - remote IPI ID 267 * 268 * It will clear the remote bit in the isr register. 269 * 270 */ 271 void ipi_mb_ack(uint32_t local, uint32_t remote) 272 { 273 mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET, 274 IPI_BIT_MASK(remote)); 275 } 276 277 /* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt 278 * 279 * @local - local IPI ID 280 * @remote - remote IPI ID 281 * 282 * It will mask the remote bit in the idr register. 283 * 284 */ 285 void ipi_mb_disable_irq(uint32_t local, uint32_t remote) 286 { 287 mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 288 IPI_BIT_MASK(remote)); 289 } 290 291 /* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt 292 * 293 * @local - local IPI ID 294 * @remote - remote IPI ID 295 * 296 * It will mask the remote bit in the idr register. 297 * 298 */ 299 void ipi_mb_enable_irq(uint32_t local, uint32_t remote) 300 { 301 mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET, 302 IPI_BIT_MASK(remote)); 303 } 304