From ef7f98b9e099e09464ee4e116bf92ced0ceb7ca7 Mon Sep 17 00:00:00 2001 From: Yao Jie Date: Wed, 7 Feb 2024 19:22:55 +0800 Subject: [PATCH] mailbox: t5m add aocpu alive check mechanism [1/1] PD#SWPL-155395 Problem: When modules send mailbox message to aocpu, sometimes aocpu can not response because of stuck or interrupt signal lost, at this time driver modules need to know whether aocpu is alive or not, this is helpful to debug. Solution: Add aocpu alive check mechanism, when aocpu did not response, system will check and print aocpu status. Verify: T5M-AY309 Change-Id: Idd1c47fd99505f3a159c86390c28303f5a5b60e9 Signed-off-by: Yao Jie --- arch/arm64/boot/dts/amlogic/mesont5m.dtsi | 2 ++ drivers/mailbox/meson_mbox_fifo.c | 20 +++++++++++ include/dt-bindings/mailbox/t5m-mbox.h | 3 ++ include/linux/amlogic/aml_mbox.h | 42 ++++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletion(-) 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);