1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2018 NXP 4 * Author: Dong Aisheng <aisheng.dong@nxp.com> 5 * 6 * Implementation of the SCU IPC functions using MUs (client side). 7 * 8 */ 9 10 #include <linux/err.h> 11 #include <linux/firmware/imx/ipc.h> 12 #include <linux/firmware/imx/sci.h> 13 #include <linux/interrupt.h> 14 #include <linux/irq.h> 15 #include <linux/kernel.h> 16 #include <linux/mailbox_client.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/of.h> 20 #include <linux/of_platform.h> 21 #include <linux/platform_device.h> 22 23 #define SCU_MU_CHAN_NUM 8 24 #define MAX_RX_TIMEOUT (msecs_to_jiffies(3000)) 25 26 struct imx_sc_chan { 27 struct imx_sc_ipc *sc_ipc; 28 29 struct mbox_client cl; 30 struct mbox_chan *ch; 31 int idx; 32 struct completion tx_done; 33 }; 34 35 struct imx_sc_ipc { 36 /* SCU uses 4 Tx and 4 Rx channels */ 37 struct imx_sc_chan chans[SCU_MU_CHAN_NUM]; 38 struct device *dev; 39 struct mutex lock; 40 struct completion done; 41 bool fast_ipc; 42 43 /* temporarily store the SCU msg */ 44 u32 *msg; 45 u8 rx_size; 46 u8 count; 47 }; 48 49 /* 50 * This type is used to indicate error response for most functions. 51 */ 52 enum imx_sc_error_codes { 53 IMX_SC_ERR_NONE = 0, /* Success */ 54 IMX_SC_ERR_VERSION = 1, /* Incompatible API version */ 55 IMX_SC_ERR_CONFIG = 2, /* Configuration error */ 56 IMX_SC_ERR_PARM = 3, /* Bad parameter */ 57 IMX_SC_ERR_NOACCESS = 4, /* Permission error (no access) */ 58 IMX_SC_ERR_LOCKED = 5, /* Permission error (locked) */ 59 IMX_SC_ERR_UNAVAILABLE = 6, /* Unavailable (out of resources) */ 60 IMX_SC_ERR_NOTFOUND = 7, /* Not found */ 61 IMX_SC_ERR_NOPOWER = 8, /* No power */ 62 IMX_SC_ERR_IPC = 9, /* Generic IPC error */ 63 IMX_SC_ERR_BUSY = 10, /* Resource is currently busy/active */ 64 IMX_SC_ERR_FAIL = 11, /* General I/O failure */ 65 IMX_SC_ERR_LAST 66 }; 67 68 static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = { 69 0, /* IMX_SC_ERR_NONE */ 70 -EINVAL, /* IMX_SC_ERR_VERSION */ 71 -EINVAL, /* IMX_SC_ERR_CONFIG */ 72 -EINVAL, /* IMX_SC_ERR_PARM */ 73 -EACCES, /* IMX_SC_ERR_NOACCESS */ 74 -EACCES, /* IMX_SC_ERR_LOCKED */ 75 -ERANGE, /* IMX_SC_ERR_UNAVAILABLE */ 76 -ENOENT, /* IMX_SC_ERR_NOTFOUND */ 77 -ENODEV, /* IMX_SC_ERR_NOPOWER */ 78 -ECOMM, /* IMX_SC_ERR_IPC */ 79 -EBUSY, /* IMX_SC_ERR_BUSY */ 80 -EIO, /* IMX_SC_ERR_FAIL */ 81 }; 82 83 static struct imx_sc_ipc *imx_sc_ipc_handle; 84 85 static void imx_scu_free_mbox_chan(void *data) 86 { 87 mbox_free_channel(data); 88 } 89 90 static void imx_scu_clear_handle(void *data) 91 { 92 if (imx_sc_ipc_handle == data) 93 imx_sc_ipc_handle = NULL; 94 } 95 96 static inline int imx_sc_to_linux_errno(int errno) 97 { 98 if (errno >= IMX_SC_ERR_NONE && errno < IMX_SC_ERR_LAST) 99 return imx_sc_linux_errmap[errno]; 100 return -EIO; 101 } 102 103 /* 104 * Get the default handle used by SCU 105 */ 106 int imx_scu_get_handle(struct imx_sc_ipc **ipc) 107 { 108 if (!imx_sc_ipc_handle) 109 return -EPROBE_DEFER; 110 111 *ipc = imx_sc_ipc_handle; 112 return 0; 113 } 114 EXPORT_SYMBOL(imx_scu_get_handle); 115 116 /* Callback called when the word of a message is ack-ed, eg read by SCU */ 117 static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r) 118 { 119 struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl); 120 121 complete(&sc_chan->tx_done); 122 } 123 124 static void imx_scu_rx_callback(struct mbox_client *c, void *msg) 125 { 126 struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl); 127 struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc; 128 struct imx_sc_rpc_msg *hdr; 129 u32 *data = msg; 130 int i; 131 132 if (!sc_ipc->msg) { 133 dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n", 134 sc_chan->idx, *data); 135 return; 136 } 137 138 if (sc_ipc->fast_ipc) { 139 hdr = msg; 140 sc_ipc->rx_size = hdr->size; 141 sc_ipc->msg[0] = *data++; 142 143 for (i = 1; i < sc_ipc->rx_size; i++) 144 sc_ipc->msg[i] = *data++; 145 146 complete(&sc_ipc->done); 147 148 return; 149 } 150 151 if (sc_chan->idx == 0) { 152 hdr = msg; 153 sc_ipc->rx_size = hdr->size; 154 dev_dbg(sc_ipc->dev, "msg rx size %u\n", sc_ipc->rx_size); 155 if (sc_ipc->rx_size > 4) 156 dev_warn(sc_ipc->dev, "RPC does not support receiving over 4 words: %u\n", 157 sc_ipc->rx_size); 158 } 159 160 sc_ipc->msg[sc_chan->idx] = *data; 161 sc_ipc->count++; 162 163 dev_dbg(sc_ipc->dev, "mu %u msg %u 0x%x\n", sc_chan->idx, 164 sc_ipc->count, *data); 165 166 if ((sc_ipc->rx_size != 0) && (sc_ipc->count == sc_ipc->rx_size)) 167 complete(&sc_ipc->done); 168 } 169 170 static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) 171 { 172 struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg; 173 struct imx_sc_chan *sc_chan; 174 u32 *data = msg; 175 int ret; 176 int size; 177 int i; 178 179 /* Check size */ 180 if (hdr.size > IMX_SC_RPC_MAX_MSG) 181 return -EINVAL; 182 183 dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc, 184 hdr.func, hdr.size); 185 186 size = sc_ipc->fast_ipc ? 1 : hdr.size; 187 for (i = 0; i < size; i++) { 188 sc_chan = &sc_ipc->chans[i % 4]; 189 190 /* 191 * SCU requires that all messages words are written 192 * sequentially but linux MU driver implements multiple 193 * independent channels for each register so ordering between 194 * different channels must be ensured by SCU API interface. 195 * 196 * Wait for tx_done before every send to ensure that no 197 * queueing happens at the mailbox channel level. 198 */ 199 if (!sc_ipc->fast_ipc) { 200 wait_for_completion(&sc_chan->tx_done); 201 reinit_completion(&sc_chan->tx_done); 202 } 203 204 ret = mbox_send_message(sc_chan->ch, &data[i]); 205 if (ret < 0) 206 return ret; 207 } 208 209 return 0; 210 } 211 212 /* 213 * RPC command/response 214 */ 215 int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp) 216 { 217 uint8_t saved_svc, saved_func; 218 struct imx_sc_rpc_msg *hdr; 219 int ret; 220 221 if (WARN_ON(!sc_ipc || !msg)) 222 return -EINVAL; 223 224 mutex_lock(&sc_ipc->lock); 225 reinit_completion(&sc_ipc->done); 226 227 if (have_resp) { 228 sc_ipc->msg = msg; 229 saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc; 230 saved_func = ((struct imx_sc_rpc_msg *)msg)->func; 231 } 232 sc_ipc->count = 0; 233 ret = imx_scu_ipc_write(sc_ipc, msg); 234 if (ret < 0) { 235 dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret); 236 goto out; 237 } 238 239 if (have_resp) { 240 if (!wait_for_completion_timeout(&sc_ipc->done, 241 MAX_RX_TIMEOUT)) { 242 dev_err(sc_ipc->dev, "RPC send msg timeout\n"); 243 mutex_unlock(&sc_ipc->lock); 244 return -ETIMEDOUT; 245 } 246 247 /* response status is stored in hdr->func field */ 248 hdr = msg; 249 ret = hdr->func; 250 /* 251 * Some special SCU firmware APIs do NOT have return value 252 * in hdr->func, but they do have response data, those special 253 * APIs are defined as void function in SCU firmware, so they 254 * should be treated as return success always. 255 */ 256 if ((saved_svc == IMX_SC_RPC_SVC_MISC) && 257 (saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID || 258 saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS)) 259 ret = 0; 260 } 261 262 out: 263 sc_ipc->msg = NULL; 264 mutex_unlock(&sc_ipc->lock); 265 266 dev_dbg(sc_ipc->dev, "RPC SVC done\n"); 267 268 return imx_sc_to_linux_errno(ret); 269 } 270 EXPORT_SYMBOL(imx_scu_call_rpc); 271 272 static int imx_scu_probe(struct platform_device *pdev) 273 { 274 struct device *dev = &pdev->dev; 275 struct imx_sc_ipc *sc_ipc; 276 struct imx_sc_chan *sc_chan; 277 struct mbox_client *cl; 278 char *chan_name; 279 struct of_phandle_args args; 280 int num_channel; 281 int ret; 282 int i; 283 284 sc_ipc = devm_kzalloc(dev, sizeof(*sc_ipc), GFP_KERNEL); 285 if (!sc_ipc) 286 return -ENOMEM; 287 288 ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes", 289 "#mbox-cells", 0, &args); 290 if (ret) 291 return ret; 292 293 sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu"); 294 of_node_put(args.np); 295 296 num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM; 297 for (i = 0; i < num_channel; i++) { 298 if (i < num_channel / 2) 299 chan_name = kasprintf(GFP_KERNEL, "tx%d", i); 300 else 301 chan_name = kasprintf(GFP_KERNEL, "rx%d", 302 i - num_channel / 2); 303 304 if (!chan_name) 305 return -ENOMEM; 306 307 sc_chan = &sc_ipc->chans[i]; 308 cl = &sc_chan->cl; 309 cl->dev = dev; 310 cl->tx_block = false; 311 cl->knows_txdone = true; 312 cl->rx_callback = imx_scu_rx_callback; 313 314 if (!sc_ipc->fast_ipc) { 315 /* Initial tx_done completion as "done" */ 316 cl->tx_done = imx_scu_tx_done; 317 init_completion(&sc_chan->tx_done); 318 complete(&sc_chan->tx_done); 319 } 320 321 sc_chan->sc_ipc = sc_ipc; 322 sc_chan->idx = i % (num_channel / 2); 323 sc_chan->ch = mbox_request_channel_byname(cl, chan_name); 324 if (IS_ERR(sc_chan->ch)) { 325 ret = PTR_ERR(sc_chan->ch); 326 dev_err_probe(dev, ret, "Failed to request mbox chan %s\n", 327 chan_name); 328 kfree(chan_name); 329 return ret; 330 } 331 332 dev_dbg(dev, "request mbox chan %s\n", chan_name); 333 /* chan_name is not used anymore by framework */ 334 kfree(chan_name); 335 336 ret = devm_add_action_or_reset(dev, imx_scu_free_mbox_chan, 337 sc_chan->ch); 338 if (ret) 339 return ret; 340 } 341 342 sc_ipc->dev = dev; 343 ret = devm_mutex_init(dev, &sc_ipc->lock); 344 if (ret) 345 return ret; 346 init_completion(&sc_ipc->done); 347 348 imx_sc_ipc_handle = sc_ipc; 349 ret = devm_add_action_or_reset(dev, imx_scu_clear_handle, sc_ipc); 350 if (ret) 351 return ret; 352 353 ret = imx_scu_soc_init(dev); 354 if (ret) 355 dev_warn(dev, "failed to initialize SoC info: %d\n", ret); 356 357 ret = imx_scu_enable_general_irq_channel(dev); 358 if (ret) 359 dev_warn(dev, 360 "failed to enable general irq channel: %d\n", ret); 361 362 dev_info(dev, "NXP i.MX SCU Initialized\n"); 363 364 ret = devm_of_platform_populate(dev); 365 if (ret) 366 of_platform_depopulate(dev); 367 368 return ret; 369 } 370 371 static const struct of_device_id imx_scu_match[] = { 372 { .compatible = "fsl,imx-scu", }, 373 { /* Sentinel */ } 374 }; 375 376 static struct platform_driver imx_scu_driver = { 377 .driver = { 378 .name = "imx-scu", 379 .of_match_table = imx_scu_match, 380 .suppress_bind_attrs = true, 381 }, 382 .probe = imx_scu_probe, 383 }; 384 385 static int __init imx_scu_driver_init(void) 386 { 387 return platform_driver_register(&imx_scu_driver); 388 } 389 subsys_initcall_sync(imx_scu_driver_init); 390 391 MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>"); 392 MODULE_DESCRIPTION("IMX SCU firmware protocol driver"); 393 MODULE_LICENSE("GPL v2"); 394