1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2021-2026 Axiado Corporation (or its affiliates). 4 */ 5 6 #include <linux/atomic.h> 7 #include <linux/interrupt.h> 8 #include <linux/io.h> 9 #include <linux/bitfield.h> 10 #include <linux/debugfs.h> 11 #include <linux/iopoll.h> 12 #include <linux/mailbox_controller.h> 13 #include <linux/math.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/property.h> 18 #include <linux/slab.h> 19 #include <linux/unaligned.h> 20 21 #define AXIADO_MBOX_TX_CHANS 8 /* 0-7 */ 22 #define AXIADO_MBOX_RX_CHANS 8 /* 8-15 */ 23 #define AXIADO_MBOX_CHAN_STRIDE 0x4 24 #define AXIADO_MBOX_TX_REG_STRIDE 0x40 25 #define AXIADO_MBOX_RX_REG_STRIDE 0x30 26 #define AXIADO_MBOX_RX_POLL_US 10 27 #define AXIADO_MBOX_RX_TIMEOUT_US 1000 28 29 /* Mailbox CSR bit definitions */ 30 #define AXIADO_MBOX_CSR_EMPTY BIT(0) /* 1 = FIFO empty; 0 = data available */ 31 #define AXIADO_MBOX_CSR_OVERFLOW BIT(2) /* write 1 to clear (W1C) */ 32 #define AXIADO_MBOX_CSR_UNDERFLOW BIT(3) /* write 1 to clear (W1C) */ 33 #define AXIADO_MBOX_CSR_FLUSH BIT(4) /* W1TRG flush; startup/shutdown */ 34 #define AXIADO_MBOX_CSR_LEVEL GENMASK(11, 5) 35 36 #define AXIADO_MBOX_CSR_ERRORS (AXIADO_MBOX_CSR_OVERFLOW | \ 37 AXIADO_MBOX_CSR_UNDERFLOW) 38 39 struct axiado_mbox_data { 40 u8 num_chans; 41 u16 msg_size; 42 }; 43 44 struct axiado_channel_data { 45 void __iomem *mbox_reg; 46 void __iomem *csr_reg; 47 void *rx_buffer; 48 u8 channel_num; 49 int irq; 50 struct mbox_chan *chan; 51 bool active; 52 atomic_t fifo_errors; 53 }; 54 55 /* mailbox side */ 56 struct axiado_mbox { 57 struct mbox_controller mbox; 58 const struct axiado_mbox_data *drv_data; 59 void __iomem *tx_base; 60 void __iomem *rx_base; 61 struct dentry *debugfs_dir; 62 }; 63 64 /* 65 * Checks OVERFLOW/UNDERFLOW, logs and W1C-clears them if set. Shared by the 66 * TX and RX paths; RX additionally flushes the FIFO afterwards to resync 67 * framing, which TX must not do since it could discard data the peer has 68 * not read yet. 69 */ 70 static bool axiado_mbox_clear_fifo_errors(struct axiado_channel_data *priv) 71 { 72 struct device *dev = priv->chan->mbox->dev; 73 u32 errors; 74 75 errors = readl(priv->csr_reg) & AXIADO_MBOX_CSR_ERRORS; 76 if (!errors) 77 return false; 78 79 writel(errors, priv->csr_reg); 80 atomic_inc(&priv->fifo_errors); 81 82 dev_warn_ratelimited(dev, "Channel %u FIFO error: %#x\n", 83 priv->channel_num, errors); 84 85 return true; 86 } 87 88 static int axiado_mbox_send_data(struct mbox_chan *chan, void *data) 89 { 90 struct axiado_mbox *mb = dev_get_drvdata(chan->mbox->dev); 91 struct axiado_channel_data *priv = chan->con_priv; 92 unsigned int idx = priv->channel_num; 93 u8 tail[sizeof(u32)] = { 0 }; 94 const u8 *buf = data; 95 unsigned int tail_len; 96 unsigned int offset; 97 u32 msg_len; 98 99 if (!data) 100 return -EINVAL; 101 102 /* 103 * The Axiado mailbox message ABI stores the total message length, 104 * including this length word, as a little-endian byte count in the 105 * first word of every message. 106 */ 107 msg_len = get_unaligned_le32(data); 108 if (msg_len < sizeof(u32) || msg_len > mb->drv_data->msg_size) 109 return -EINVAL; 110 111 /* Only touch the hardware after validating the message. */ 112 axiado_mbox_clear_fifo_errors(priv); 113 114 if (!(readl(priv->csr_reg) & AXIADO_MBOX_CSR_EMPTY)) { 115 dev_warn_ratelimited(mb->mbox.dev, "Channel %u is busy\n", idx); 116 return -EBUSY; 117 } 118 119 for (offset = 0; offset + sizeof(u32) <= msg_len; 120 offset += sizeof(u32)) 121 writel(get_unaligned_le32(buf + offset), priv->mbox_reg); 122 123 tail_len = msg_len - offset; 124 if (tail_len) { 125 memcpy(tail, buf + offset, tail_len); 126 writel(get_unaligned_le32(tail), priv->mbox_reg); 127 } 128 129 dev_dbg(mb->mbox.dev, "%s: Ch-%u sent\n", __func__, idx); 130 131 return 0; 132 } 133 134 static irqreturn_t axiado_rx_thread(int irq, void *dev_id) 135 { 136 struct axiado_channel_data *priv = dev_id; 137 struct mbox_chan *chan = priv->chan; 138 struct axiado_mbox *mb = dev_get_drvdata(chan->mbox->dev); 139 u8 *buf = priv->rx_buffer; 140 unsigned int num_words; 141 unsigned int remaining; 142 unsigned int i; 143 u32 msg_len; 144 u32 word; 145 u32 csr; 146 int ret; 147 148 /* 149 * Clear and log/count any pending errors, but don't discard data 150 * on their account alone: a rejected overflow write doesn't 151 * corrupt what was already safely queued ahead of it, so let the 152 * length-based read below decide whether what's here is usable. 153 */ 154 axiado_mbox_clear_fifo_errors(priv); 155 156 csr = readl(priv->csr_reg); 157 if (csr & AXIADO_MBOX_CSR_EMPTY) 158 return IRQ_NONE; 159 160 /* 161 * The first word contains the total message length in bytes, 162 * including the length word itself. 163 */ 164 word = readl(priv->mbox_reg); 165 msg_len = word; 166 put_unaligned_le32(word, buf); 167 168 if (msg_len < sizeof(u32) || msg_len > mb->drv_data->msg_size) 169 goto invalid_message; 170 171 num_words = DIV_ROUND_UP(msg_len, sizeof(u32)); 172 remaining = num_words - 1; 173 174 /* 175 * The not-empty interrupt may occur as soon as the first DW enters 176 * the FIFO. Wait until all remaining DWs of this message arrive. 177 */ 178 if (remaining) { 179 ret = readl_poll_timeout(priv->csr_reg, csr, 180 (csr & AXIADO_MBOX_CSR_ERRORS) || 181 FIELD_GET(AXIADO_MBOX_CSR_LEVEL, csr) >= 182 remaining, 183 AXIADO_MBOX_RX_POLL_US, 184 AXIADO_MBOX_RX_TIMEOUT_US); 185 if (ret) 186 goto incomplete_message; 187 188 axiado_mbox_clear_fifo_errors(priv); 189 } 190 191 for (i = 1; i < num_words; i++) { 192 word = readl(priv->mbox_reg); 193 put_unaligned_le32(word, buf + i * sizeof(u32)); 194 } 195 196 axiado_mbox_clear_fifo_errors(priv); 197 198 if (READ_ONCE(priv->active)) 199 mbox_chan_received_data(chan, priv->rx_buffer); 200 201 return IRQ_HANDLED; 202 203 incomplete_message: 204 dev_warn_ratelimited(chan->mbox->dev, 205 "Channel %u received an incomplete message\n", 206 priv->channel_num); 207 208 invalid_message: 209 writel(AXIADO_MBOX_CSR_FLUSH, priv->csr_reg); 210 211 return IRQ_HANDLED; 212 } 213 214 static int axiado_mbox_startup(struct mbox_chan *chan) 215 { 216 struct axiado_channel_data *priv = chan->con_priv; 217 218 /* 219 * Only flush on a genuine error. A blind flush here would discard 220 * a message the peer legitimately sent before this side started 221 * up (e.g. during normal boot sequencing), which is not corrupt 222 * and does not need resyncing. 223 */ 224 if (axiado_mbox_clear_fifo_errors(priv)) 225 writel(AXIADO_MBOX_CSR_FLUSH, priv->csr_reg); 226 227 WRITE_ONCE(priv->active, true); 228 229 if (priv->channel_num >= AXIADO_MBOX_TX_CHANS) 230 enable_irq(priv->irq); 231 232 return 0; 233 } 234 235 static void axiado_mbox_shutdown(struct mbox_chan *chan) 236 { 237 struct axiado_channel_data *priv = chan->con_priv; 238 239 WRITE_ONCE(priv->active, false); 240 241 if (priv->channel_num >= AXIADO_MBOX_TX_CHANS) 242 disable_irq(priv->irq); 243 244 if (axiado_mbox_clear_fifo_errors(priv)) 245 writel(AXIADO_MBOX_CSR_FLUSH, priv->csr_reg); 246 } 247 248 static bool axiado_mbox_last_tx_done(struct mbox_chan *chan) 249 { 250 struct axiado_channel_data *priv = chan->con_priv; 251 252 return !!(readl(priv->csr_reg) & AXIADO_MBOX_CSR_EMPTY); 253 } 254 255 static const struct mbox_chan_ops axiado_mbox_chan_ops = { 256 .send_data = axiado_mbox_send_data, 257 .startup = axiado_mbox_startup, 258 .shutdown = axiado_mbox_shutdown, 259 .last_tx_done = axiado_mbox_last_tx_done, 260 }; 261 262 static void axiado_mbox_debugfs_remove(void *dentry) 263 { 264 debugfs_remove_recursive(dentry); 265 } 266 267 static int axiado_mbox_probe(struct platform_device *pdev) 268 { 269 const struct axiado_mbox_data *drv_data; 270 struct axiado_channel_data *ch_data; 271 struct device *dev = &pdev->dev; 272 struct axiado_mbox *mb; 273 unsigned int irq_idx = 0; 274 unsigned int rx_chan; 275 unsigned int i; 276 int ret; 277 278 drv_data = device_get_match_data(dev); 279 if (!drv_data) 280 return -ENODEV; 281 282 mb = devm_kzalloc(dev, sizeof(*mb), GFP_KERNEL); 283 if (!mb) 284 return -ENOMEM; 285 286 mb->mbox.dev = dev; 287 mb->mbox.num_chans = drv_data->num_chans; 288 289 mb->mbox.chans = devm_kcalloc(&pdev->dev, 290 drv_data->num_chans, 291 sizeof(*mb->mbox.chans), 292 GFP_KERNEL); 293 if (!mb->mbox.chans) 294 return -ENOMEM; 295 296 mb->tx_base = devm_platform_ioremap_resource_byname(pdev, "tx"); 297 if (IS_ERR(mb->tx_base)) 298 return PTR_ERR(mb->tx_base); 299 300 mb->rx_base = devm_platform_ioremap_resource_byname(pdev, "rx"); 301 if (IS_ERR(mb->rx_base)) 302 return PTR_ERR(mb->rx_base); 303 304 ch_data = devm_kcalloc(&pdev->dev, 305 drv_data->num_chans, 306 sizeof(*ch_data), 307 GFP_KERNEL); 308 if (!ch_data) 309 return -ENOMEM; 310 311 mb->debugfs_dir = debugfs_create_dir(dev_name(dev), NULL); 312 ret = devm_add_action_or_reset(dev, axiado_mbox_debugfs_remove, 313 mb->debugfs_dir); 314 if (ret) 315 return ret; 316 317 for (i = 0; i < drv_data->num_chans; i++) { 318 char name[16]; 319 320 ch_data[i].channel_num = i; 321 ch_data[i].chan = &mb->mbox.chans[i]; 322 323 mb->mbox.chans[i].con_priv = &ch_data[i]; 324 325 snprintf(name, sizeof(name), "chan%u-errors", i); 326 debugfs_create_atomic_t(name, 0444, mb->debugfs_dir, 327 &ch_data[i].fifo_errors); 328 329 if (i < AXIADO_MBOX_TX_CHANS) { 330 ch_data[i].mbox_reg = mb->tx_base + (i * AXIADO_MBOX_CHAN_STRIDE); 331 ch_data[i].csr_reg = mb->tx_base + AXIADO_MBOX_TX_REG_STRIDE + 332 (i * AXIADO_MBOX_CHAN_STRIDE); 333 ch_data[i].irq = -1; 334 continue; 335 } 336 337 ch_data[i].rx_buffer = devm_kzalloc(dev, drv_data->msg_size, 338 GFP_KERNEL); 339 if (!ch_data[i].rx_buffer) 340 return -ENOMEM; 341 342 rx_chan = i - AXIADO_MBOX_TX_CHANS; 343 ch_data[i].mbox_reg = mb->rx_base + 344 (rx_chan * AXIADO_MBOX_CHAN_STRIDE); 345 ch_data[i].csr_reg = mb->rx_base + AXIADO_MBOX_RX_REG_STRIDE + 346 (rx_chan * AXIADO_MBOX_CHAN_STRIDE); 347 ch_data[i].irq = platform_get_irq(pdev, irq_idx++); 348 if (ch_data[i].irq < 0) 349 return dev_err_probe(dev, ch_data[i].irq, 350 "Failed to get IRQ for channel %u\n", i); 351 352 ret = devm_request_threaded_irq(dev, ch_data[i].irq, NULL, 353 axiado_rx_thread, 354 IRQF_ONESHOT | IRQF_NO_AUTOEN, 355 dev_name(dev), &ch_data[i]); 356 if (ret) 357 return dev_err_probe(dev, ret, 358 "Failed to request IRQ for channel %u\n", i); 359 360 dev_dbg(dev, "RX chan %u -> irq %d\n", i, ch_data[i].irq); 361 } 362 363 platform_set_drvdata(pdev, mb); 364 mb->drv_data = drv_data; 365 mb->mbox.ops = &axiado_mbox_chan_ops; 366 mb->mbox.txdone_irq = false; 367 mb->mbox.txdone_poll = true; 368 mb->mbox.txpoll_period = 5; 369 370 return devm_mbox_controller_register(dev, &mb->mbox); 371 } 372 373 static const struct axiado_mbox_data axiado_drv_data = { 374 .num_chans = AXIADO_MBOX_TX_CHANS + AXIADO_MBOX_RX_CHANS, 375 .msg_size = 256, 376 }; 377 378 static const struct of_device_id axiado_mbox_of_match[] = { 379 { .compatible = "axiado,ax3005-mailbox", .data = &axiado_drv_data }, 380 { } 381 }; 382 MODULE_DEVICE_TABLE(of, axiado_mbox_of_match); 383 384 static struct platform_driver axiado_mbox_driver = { 385 .driver = { 386 .name = "axiado-mailbox", 387 .of_match_table = axiado_mbox_of_match, 388 }, 389 .probe = axiado_mbox_probe, 390 }; 391 module_platform_driver(axiado_mbox_driver); 392 393 MODULE_AUTHOR("Axiado Corporation"); 394 MODULE_DESCRIPTION("Axiado Mailbox driver"); 395 MODULE_LICENSE("GPL"); 396