1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * System Control and Management Interface (SCMI) Message SMC/HVC 4 * Transport driver 5 * 6 * Copyright 2020 NXP 7 */ 8 9 #include <linux/arm-smccc.h> 10 #include <linux/atomic.h> 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/interrupt.h> 14 #include <linux/mutex.h> 15 #include <linux/of.h> 16 #include <linux/of_address.h> 17 #include <linux/of_irq.h> 18 #include <linux/processor.h> 19 #include <linux/slab.h> 20 21 #include "common.h" 22 23 /* 24 * The shmem address is split into 4K page and offset. 25 * This is to make sure the parameters fit in 32bit arguments of the 26 * smc/hvc call to keep it uniform across smc32/smc64 conventions. 27 * This however limits the shmem address to 44 bit. 28 * 29 * These optional parameters can be used to distinguish among multiple 30 * scmi instances that are using the same smc-id. 31 * The page parameter is passed in r1/x1/w1 register and the offset parameter 32 * is passed in r2/x2/w2 register. 33 */ 34 35 #define SHMEM_SIZE (SZ_4K) 36 #define SHMEM_SHIFT 12 37 #define SHMEM_PAGE(x) (_UL((x) >> SHMEM_SHIFT)) 38 #define SHMEM_OFFSET(x) ((x) & (SHMEM_SIZE - 1)) 39 40 /** 41 * struct scmi_smc - Structure representing a SCMI smc transport 42 * 43 * @cinfo: SCMI channel info 44 * @shmem: Transmit/Receive shared memory area 45 * @shmem_lock: Lock to protect access to Tx/Rx shared memory area. 46 * Used when NOT operating in atomic mode. 47 * @inflight: Atomic flag to protect access to Tx/Rx shared memory area. 48 * Used when operating in atomic mode. 49 * @func_id: smc/hvc call function id 50 * @param_page: 4K page number of the shmem channel 51 * @param_offset: Offset within the 4K page of the shmem channel 52 */ 53 54 struct scmi_smc { 55 struct scmi_chan_info *cinfo; 56 struct scmi_shared_mem __iomem *shmem; 57 /* Protect access to shmem area */ 58 struct mutex shmem_lock; 59 #define INFLIGHT_NONE MSG_TOKEN_MAX 60 atomic_t inflight; 61 u32 func_id; 62 u32 param_page; 63 u32 param_offset; 64 }; 65 66 static irqreturn_t smc_msg_done_isr(int irq, void *data) 67 { 68 struct scmi_smc *scmi_info = data; 69 70 scmi_rx_callback(scmi_info->cinfo, 71 shmem_read_header(scmi_info->shmem), NULL); 72 73 return IRQ_HANDLED; 74 } 75 76 static bool smc_chan_available(struct device_node *of_node, int idx) 77 { 78 struct device_node *np = of_parse_phandle(of_node, "shmem", 0); 79 if (!np) 80 return false; 81 82 of_node_put(np); 83 return true; 84 } 85 86 static inline void smc_channel_lock_init(struct scmi_smc *scmi_info) 87 { 88 if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) 89 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); 90 else 91 mutex_init(&scmi_info->shmem_lock); 92 } 93 94 static bool smc_xfer_inflight(struct scmi_xfer *xfer, atomic_t *inflight) 95 { 96 int ret; 97 98 ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq); 99 100 return ret == INFLIGHT_NONE; 101 } 102 103 static inline void 104 smc_channel_lock_acquire(struct scmi_smc *scmi_info, 105 struct scmi_xfer *xfer __maybe_unused) 106 { 107 if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) 108 spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight)); 109 else 110 mutex_lock(&scmi_info->shmem_lock); 111 } 112 113 static inline void smc_channel_lock_release(struct scmi_smc *scmi_info) 114 { 115 if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) 116 atomic_set(&scmi_info->inflight, INFLIGHT_NONE); 117 else 118 mutex_unlock(&scmi_info->shmem_lock); 119 } 120 121 static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, 122 bool tx) 123 { 124 struct device *cdev = cinfo->dev; 125 struct scmi_smc *scmi_info; 126 resource_size_t size; 127 struct resource res; 128 struct device_node *np; 129 u32 func_id; 130 int ret, irq; 131 132 if (!tx) 133 return -ENODEV; 134 135 scmi_info = devm_kzalloc(dev, sizeof(*scmi_info), GFP_KERNEL); 136 if (!scmi_info) 137 return -ENOMEM; 138 139 np = of_parse_phandle(cdev->of_node, "shmem", 0); 140 if (!of_device_is_compatible(np, "arm,scmi-shmem")) 141 return -ENXIO; 142 143 ret = of_address_to_resource(np, 0, &res); 144 of_node_put(np); 145 if (ret) { 146 dev_err(cdev, "failed to get SCMI Tx shared memory\n"); 147 return ret; 148 } 149 150 size = resource_size(&res); 151 scmi_info->shmem = devm_ioremap(dev, res.start, size); 152 if (!scmi_info->shmem) { 153 dev_err(dev, "failed to ioremap SCMI Tx shared memory\n"); 154 return -EADDRNOTAVAIL; 155 } 156 157 ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); 158 if (ret < 0) 159 return ret; 160 161 if (of_device_is_compatible(dev->of_node, "arm,scmi-smc-param")) { 162 scmi_info->param_page = SHMEM_PAGE(res.start); 163 scmi_info->param_offset = SHMEM_OFFSET(res.start); 164 } 165 /* 166 * If there is an interrupt named "a2p", then the service and 167 * completion of a message is signaled by an interrupt rather than by 168 * the return of the SMC call. 169 */ 170 irq = of_irq_get_byname(cdev->of_node, "a2p"); 171 if (irq > 0) { 172 ret = devm_request_irq(dev, irq, smc_msg_done_isr, 173 IRQF_NO_SUSPEND, 174 dev_name(dev), scmi_info); 175 if (ret) { 176 dev_err(dev, "failed to setup SCMI smc irq\n"); 177 return ret; 178 } 179 } else { 180 cinfo->no_completion_irq = true; 181 } 182 183 scmi_info->func_id = func_id; 184 scmi_info->cinfo = cinfo; 185 smc_channel_lock_init(scmi_info); 186 cinfo->transport_info = scmi_info; 187 188 return 0; 189 } 190 191 static int smc_chan_free(int id, void *p, void *data) 192 { 193 struct scmi_chan_info *cinfo = p; 194 struct scmi_smc *scmi_info = cinfo->transport_info; 195 196 cinfo->transport_info = NULL; 197 scmi_info->cinfo = NULL; 198 199 return 0; 200 } 201 202 static int smc_send_message(struct scmi_chan_info *cinfo, 203 struct scmi_xfer *xfer) 204 { 205 struct scmi_smc *scmi_info = cinfo->transport_info; 206 struct arm_smccc_res res; 207 unsigned long page = scmi_info->param_page; 208 unsigned long offset = scmi_info->param_offset; 209 210 /* 211 * Channel will be released only once response has been 212 * surely fully retrieved, so after .mark_txdone() 213 */ 214 smc_channel_lock_acquire(scmi_info, xfer); 215 216 shmem_tx_prepare(scmi_info->shmem, xfer, cinfo); 217 218 arm_smccc_1_1_invoke(scmi_info->func_id, page, offset, 0, 0, 0, 0, 0, 219 &res); 220 221 /* Only SMCCC_RET_NOT_SUPPORTED is valid error code */ 222 if (res.a0) { 223 smc_channel_lock_release(scmi_info); 224 return -EOPNOTSUPP; 225 } 226 227 return 0; 228 } 229 230 static void smc_fetch_response(struct scmi_chan_info *cinfo, 231 struct scmi_xfer *xfer) 232 { 233 struct scmi_smc *scmi_info = cinfo->transport_info; 234 235 shmem_fetch_response(scmi_info->shmem, xfer); 236 } 237 238 static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret, 239 struct scmi_xfer *__unused) 240 { 241 struct scmi_smc *scmi_info = cinfo->transport_info; 242 243 smc_channel_lock_release(scmi_info); 244 } 245 246 static const struct scmi_transport_ops scmi_smc_ops = { 247 .chan_available = smc_chan_available, 248 .chan_setup = smc_chan_setup, 249 .chan_free = smc_chan_free, 250 .send_message = smc_send_message, 251 .mark_txdone = smc_mark_txdone, 252 .fetch_response = smc_fetch_response, 253 }; 254 255 const struct scmi_desc scmi_smc_desc = { 256 .ops = &scmi_smc_ops, 257 .max_rx_timeout_ms = 30, 258 .max_msg = 20, 259 .max_msg_size = 128, 260 /* 261 * Setting .sync_cmds_atomic_replies to true for SMC assumes that, 262 * once the SMC instruction has completed successfully, the issued 263 * SCMI command would have been already fully processed by the SCMI 264 * platform firmware and so any possible response value expected 265 * for the issued command will be immmediately ready to be fetched 266 * from the shared memory area. 267 */ 268 .sync_cmds_completed_on_ret = true, 269 .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE), 270 }; 271