Skip to content

Commit f2539c2

Browse files
jk-ozlabsalexandrebelloni
authored andcommitted
i3c: ast2600: enable IBI support
The ast2600 i3c hardware is capable of IBIs, but we need a workaround for a hardware issue with the I3C state machine handling IBI payloads of specific lengths when PEC is not enabled. To avoid this, we need to unconditionally enable PECs, at the consquence of losing a byte of data when the device does not send a PEC. Enable IBIs on the ast2600 platform, including an implementation of the PEC workaround, which prints a warning when triggered. Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Reviewed-by: Joel Stanley <joel@jms.id.au> Link: https://lore.kernel.org/r/ba923b96d6d129024c975e8a0472c5b2fcb3af32.1680161823.git.jk@codeconstruct.com.au Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent f3a3553 commit f2539c2

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

drivers/i3c/master/ast2600-i3c-master.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
#define AST2600_DEFAULT_SDA_PULLUP_OHMS 2000
3838

39+
#define DEV_ADDR_TABLE_IBI_PEC BIT(11)
40+
3941
struct ast2600_i3c {
4042
struct dw_i3c_master dw;
4143
struct regmap *global_regs;
@@ -99,8 +101,26 @@ static int ast2600_i3c_init(struct dw_i3c_master *dw)
99101
return rc;
100102
}
101103

104+
static void ast2600_i3c_set_dat_ibi(struct dw_i3c_master *i3c,
105+
struct i3c_dev_desc *dev,
106+
bool enable, u32 *dat)
107+
{
108+
/*
109+
* The ast2600 i3c controller will lock up on receiving 4n+1-byte IBIs
110+
* if the PEC is disabled. We have no way to restrict the length of
111+
* IBIs sent to the controller, so we need to unconditionally enable
112+
* PEC checking, which means we drop a byte of payload data
113+
*/
114+
if (enable && dev->info.bcr & I3C_BCR_IBI_PAYLOAD) {
115+
dev_warn_once(&i3c->base.dev,
116+
"Enabling PEC workaround. IBI payloads will be truncated\n");
117+
*dat |= DEV_ADDR_TABLE_IBI_PEC;
118+
}
119+
}
120+
102121
const struct dw_i3c_platform_ops ast2600_i3c_ops = {
103122
.init = ast2600_i3c_init,
123+
.set_dat_ibi = ast2600_i3c_set_dat_ibi,
104124
};
105125

106126
static int ast2600_i3c_probe(struct platform_device *pdev)
@@ -137,6 +157,7 @@ static int ast2600_i3c_probe(struct platform_device *pdev)
137157
i3c->sda_pullup);
138158

139159
i3c->dw.platform_ops = &ast2600_i3c_ops;
160+
i3c->dw.ibi_capable = true;
140161
return dw_i3c_common_probe(&i3c->dw, pdev);
141162
}
142163

0 commit comments

Comments
 (0)