Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i3c: master: support to adjust first broadcast address speed

According to I3C spec 6.2 Timing Specification, the Open Drain High Period
of SCL Clock timing for first broadcast address should be adjusted to 200ns
at least. I3C device working as i2c device will see the broadcast to close
its Spike Filter then change to work at I3C mode. After that I3C open drain
SCL high level should be adjusted back.

Signed-off-by: Carlos Song <carlos.song@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240910051626.4052552-1-carlos.song@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Carlos Song and committed by
Alexandre Belloni
aef79e18 061dd21c

+28
+12
drivers/i3c/master.c
··· 1868 1868 goto err_bus_cleanup; 1869 1869 } 1870 1870 1871 + if (master->ops->set_speed) { 1872 + ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED); 1873 + if (ret) 1874 + goto err_bus_cleanup; 1875 + } 1876 + 1871 1877 /* 1872 1878 * Reset all dynamic address that may have been assigned before 1873 1879 * (assigned by the bootloader for example). ··· 1881 1875 ret = i3c_master_rstdaa_locked(master, I3C_BROADCAST_ADDR); 1882 1876 if (ret && ret != I3C_ERROR_M2) 1883 1877 goto err_bus_cleanup; 1878 + 1879 + if (master->ops->set_speed) { 1880 + master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); 1881 + if (ret) 1882 + goto err_bus_cleanup; 1883 + } 1884 1884 1885 1885 /* Disable all slave events before starting DAA. */ 1886 1886 ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
+16
include/linux/i3c/master.h
··· 278 278 }; 279 279 280 280 /** 281 + * enum i3c_open_drain_speed - I3C open-drain speed 282 + * @I3C_OPEN_DRAIN_SLOW_SPEED: Slow open-drain speed for sending the first 283 + * broadcast address. The first broadcast address at this speed 284 + * will be visible to all devices on the I3C bus. I3C devices 285 + * working in I2C mode will turn off their spike filter when 286 + * switching into I3C mode. 287 + * @I3C_OPEN_DRAIN_NORMAL_SPEED: Normal open-drain speed in I3C bus mode. 288 + */ 289 + enum i3c_open_drain_speed { 290 + I3C_OPEN_DRAIN_SLOW_SPEED, 291 + I3C_OPEN_DRAIN_NORMAL_SPEED, 292 + }; 293 + 294 + /** 281 295 * enum i3c_addr_slot_status - I3C address slot status 282 296 * @I3C_ADDR_SLOT_FREE: address is free 283 297 * @I3C_ADDR_SLOT_RSVD: address is reserved ··· 450 436 * NULL. 451 437 * @enable_hotjoin: enable hot join event detect. 452 438 * @disable_hotjoin: disable hot join event detect. 439 + * @set_speed: adjust I3C open drain mode timing. 453 440 */ 454 441 struct i3c_master_controller_ops { 455 442 int (*bus_init)(struct i3c_master_controller *master); ··· 479 464 struct i3c_ibi_slot *slot); 480 465 int (*enable_hotjoin)(struct i3c_master_controller *master); 481 466 int (*disable_hotjoin)(struct i3c_master_controller *master); 467 + int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed); 482 468 }; 483 469 484 470 /**