blob: a4ab3f28ece66ef6e530553c7f36dcf83a2ca408 [file] [log] [blame]
From 6a2e0b505985a089d209920251a95201abacfa31 Mon Sep 17 00:00:00 2001
From: "Kao.Benson" <kao.benson@inventec.corp-partner.google.com>
Date: Mon, 5 Aug 2024 17:22:18 +0800
Subject: [PATCH] AMD apml through i3c interface process
AMD recommends applying a provided patch. Through studying this patch,
we have achieved the ability to retry in case of NACK by modifying the
software in i3c driver.
Reference patch:
https://github.com/AMDESE/OpenBMC/blob/master/meta-amd/meta-common/recipes-kernel/linux/linux-aspeed/0002-drivers-i3c-Modify-I3C-driver.patch#L3008
Tested:
Before modify, It saw the error by using i3c tool
~# i3ctransfer -d i3c-0-22400000002 -w 0x73 -r 0x0a
Error: transfer failed: Input/output error
~# i3ctransfer -d i3c-0-22400000002 -w 0x73 -r 0x0a
Success on message 0
Success on message 1
received data:
0x09
0x00
0x10
0x00
0x00
0x00
0x41
0x75
0x74
0x6
[After we modify]
~# i3ctransfer -d i3c-0-22400000002 -w
0x73,0x08,0x08,0x91,0x00,0x00,0x00,0x00,0x00,0x00
Success on message 0
~# i3ctransfer -d i3c-0-22400000002 -w 0x02 -r 1
Success on message 0
Success on message 1
received data:
0x80
~# i3ctransfer -d i3c-0-22400000002 -w 0x73 -r 0x0a
Success on message 0
Success on message 1
received data:
0x09
0x00
0x10
0x00
0x00
0x00
0x41
0x75
0x74
0x68
~# i3ctransfer -d i3c-0-22400000002 -w 0x73 -r 0x0a
Success on message 0
Success on message 1
received data:
0x09
0x00
0x10
0x00
0x00
0x00
0x41
0x75
0x74
0x68
Signed-off-by: Kao.Benson <kao.benson@inventec.corp-partner.google.com>
---
drivers/i3c/master/svc-i3c-master.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index 6fdaa8b9de5d..ec9d4be0d8dc 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -196,6 +196,7 @@
#define SVC_I3C_MAX_I2CBAUD 15
#define I3C_SCL_PP_PERIOD_NS_MIN 40
#define I3C_SCL_OD_LOW_PERIOD_NS_MIN 200
+#define I3C_RETRY 3
/* DMA definitions */
#define MAX_DMA_COUNT 1024
@@ -1449,11 +1450,12 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
bool use_dma)
{
u32 reg, rdterm = *read_len, mstatus;
- int ret, i, count, space;
+ int ret, i, count, space, retry_times = 0;
unsigned long flags;
unsigned long start;
u32 ibiresp;
+retry_count:
if (rdterm > SVC_I3C_MAX_RDTERM)
rdterm = SVC_I3C_MAX_RDTERM;
@@ -1566,8 +1568,13 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
reg = readl(master->regs + SVC_I3C_MSTATUS);
if (SVC_I3C_MSTATUS_NACKED(reg)) {
dev_dbg(master->dev, "addr 0x%x NACK\n", addr);
- ret = -EIO;
- goto emit_stop;
+ if (retry_times >= I3C_RETRY)
+ {
+ ret = -EIO;
+ goto emit_stop;
+ }
+ retry_times++;
+ goto retry_count;
}
if (use_dma)
--
2.34.1