| 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 | |