1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2016, Linaro Ltd 4 */ 5 6 #include <linux/io.h> 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/of_address.h> 10 #include <linux/of_irq.h> 11 #include <linux/interrupt.h> 12 #include <linux/platform_device.h> 13 #include <linux/mailbox_client.h> 14 #include <linux/mfd/syscon.h> 15 #include <linux/slab.h> 16 #include <linux/rpmsg.h> 17 #include <linux/idr.h> 18 #include <linux/circ_buf.h> 19 #include <linux/soc/qcom/smem.h> 20 #include <linux/sizes.h> 21 #include <linux/delay.h> 22 #include <linux/regmap.h> 23 #include <linux/workqueue.h> 24 #include <linux/list.h> 25 26 #include <linux/rpmsg/qcom_glink.h> 27 28 #include "qcom_glink_native.h" 29 30 #define FIFO_FULL_RESERVE 8 31 #define FIFO_ALIGNMENT 8 32 #define TX_BLOCKED_CMD_RESERVE 8 /* size of struct read_notif_request */ 33 34 #define SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR 478 35 #define SMEM_GLINK_NATIVE_XPRT_FIFO_0 479 36 #define SMEM_GLINK_NATIVE_XPRT_FIFO_1 480 37 38 struct qcom_glink_smem { 39 struct device dev; 40 41 int irq; 42 struct qcom_glink *glink; 43 44 struct mbox_client mbox_client; 45 struct mbox_chan *mbox_chan; 46 47 u32 remote_pid; 48 }; 49 50 struct glink_smem_pipe { 51 struct qcom_glink_pipe native; 52 53 __le32 *tail; 54 __le32 *head; 55 56 void *fifo; 57 58 struct qcom_glink_smem *smem; 59 }; 60 61 #define to_smem_pipe(p) container_of(p, struct glink_smem_pipe, native) 62 63 static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np) 64 { 65 struct glink_smem_pipe *pipe = to_smem_pipe(np); 66 struct qcom_glink_smem *smem = pipe->smem; 67 size_t len; 68 void *fifo; 69 u32 head; 70 u32 tail; 71 72 if (!pipe->fifo) { 73 fifo = qcom_smem_get(smem->remote_pid, 74 SMEM_GLINK_NATIVE_XPRT_FIFO_1, &len); 75 if (IS_ERR(fifo)) { 76 pr_err("failed to acquire RX fifo handle: %ld\n", 77 PTR_ERR(fifo)); 78 return 0; 79 } 80 81 pipe->fifo = fifo; 82 pipe->native.length = len; 83 } 84 85 head = le32_to_cpu(*pipe->head); 86 tail = le32_to_cpu(*pipe->tail); 87 88 if (head < tail) 89 return pipe->native.length - tail + head; 90 else 91 return head - tail; 92 } 93 94 static void glink_smem_rx_peek(struct qcom_glink_pipe *np, 95 void *data, unsigned int offset, size_t count) 96 { 97 struct glink_smem_pipe *pipe = to_smem_pipe(np); 98 size_t len; 99 u32 tail; 100 101 tail = le32_to_cpu(*pipe->tail); 102 tail += offset; 103 if (tail >= pipe->native.length) 104 tail -= pipe->native.length; 105 106 /* 107 * Order the availability (head) read in glink_smem_rx_avail() 108 * against the FIFO payload read below, so APPS never consumes 109 * stale data the remote has not yet published. 110 */ 111 rmb(); 112 113 len = min_t(size_t, count, pipe->native.length - tail); 114 if (len) 115 memcpy_fromio(data, pipe->fifo + tail, len); 116 117 if (len != count) 118 memcpy_fromio(data + len, pipe->fifo, (count - len)); 119 } 120 121 static void glink_smem_rx_advance(struct qcom_glink_pipe *np, 122 size_t count) 123 { 124 struct glink_smem_pipe *pipe = to_smem_pipe(np); 125 u32 tail; 126 127 tail = le32_to_cpu(*pipe->tail); 128 129 tail += count; 130 if (tail >= pipe->native.length) 131 tail -= pipe->native.length; 132 133 *pipe->tail = cpu_to_le32(tail); 134 } 135 136 static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np) 137 { 138 struct glink_smem_pipe *pipe = to_smem_pipe(np); 139 u32 head; 140 u32 tail; 141 u32 avail; 142 143 head = le32_to_cpu(*pipe->head); 144 tail = le32_to_cpu(*pipe->tail); 145 146 if (tail <= head) 147 avail = pipe->native.length - head + tail; 148 else 149 avail = tail - head; 150 151 if (avail < (FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE)) 152 avail = 0; 153 else 154 avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE; 155 156 return avail; 157 } 158 159 static unsigned int glink_smem_tx_write_one(struct glink_smem_pipe *pipe, 160 unsigned int head, 161 const void *data, size_t count) 162 { 163 size_t len; 164 165 len = min_t(size_t, count, pipe->native.length - head); 166 if (len) 167 memcpy(pipe->fifo + head, data, len); 168 169 if (len != count) 170 memcpy(pipe->fifo, data + len, count - len); 171 172 head += count; 173 if (head >= pipe->native.length) 174 head -= pipe->native.length; 175 176 return head; 177 } 178 179 static void glink_smem_tx_write(struct qcom_glink_pipe *glink_pipe, 180 const void *hdr, size_t hlen, 181 const void *data, size_t dlen) 182 { 183 struct glink_smem_pipe *pipe = to_smem_pipe(glink_pipe); 184 unsigned int head; 185 186 head = le32_to_cpu(*pipe->head); 187 188 head = glink_smem_tx_write_one(pipe, head, hdr, hlen); 189 head = glink_smem_tx_write_one(pipe, head, data, dlen); 190 191 /* Ensure head is always aligned to 8 bytes */ 192 head = ALIGN(head, 8); 193 if (head >= pipe->native.length) 194 head -= pipe->native.length; 195 196 /* Ensure ordering of fifo and head update */ 197 wmb(); 198 199 *pipe->head = cpu_to_le32(head); 200 } 201 202 static void glink_smem_tx_kick(struct qcom_glink_pipe *glink_pipe) 203 { 204 struct glink_smem_pipe *pipe = to_smem_pipe(glink_pipe); 205 struct qcom_glink_smem *smem = pipe->smem; 206 207 mbox_send_message(smem->mbox_chan, NULL); 208 mbox_client_txdone(smem->mbox_chan, 0); 209 } 210 211 static irqreturn_t qcom_glink_smem_intr(int irq, void *data) 212 { 213 struct qcom_glink_smem *smem = data; 214 215 qcom_glink_native_rx(smem->glink); 216 217 return IRQ_HANDLED; 218 } 219 220 static void qcom_glink_smem_release(struct device *dev) 221 { 222 struct qcom_glink_smem *smem = container_of(dev, struct qcom_glink_smem, dev); 223 224 kfree(smem); 225 } 226 227 struct qcom_glink_smem *qcom_glink_smem_register(struct device *parent, 228 struct device_node *node) 229 { 230 struct glink_smem_pipe *rx_pipe; 231 struct glink_smem_pipe *tx_pipe; 232 struct qcom_glink_smem *smem; 233 struct qcom_glink *glink; 234 struct device *dev; 235 u32 remote_pid; 236 __le32 *descs; 237 size_t size; 238 int ret; 239 240 smem = kzalloc_obj(*smem); 241 if (!smem) 242 return ERR_PTR(-ENOMEM); 243 244 dev = &smem->dev; 245 246 dev->parent = parent; 247 dev->of_node = node; 248 dev->release = qcom_glink_smem_release; 249 dev_set_name(dev, "%s:%pOFn", dev_name(parent->parent), node); 250 ret = device_register(dev); 251 if (ret) { 252 pr_err("failed to register glink edge\n"); 253 put_device(dev); 254 return ERR_PTR(ret); 255 } 256 257 ret = of_property_read_u32(dev->of_node, "qcom,remote-pid", 258 &remote_pid); 259 if (ret) { 260 dev_err(dev, "failed to parse qcom,remote-pid\n"); 261 goto err_put_dev; 262 } 263 264 smem->remote_pid = remote_pid; 265 266 rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL); 267 tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL); 268 if (!rx_pipe || !tx_pipe) { 269 ret = -ENOMEM; 270 goto err_put_dev; 271 } 272 273 ret = qcom_smem_alloc(remote_pid, 274 SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32); 275 if (ret && ret != -EEXIST) { 276 dev_err(dev, "failed to allocate glink descriptors\n"); 277 goto err_put_dev; 278 } 279 280 descs = qcom_smem_get(remote_pid, 281 SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size); 282 if (IS_ERR(descs)) { 283 dev_err(dev, "failed to acquire xprt descriptor\n"); 284 ret = PTR_ERR(descs); 285 goto err_put_dev; 286 } 287 288 if (size != 32) { 289 dev_err(dev, "glink descriptor of invalid size\n"); 290 ret = -EINVAL; 291 goto err_put_dev; 292 } 293 294 tx_pipe->tail = &descs[0]; 295 tx_pipe->head = &descs[1]; 296 rx_pipe->tail = &descs[2]; 297 rx_pipe->head = &descs[3]; 298 299 ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0, 300 SZ_16K); 301 if (ret && ret != -EEXIST) { 302 dev_err(dev, "failed to allocate TX fifo\n"); 303 goto err_put_dev; 304 } 305 306 tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0, 307 &tx_pipe->native.length); 308 if (IS_ERR(tx_pipe->fifo)) { 309 dev_err(dev, "failed to acquire TX fifo\n"); 310 ret = PTR_ERR(tx_pipe->fifo); 311 goto err_put_dev; 312 } 313 314 smem->irq = of_irq_get(smem->dev.of_node, 0); 315 ret = devm_request_irq(&smem->dev, smem->irq, qcom_glink_smem_intr, 316 IRQF_NO_SUSPEND | IRQF_NO_AUTOEN, 317 "glink-smem", smem); 318 if (ret) { 319 dev_err(&smem->dev, "failed to request IRQ\n"); 320 goto err_put_dev; 321 } 322 323 smem->mbox_client.dev = &smem->dev; 324 smem->mbox_client.knows_txdone = true; 325 smem->mbox_chan = mbox_request_channel(&smem->mbox_client, 0); 326 if (IS_ERR(smem->mbox_chan)) { 327 ret = dev_err_probe(&smem->dev, PTR_ERR(smem->mbox_chan), 328 "failed to acquire IPC channel\n"); 329 goto err_put_dev; 330 } 331 332 rx_pipe->smem = smem; 333 rx_pipe->native.avail = glink_smem_rx_avail; 334 rx_pipe->native.peek = glink_smem_rx_peek; 335 rx_pipe->native.advance = glink_smem_rx_advance; 336 337 tx_pipe->smem = smem; 338 tx_pipe->native.avail = glink_smem_tx_avail; 339 tx_pipe->native.write = glink_smem_tx_write; 340 tx_pipe->native.kick = glink_smem_tx_kick; 341 342 *rx_pipe->tail = 0; 343 *tx_pipe->head = 0; 344 345 glink = qcom_glink_native_probe(dev, 346 GLINK_FEATURE_INTENT_REUSE, 347 &rx_pipe->native, &tx_pipe->native, 348 false); 349 if (IS_ERR(glink)) { 350 ret = PTR_ERR(glink); 351 goto err_free_mbox; 352 } 353 354 smem->glink = glink; 355 356 enable_irq(smem->irq); 357 358 return smem; 359 360 err_free_mbox: 361 mbox_free_channel(smem->mbox_chan); 362 363 err_put_dev: 364 device_unregister(dev); 365 366 return ERR_PTR(ret); 367 } 368 EXPORT_SYMBOL_GPL(qcom_glink_smem_register); 369 370 void qcom_glink_smem_unregister(struct qcom_glink_smem *smem) 371 { 372 struct qcom_glink *glink = smem->glink; 373 374 disable_irq(smem->irq); 375 376 qcom_glink_native_remove(glink); 377 378 mbox_free_channel(smem->mbox_chan); 379 device_unregister(&smem->dev); 380 } 381 EXPORT_SYMBOL_GPL(qcom_glink_smem_unregister); 382 383 MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>"); 384 MODULE_DESCRIPTION("Qualcomm GLINK SMEM driver"); 385 MODULE_LICENSE("GPL v2"); 386