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 <jie.yao@amlogic.com>
This commit is contained in:
Yao Jie
2024-02-07 19:22:55 +08:00
committed by Luan Yuan
parent e595c81e0e
commit ef7f98b9e0
4 changed files with 66 additions and 1 deletions
@@ -347,6 +347,8 @@
mbox-nums = <T5M_MBOX_NUMS>;
mboxids = <T5M_MBOX_AO2REE>,
<T5M_MBOX_REE2AO>;
aocpu_sts_mboxid = <T5M_MBOX_AO2TEE>;
ree2aocpu_mboxid = <T5M_MBOX_REE2AO>;
#mbox-cells = <1>;
mbox-wr-same;
};
+20
View File
@@ -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;
}
+3
View File
@@ -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__ */
+41 -1
View File
@@ -7,6 +7,8 @@
#define _AML_MBOX_H_
#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mailbox_client.h>
#include <linux/mailbox_controller.h>
#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);