Skip to content

Commit 96267f3

Browse files
NXP-CarlosSongalexandrebelloni
authored andcommitted
i3c: master: svc: adjust SDR according to i3c spec
According to I3C Specification(Version 1.1) 5.1.2.4 "Use of Clock Speed to Prevent Legacy I2C Devices From Seeing I3C traffic", when slow i2c devices(FM/FM+ rate i2c frequency without 50ns filter) works on i3c bus, i3c SDR should work at FM/FM+ rate. Adjust timing for difference mode. Signed-off-by: Clark Wang <xiaoning.wang@nxp.com> Signed-off-by: Carlos Song <carlos.song@nxp.com> Signed-off-by: Frank Li <frank.li@nxp.com> Acked-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/r/20240719080233.842771-1-carlos.song@nxp.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent 20ade67 commit 96267f3

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@
127127

128128
/* This parameter depends on the implementation and may be tuned */
129129
#define SVC_I3C_FIFO_SIZE 16
130+
#define SVC_I3C_PPBAUD_MAX 15
131+
#define SVC_I3C_QUICK_I2C_CLK 4170000
130132

131133
#define SVC_I3C_EVENT_IBI BIT(0)
132134
#define SVC_I3C_EVENT_HOTJOIN BIT(1)
@@ -585,6 +587,7 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
585587
struct i3c_bus *bus = i3c_master_get_bus(m);
586588
struct i3c_device_info info = {};
587589
unsigned long fclk_rate, fclk_period_ns;
590+
unsigned long i2c_period_ns, i2c_scl_rate, i3c_scl_rate;
588591
unsigned int high_period_ns, od_low_period_ns;
589592
u32 ppbaud, pplow, odhpp, odbaud, odstop, i2cbaud, reg;
590593
int ret;
@@ -605,12 +608,15 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
605608
}
606609

607610
fclk_period_ns = DIV_ROUND_UP(1000000000, fclk_rate);
611+
i2c_period_ns = DIV_ROUND_UP(1000000000, bus->scl_rate.i2c);
612+
i2c_scl_rate = bus->scl_rate.i2c;
613+
i3c_scl_rate = bus->scl_rate.i3c;
608614

609615
/*
610616
* Using I3C Push-Pull mode, target is 12.5MHz/80ns period.
611617
* Simplest configuration is using a 50% duty-cycle of 40ns.
612618
*/
613-
ppbaud = DIV_ROUND_UP(40, fclk_period_ns) - 1;
619+
ppbaud = DIV_ROUND_UP(fclk_rate / 2, i3c_scl_rate) - 1;
614620
pplow = 0;
615621

616622
/*
@@ -620,7 +626,7 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
620626
*/
621627
odhpp = 1;
622628
high_period_ns = (ppbaud + 1) * fclk_period_ns;
623-
odbaud = DIV_ROUND_UP(240 - high_period_ns, high_period_ns) - 1;
629+
odbaud = DIV_ROUND_UP(fclk_rate, SVC_I3C_QUICK_I2C_CLK * (1 + ppbaud)) - 2;
624630
od_low_period_ns = (odbaud + 1) * high_period_ns;
625631

626632
switch (bus->mode) {
@@ -629,20 +635,27 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
629635
odstop = 0;
630636
break;
631637
case I3C_BUS_MODE_MIXED_FAST:
632-
case I3C_BUS_MODE_MIXED_LIMITED:
633638
/*
634639
* Using I2C Fm+ mode, target is 1MHz/1000ns, the difference
635640
* between the high and low period does not really matter.
636641
*/
637-
i2cbaud = DIV_ROUND_UP(1000, od_low_period_ns) - 2;
642+
i2cbaud = DIV_ROUND_UP(i2c_period_ns, od_low_period_ns) - 2;
638643
odstop = 1;
639644
break;
645+
case I3C_BUS_MODE_MIXED_LIMITED:
640646
case I3C_BUS_MODE_MIXED_SLOW:
641-
/*
642-
* Using I2C Fm mode, target is 0.4MHz/2500ns, with the same
643-
* constraints as the FM+ mode.
644-
*/
645-
i2cbaud = DIV_ROUND_UP(2500, od_low_period_ns) - 2;
647+
/* I3C PP + I3C OP + I2C OP both use i2c clk rate */
648+
if (ppbaud > SVC_I3C_PPBAUD_MAX) {
649+
ppbaud = SVC_I3C_PPBAUD_MAX;
650+
pplow = DIV_ROUND_UP(fclk_rate, i3c_scl_rate) - (2 + 2 * ppbaud);
651+
}
652+
653+
high_period_ns = (ppbaud + 1) * fclk_period_ns;
654+
odhpp = 0;
655+
odbaud = DIV_ROUND_UP(fclk_rate, i2c_scl_rate * (2 + 2 * ppbaud)) - 1;
656+
657+
od_low_period_ns = (odbaud + 1) * high_period_ns;
658+
i2cbaud = DIV_ROUND_UP(i2c_period_ns, od_low_period_ns) - 2;
646659
odstop = 1;
647660
break;
648661
default:

0 commit comments

Comments
 (0)