1 // SPDX-License-Identifier: GPL-2.0+
3 * rWTM BIU Mailbox driver for Armada 37xx
5 * Author: Marek Behun <marek.behun@nic.cz>
8 #include <linux/device.h>
9 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <linux/mailbox_controller.h>
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/armada-37xx-rwtm-mailbox.h>
18 #define DRIVER_NAME "armada-37xx-rwtm-mailbox"
20 /* relative to rWTM BIU Mailbox Registers */
21 #define RWTM_MBOX_PARAM(i) (0x0 + ((i) << 2))
22 #define RWTM_MBOX_COMMAND 0x40
23 #define RWTM_MBOX_RETURN_STATUS 0x80
24 #define RWTM_MBOX_STATUS(i) (0x84 + ((i) << 2))
25 #define RWTM_MBOX_FIFO_STATUS 0xc4
26 #define FIFO_STS_RDY 0x100
27 #define FIFO_STS_CNTR_MASK 0x7
28 #define FIFO_STS_CNTR_MAX 4
30 #define RWTM_HOST_INT_RESET 0xc8
31 #define RWTM_HOST_INT_MASK 0xcc
32 #define SP_CMD_COMPLETE BIT(0)
33 #define SP_CMD_QUEUE_FULL_ACCESS BIT(17)
34 #define SP_CMD_QUEUE_FULL BIT(18)
38 struct mbox_controller controller
;
43 static void a37xx_mbox_receive(struct mbox_chan
*chan
)
45 struct a37xx_mbox
*mbox
= chan
->con_priv
;
46 struct armada_37xx_rwtm_rx_msg rx_msg
;
49 rx_msg
.retval
= readl(mbox
->base
+ RWTM_MBOX_RETURN_STATUS
);
50 for (i
= 0; i
< 16; ++i
)
51 rx_msg
.status
[i
] = readl(mbox
->base
+ RWTM_MBOX_STATUS(i
));
53 mbox_chan_received_data(chan
, &rx_msg
);
56 static irqreturn_t
a37xx_mbox_irq_handler(int irq
, void *data
)
58 struct mbox_chan
*chan
= data
;
59 struct a37xx_mbox
*mbox
= chan
->con_priv
;
62 reg
= readl(mbox
->base
+ RWTM_HOST_INT_RESET
);
64 if (reg
& SP_CMD_COMPLETE
)
65 a37xx_mbox_receive(chan
);
67 if (reg
& (SP_CMD_QUEUE_FULL_ACCESS
| SP_CMD_QUEUE_FULL
))
68 dev_err(mbox
->dev
, "Secure processor command queue full\n");
70 writel(reg
, mbox
->base
+ RWTM_HOST_INT_RESET
);
72 mbox_chan_txdone(chan
, 0);
74 return reg
? IRQ_HANDLED
: IRQ_NONE
;
77 static int a37xx_mbox_send_data(struct mbox_chan
*chan
, void *data
)
79 struct a37xx_mbox
*mbox
= chan
->con_priv
;
80 struct armada_37xx_rwtm_tx_msg
*msg
= data
;
87 reg
= readl(mbox
->base
+ RWTM_MBOX_FIFO_STATUS
);
88 if (!(reg
& FIFO_STS_RDY
))
89 dev_warn(mbox
->dev
, "Secure processor not ready\n");
91 if ((reg
& FIFO_STS_CNTR_MASK
) >= FIFO_STS_CNTR_MAX
) {
92 dev_err(mbox
->dev
, "Secure processor command queue full\n");
96 for (i
= 0; i
< 16; ++i
)
97 writel(msg
->args
[i
], mbox
->base
+ RWTM_MBOX_PARAM(i
));
98 writel(msg
->command
, mbox
->base
+ RWTM_MBOX_COMMAND
);
103 static int a37xx_mbox_startup(struct mbox_chan
*chan
)
105 struct a37xx_mbox
*mbox
= chan
->con_priv
;
109 ret
= devm_request_irq(mbox
->dev
, mbox
->irq
, a37xx_mbox_irq_handler
, 0,
112 dev_err(mbox
->dev
, "Cannot request irq\n");
116 /* enable IRQ generation */
117 reg
= readl(mbox
->base
+ RWTM_HOST_INT_MASK
);
118 reg
&= ~(SP_CMD_COMPLETE
| SP_CMD_QUEUE_FULL_ACCESS
| SP_CMD_QUEUE_FULL
);
119 writel(reg
, mbox
->base
+ RWTM_HOST_INT_MASK
);
124 static void a37xx_mbox_shutdown(struct mbox_chan
*chan
)
127 struct a37xx_mbox
*mbox
= chan
->con_priv
;
129 /* disable interrupt generation */
130 reg
= readl(mbox
->base
+ RWTM_HOST_INT_MASK
);
131 reg
|= SP_CMD_COMPLETE
| SP_CMD_QUEUE_FULL_ACCESS
| SP_CMD_QUEUE_FULL
;
132 writel(reg
, mbox
->base
+ RWTM_HOST_INT_MASK
);
134 devm_free_irq(mbox
->dev
, mbox
->irq
, chan
);
137 static const struct mbox_chan_ops a37xx_mbox_ops
= {
138 .send_data
= a37xx_mbox_send_data
,
139 .startup
= a37xx_mbox_startup
,
140 .shutdown
= a37xx_mbox_shutdown
,
143 static int armada_37xx_mbox_probe(struct platform_device
*pdev
)
145 struct a37xx_mbox
*mbox
;
146 struct resource
*regs
;
147 struct mbox_chan
*chans
;
150 mbox
= devm_kzalloc(&pdev
->dev
, sizeof(*mbox
), GFP_KERNEL
);
154 /* Allocated one channel */
155 chans
= devm_kzalloc(&pdev
->dev
, sizeof(*chans
), GFP_KERNEL
);
159 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
161 mbox
->base
= devm_ioremap_resource(&pdev
->dev
, regs
);
162 if (IS_ERR(mbox
->base
)) {
163 dev_err(&pdev
->dev
, "ioremap failed\n");
164 return PTR_ERR(mbox
->base
);
167 mbox
->irq
= platform_get_irq(pdev
, 0);
169 dev_err(&pdev
->dev
, "Cannot get irq\n");
173 mbox
->dev
= &pdev
->dev
;
175 /* Hardware supports only one channel. */
176 chans
[0].con_priv
= mbox
;
177 mbox
->controller
.dev
= mbox
->dev
;
178 mbox
->controller
.num_chans
= 1;
179 mbox
->controller
.chans
= chans
;
180 mbox
->controller
.ops
= &a37xx_mbox_ops
;
181 mbox
->controller
.txdone_irq
= true;
183 ret
= devm_mbox_controller_register(mbox
->dev
, &mbox
->controller
);
185 dev_err(&pdev
->dev
, "Could not register mailbox controller\n");
189 platform_set_drvdata(pdev
, mbox
);
194 static const struct of_device_id armada_37xx_mbox_match
[] = {
195 { .compatible
= "marvell,armada-3700-rwtm-mailbox" },
199 MODULE_DEVICE_TABLE(of
, armada_37xx_mbox_match
);
201 static struct platform_driver armada_37xx_mbox_driver
= {
202 .probe
= armada_37xx_mbox_probe
,
205 .of_match_table
= armada_37xx_mbox_match
,
209 module_platform_driver(armada_37xx_mbox_driver
);
211 MODULE_LICENSE("GPL v2");
212 MODULE_DESCRIPTION("rWTM BIU Mailbox driver for Armada 37xx");
213 MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");