* [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic
@ 2024-07-02 22:31 Frank Li
2024-07-08 6:53 ` Miquel Raynal
2024-07-15 21:48 ` Alexandre Belloni
0 siblings, 2 replies; 3+ messages in thread
From: Frank Li @ 2024-07-02 22:31 UTC (permalink / raw)
To: Miquel Raynal, Conor Culhane, Alexandre Belloni,
moderated list:SILVACO I3C DUAL-ROLE MASTER, open list
Cc: imx
The REQUEST_PROC_DAA command behaves differently from other commands.
Sometimes the hardware can auto emit STOP, but in other conditions, it
cannot.
Improves the code logic to better handle these situations.
Hardware can auto emit STOP only when the following conditions are met:
- The previous I3C device correctly returns a PID and ACKs an I3C address.
- A NACK is received when emitting 7E to try to get the next I3C device's
PID.
In all other cases, a manual STOP emission is needed.
The code is changed to emit STOP when break the while loop and 'return 0'
only when the hardware can auto emit STOP.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/i3c/master/svc-i3c-master.c | 61 ++++++++++++++++++++---------
1 file changed, 43 insertions(+), 18 deletions(-)
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index f0362509319e0..15fa56383bdc9 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -790,7 +790,20 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
int ret, i;
while (true) {
- /* Enter/proceed with DAA */
+ /* SVC_I3C_MCTRL_REQUEST_PROC_DAA have two mode, ENTER DAA or PROCESS DAA.
+ *
+ * ENTER DAA:
+ * 1 will issue START, 7E, ENTDAA, and then emits 7E/R to process first target.
+ * 2 Stops just before the new Dynamic Address (DA) is to be emitted.
+ *
+ * PROCESS DAA:
+ * 1 The DA is written using MWDATAB or ADDR bits 6:0.
+ * 2 ProcessDAA is requested again to write the new address, and then starts the
+ * next (START, 7E, ENTDAA) unless marked to STOP; an MSTATUS indicating NACK
+ * means DA was not accepted (e.g. parity error). If PROCESSDAA is NACKed on the
+ * 7E/R, which means no more Slaves need a DA, then a COMPLETE will be signaled
+ * (along with DONE), and a STOP issued automatically.
+ */
writel(SVC_I3C_MCTRL_REQUEST_PROC_DAA |
SVC_I3C_MCTRL_TYPE_I3C |
SVC_I3C_MCTRL_IBIRESP_NACK |
@@ -807,7 +820,7 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
SVC_I3C_MSTATUS_MCTRLDONE(reg),
1, 1000);
if (ret)
- return ret;
+ break;
if (SVC_I3C_MSTATUS_RXPEND(reg)) {
u8 data[6];
@@ -819,7 +832,7 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
*/
ret = svc_i3c_master_readb(master, data, 6);
if (ret)
- return ret;
+ break;
for (i = 0; i < 6; i++)
prov_id[dev_nb] |= (u64)(data[i]) << (8 * (5 - i));
@@ -827,7 +840,7 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
/* We do not care about the BCR and DCR yet */
ret = svc_i3c_master_readb(master, data, 2);
if (ret)
- return ret;
+ break;
} else if (SVC_I3C_MSTATUS_MCTRLDONE(reg)) {
if (SVC_I3C_MSTATUS_STATE_IDLE(reg) &&
SVC_I3C_MSTATUS_COMPLETE(reg)) {
@@ -835,12 +848,23 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
* All devices received and acked they dynamic
* address, this is the natural end of the DAA
* procedure.
+ *
+ * Hardware will auto emit STOP at this case.
*/
- break;
+ *count = dev_nb;
+ return 0;
+
} else if (SVC_I3C_MSTATUS_NACKED(reg)) {
/* No I3C devices attached */
- if (dev_nb == 0)
+ if (dev_nb == 0) {
+ /*
+ * Hardware can't treat first NACK for ENTAA as normal
+ * COMPLETE. So need manual emit STOP.
+ */
+ ret = 0;
+ *count = 0;
break;
+ }
/*
* A slave device nacked the address, this is
@@ -849,8 +873,10 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
* answer again immediately and shall ack the
* address this time.
*/
- if (prov_id[dev_nb] == nacking_prov_id)
- return -EIO;
+ if (prov_id[dev_nb] == nacking_prov_id) {
+ ret = EIO;
+ break;
+ }
dev_nb--;
nacking_prov_id = prov_id[dev_nb];
@@ -858,7 +884,7 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
continue;
} else {
- return -EIO;
+ break;
}
}
@@ -870,12 +896,12 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
SVC_I3C_MSTATUS_BETWEEN(reg),
0, 1000);
if (ret)
- return ret;
+ break;
/* Give the slave device a suitable dynamic address */
ret = i3c_master_get_free_addr(&master->base, last_addr + 1);
if (ret < 0)
- return ret;
+ break;
addrs[dev_nb] = ret;
dev_dbg(master->dev, "DAA: device %d assigned to 0x%02x\n",
@@ -885,9 +911,9 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
last_addr = addrs[dev_nb++];
}
- *count = dev_nb;
-
- return 0;
+ /* Need manual issue STOP except for Complete condition */
+ svc_i3c_master_emit_stop(master);
+ return ret;
}
static int svc_i3c_update_ibirules(struct svc_i3c_master *master)
@@ -961,11 +987,10 @@ static int svc_i3c_master_do_daa(struct i3c_master_controller *m)
spin_lock_irqsave(&master->xferqueue.lock, flags);
ret = svc_i3c_master_do_daa_locked(master, addrs, &dev_nb);
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
- if (ret) {
- svc_i3c_master_emit_stop(master);
- svc_i3c_master_clear_merrwarn(master);
+
+ svc_i3c_master_clear_merrwarn(master);
+ if (ret)
goto rpm_out;
- }
/* Register all devices who participated to the core */
for (i = 0; i < dev_nb; i++) {
--
2.34.1
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic
2024-07-02 22:31 [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic Frank Li
@ 2024-07-08 6:53 ` Miquel Raynal
2024-07-15 21:48 ` Alexandre Belloni
1 sibling, 0 replies; 3+ messages in thread
From: Miquel Raynal @ 2024-07-08 6:53 UTC (permalink / raw)
To: Frank Li
Cc: Conor Culhane, Alexandre Belloni,
moderated list:SILVACO I3C DUAL-ROLE MASTER, open list, imx
Hi Frank,
Frank.Li@nxp.com wrote on Tue, 2 Jul 2024 18:31:07 -0400:
> The REQUEST_PROC_DAA command behaves differently from other commands.
> Sometimes the hardware can auto emit STOP, but in other conditions, it
> cannot.
>
> Improves the code logic to better handle these situations.
>
> Hardware can auto emit STOP only when the following conditions are met:
> - The previous I3C device correctly returns a PID and ACKs an I3C address.
> - A NACK is received when emitting 7E to try to get the next I3C device's
> PID.
>
> In all other cases, a manual STOP emission is needed.
>
> The code is changed to emit STOP when break the while loop and 'return 0'
> only when the hardware can auto emit STOP.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
Looks sensible to me.
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Thanks,
Miquèl
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic
2024-07-02 22:31 [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic Frank Li
2024-07-08 6:53 ` Miquel Raynal
@ 2024-07-15 21:48 ` Alexandre Belloni
1 sibling, 0 replies; 3+ messages in thread
From: Alexandre Belloni @ 2024-07-15 21:48 UTC (permalink / raw)
To: Miquel Raynal, Conor Culhane, linux-i3c, linux-kernel, Frank Li; +Cc: imx
On Tue, 02 Jul 2024 18:31:07 -0400, Frank Li wrote:
> The REQUEST_PROC_DAA command behaves differently from other commands.
> Sometimes the hardware can auto emit STOP, but in other conditions, it
> cannot.
>
> Improves the code logic to better handle these situations.
>
> Hardware can auto emit STOP only when the following conditions are met:
> - The previous I3C device correctly returns a PID and ACKs an I3C address.
> - A NACK is received when emitting 7E to try to get the next I3C device's
> PID.
>
> [...]
Applied, thanks!
[1/1] i3c: master: svc: Improve DAA STOP handle code logic
https://git.kernel.org/abelloni/c/a7809cb368b9
Best regards,
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-07-15 21:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-02 22:31 [PATCH 1/1] i3c: master: svc: Improve DAA STOP handle code logic Frank Li
2024-07-08 6:53 ` Miquel Raynal
2024-07-15 21:48 ` Alexandre Belloni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox