Skip to content

Commit 2a78530

Browse files
stanleychuysalexandrebelloni
authored andcommitted
i3c: master: svc: Fix npcm845 DAA process corruption
When MCONFIG.SKEW=0 and MCONFIG.ODHPP=0, the ENTDAA transaction gets corrupted and results in a no repeated-start condition at the end of address assignment. Workaround: Set MCONFIG.SKEW to 1 before initiating the DAA process. After the DAA process is completed, return MCONFIG.SKEW to its previous value. Reviewed-by: Frank Li <[email protected]> Signed-off-by: Stanley Chu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 4dd12e9 commit 2a78530

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

drivers/i3c/master/svc-i3c-master.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define SVC_I3C_MCONFIG_ODBAUD(x) FIELD_PREP(GENMASK(23, 16), (x))
3333
#define SVC_I3C_MCONFIG_ODHPP(x) FIELD_PREP(BIT(24), (x))
3434
#define SVC_I3C_MCONFIG_SKEW(x) FIELD_PREP(GENMASK(27, 25), (x))
35+
#define SVC_I3C_MCONFIG_SKEW_MASK GENMASK(27, 25)
3536
#define SVC_I3C_MCONFIG_I2CBAUD(x) FIELD_PREP(GENMASK(31, 28), (x))
3637

3738
#define SVC_I3C_MCTRL 0x084
@@ -150,6 +151,16 @@
150151
* If it is a true SlvStart, the MSTATUS state is SLVREQ.
151152
*/
152153
#define SVC_I3C_QUIRK_FALSE_SLVSTART BIT(1)
154+
/*
155+
* SVC_I3C_QUIRK_DAA_CORRUPT:
156+
* When MCONFIG.SKEW=0 and MCONFIG.ODHPP=0, the ENTDAA transaction gets
157+
* corrupted and results in a no repeated-start condition at the end of
158+
* address assignment.
159+
* Workaround:
160+
* Set MCONFIG.SKEW to 1 before initiating the DAA process. After the DAA
161+
* process is completed, return MCONFIG.SKEW to its previous value.
162+
*/
163+
#define SVC_I3C_QUIRK_DAA_CORRUPT BIT(2)
153164

154165
struct svc_i3c_cmd {
155166
u8 addr;
@@ -259,6 +270,13 @@ static inline bool svc_has_quirk(struct svc_i3c_master *master, u32 quirk)
259270
return (master->drvdata->quirks & quirk);
260271
}
261272

273+
static inline bool svc_has_daa_corrupt(struct svc_i3c_master *master)
274+
{
275+
return ((master->drvdata->quirks & SVC_I3C_QUIRK_DAA_CORRUPT) &&
276+
!(master->mctrl_config &
277+
(SVC_I3C_MCONFIG_SKEW_MASK | SVC_I3C_MCONFIG_ODHPP(1))));
278+
}
279+
262280
static inline bool is_events_enabled(struct svc_i3c_master *master, u32 mask)
263281
{
264282
return !!(master->enabled_events & mask);
@@ -1146,7 +1164,16 @@ static int svc_i3c_master_do_daa(struct i3c_master_controller *m)
11461164
}
11471165

11481166
spin_lock_irqsave(&master->xferqueue.lock, flags);
1167+
1168+
if (svc_has_daa_corrupt(master))
1169+
writel(master->mctrl_config | SVC_I3C_MCONFIG_SKEW(1),
1170+
master->regs + SVC_I3C_MCONFIG);
1171+
11491172
ret = svc_i3c_master_do_daa_locked(master, addrs, &dev_nb);
1173+
1174+
if (svc_has_daa_corrupt(master))
1175+
writel(master->mctrl_config, master->regs + SVC_I3C_MCONFIG);
1176+
11501177
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
11511178

11521179
svc_i3c_master_clear_merrwarn(master);
@@ -2033,7 +2060,8 @@ static const struct dev_pm_ops svc_i3c_pm_ops = {
20332060

20342061
static const struct svc_i3c_drvdata npcm845_drvdata = {
20352062
.quirks = SVC_I3C_QUIRK_FIFO_EMPTY |
2036-
SVC_I3C_QUIRK_FALSE_SLVSTART,
2063+
SVC_I3C_QUIRK_FALSE_SLVSTART |
2064+
SVC_I3C_QUIRK_DAA_CORRUPT,
20372065
};
20382066

20392067
static const struct svc_i3c_drvdata svc_default_drvdata = {};

0 commit comments

Comments
 (0)