diff --git a/arch/arm64/boot/dts/amlogic/mesont5m.dtsi b/arch/arm64/boot/dts/amlogic/mesont5m.dtsi index 49b984a85..3ff317e3a 100644 --- a/arch/arm64/boot/dts/amlogic/mesont5m.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesont5m.dtsi @@ -347,6 +347,8 @@ mbox-nums = ; mboxids = , ; + aocpu_sts_mboxid = ; + ree2aocpu_mboxid = ; #mbox-cells = <1>; mbox-wr-same; }; diff --git a/drivers/mailbox/meson_mbox_fifo.c b/drivers/mailbox/meson_mbox_fifo.c index 8ef3b1f12..04cbbfa4a 100644 --- a/drivers/mailbox/meson_mbox_fifo.c +++ b/drivers/mailbox/meson_mbox_fifo.c @@ -363,6 +363,9 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv u32 irq_nums = 0; u32 mbox_nums = 0; u32 mboxid = 0; + u32 spt_ao_alive_det = 0; + u32 ao_sts_mboxid = 0; + u32 ree2ao_mboxid = 0; int idx = 0; int err = 0; @@ -422,6 +425,20 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv aml_chan = devm_kzalloc(dev, sizeof(*aml_chan) * mbox_nums, GFP_KERNEL); if (IS_ERR(aml_chan)) return PTR_ERR(aml_chan); + + err = of_property_read_u32(dev->of_node, + "aocpu_sts_mboxid", &ao_sts_mboxid); + if (err) { + dev_err(dev, "Do not support aocpu alive detection %d\n", err); + } else { + err = of_property_read_u32(dev->of_node, + "ree2aocpu_mboxid", &ree2ao_mboxid); + if (err) + dev_err(dev, "failed to get ree2aocpu mbox id, %d\n", err); + else + spt_ao_alive_det = 1; + } + for (idx = 0; idx < mbox_nums; idx++) { err = of_property_read_u32_index(dev->of_node, "mboxids", idx, &mboxid); @@ -436,6 +453,9 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv aml_chan[idx].mbox_fsts_addr = mbox_fsts_base + CTL_OFFSET(mboxid); aml_chan[idx].mbox_irqsts_addr = mbox_irq_base + IRQ_STS_OFFSET(irqctlr); aml_chan[idx].mbox_irqclr_addr = mbox_irq_base + IRQ_CLR_OFFSET(irqclr); + if (spt_ao_alive_det && mboxid == ree2ao_mboxid) + aml_chan[idx].aocpu_tick_cnt_addr = mbox_rd_base + + PAYLOAD_OFFSET(ao_sts_mboxid); mutex_init(&aml_chan[idx].mutex); aml_chan[idx].tx_complete = NULL; } diff --git a/include/dt-bindings/mailbox/t5m-mbox.h b/include/dt-bindings/mailbox/t5m-mbox.h index 3bda8164f..5782059ba 100644 --- a/include/dt-bindings/mailbox/t5m-mbox.h +++ b/include/dt-bindings/mailbox/t5m-mbox.h @@ -29,4 +29,7 @@ #define T5M_MBOX_REE2AO 3 #define T5M_MBOX_NUMS 2 +// AOCPU STATUS MBOX CHANNEL ID +#define T5M_MBOX_AO2TEE 4 + #endif /* __T5M_MBOX_H__ */ diff --git a/include/linux/amlogic/aml_mbox.h b/include/linux/amlogic/aml_mbox.h index 8dcfe84d3..007f18527 100644 --- a/include/linux/amlogic/aml_mbox.h +++ b/include/linux/amlogic/aml_mbox.h @@ -7,6 +7,8 @@ #define _AML_MBOX_H_ #include #include +#include +#include #include #include #include "aml_mbox_cmd.h" @@ -79,6 +81,7 @@ struct aml_mbox_chan { void __iomem *mbox_fset_addr; void __iomem *mbox_fclr_addr; void __iomem *mbox_fsts_addr; + void __iomem *aocpu_tick_cnt_addr; struct mutex mutex; /* for aml mbox chan mutex */ struct mbox_controller *mbox; void *tx_complete; @@ -141,6 +144,33 @@ static inline struct mbox_chan *aml_mbox_request_channel_byname(struct device *d return mbox_chan; } +/* + * Check if the aocpu is alive + * @sts_addr: aocpu tick count read address + * return - 0: aocpu is alive + * - 1: aocpu is not alive + */ +static inline int check_aocpu_status(void __iomem *sts_addr) +{ + u32 aocpu_tick_count_1; + u32 aocpu_tick_count_2; + int ret; + + aocpu_tick_count_1 = readl(sts_addr); + pr_info("%s: aocpu_tick_count_1 = 0x%x\n", __func__, + aocpu_tick_count_1); + /* Sleep for 50 msec to let tick count update */ + msleep(50); + aocpu_tick_count_2 = readl(sts_addr); + pr_info("%s: aocpu_tick_count_2 = 0x%x\n", __func__, + aocpu_tick_count_2); + if (aocpu_tick_count_1 != aocpu_tick_count_2) + ret = 0; + else + ret = 1; + return ret; +} + /** * aml_mbox_transfer_data - A way for transfer mbox data * @mbox_chan: Mbox channel, this requested by mbox consumer driver @@ -157,7 +187,9 @@ static inline int aml_mbox_transfer_data(struct mbox_chan *mbox_chan, int cmd, { struct aml_mbox_data aml_data; struct aml_mbox_chan *aml_chan; + void __iomem *sts_addr; int ret; + int chk_ret; if (IS_ERR_OR_NULL(mbox_chan)) { pr_err("mbox chan is NULL\n"); @@ -176,7 +208,15 @@ static inline int aml_mbox_transfer_data(struct mbox_chan *mbox_chan, int cmd, mutex_unlock(&aml_chan->mutex); if (ret < 0) { dev_err(mbox_chan->cl->dev, "Fail to send mbox data %d\n", ret); - return ret; + sts_addr = aml_chan->aocpu_tick_cnt_addr; + if (sts_addr) { + chk_ret = check_aocpu_status(sts_addr); + if (!chk_ret) + pr_info("Info: aocpu is alive\n"); + else + pr_info("Info: aocpu is not alive\n"); + return ret; + } } if (sync == MBOX_TSYNC) ret = wait_for_completion_killable(&aml_data.complete);