Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mailbox: imx: Fix TXDB_V2 sending

i.MX95 features several processing domains, Cortex-M7, Cortex-A55
secure, Cortex-A55 non-secure. Each domain could communicate with
SCMI firmware with a dedicated MU. But the current NXP SCMI firmware
is not a RTOS, all processing logic codes are in interrupt context.
So if high priority Cortex-M7 is communicating with SCMI firmware and
requires a bit more time to handle the SCMI call, Linux MU TXDB_V2
will be timeout with high possiblity in 1000us(the current value in
imx-mailbox.c). Per NXP SCMI firmware design, if timeout, there is
no recover logic, so SCMI agents should never timeout and always
wait until the check condition met.

Based on the upper reason, enlarge the timeout value to 10ms which
is less chance to timeout, and retry if timeout really happends.

Fixes: 5bfe4067d350 ("mailbox: imx: support channel type tx doorbell v2")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>

authored by

Peng Fan and committed by
Jassi Brar
f5cb07ec d635ba42

+15 -6
+15 -6
drivers/mailbox/imx-mailbox.c
··· 226 226 { 227 227 u32 *arg = data; 228 228 u32 val; 229 - int ret; 229 + int ret, count; 230 230 231 231 switch (cp->type) { 232 232 case IMX_MU_TYPE_TX: ··· 240 240 case IMX_MU_TYPE_TXDB_V2: 241 241 imx_mu_write(priv, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 242 242 priv->dcfg->xCR[IMX_MU_GCR]); 243 - ret = readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val, 244 - !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)), 245 - 0, 1000); 246 - if (ret) 247 - dev_warn_ratelimited(priv->dev, "channel type: %d failure\n", cp->type); 243 + ret = -ETIMEDOUT; 244 + count = 0; 245 + while (ret && (count < 10)) { 246 + ret = 247 + readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val, 248 + !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)), 249 + 0, 10000); 250 + 251 + if (ret) { 252 + dev_warn_ratelimited(priv->dev, 253 + "channel type: %d timeout, %d times, retry\n", 254 + cp->type, ++count); 255 + } 256 + } 248 257 break; 249 258 default: 250 259 dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);