From f195c470f2c2cf3737b2b157a5a2dbe182e374fa Mon Sep 17 00:00:00 2001 From: Jack Chen Date: Thu, 5 Jan 2023 16:29:52 -0500 Subject: [PATCH 1/2] i3c: transfer pid from boardinfo to device info I3C device PID could be defined in device tree and stored in i3c_dev_boardinfo. It should be passed to i3c_device_info when allocating a i3c_dev_desc. Rational behind this change is: when users decide to use SETDASA to assign a dynamic address with exactly the original static address, in step of i3c_master_reattach_i3c_dev, this address is checked to be taken. Then device information retrieving step is skipped. As a result, though the i3c device is registered correctly, its device driver could not be probed. Tested: Tested with a I3C device. If assigned-address is set to be the device's static address, without this change, its device driver could not probed. And with this change, its driver is probed successfully. Signed-off-by: Jack Chen Link: https://lore.kernel.org/r/20230105212952.56321-1-zenghuchen@google.com Signed-off-by: Alexandre Belloni --- drivers/i3c/master.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index d7e6f6c99aea..4dad80338831 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -1438,6 +1438,7 @@ static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master, { struct i3c_device_info info = { .static_addr = boardinfo->static_addr, + .pid = boardinfo->pid, }; struct i3c_dev_desc *i3cdev; int ret; From 510d2358c466bf6588034f0d3b2266eed2bc0a51 Mon Sep 17 00:00:00 2001 From: Jack Chen Date: Thu, 16 Feb 2023 10:10:57 -0500 Subject: [PATCH 2/2] i3c: master: dw: stop hardcoding initial speed Bus-speed could be default(12.5MHz) or defined by users in dts. Dw-i3c-master should not hard-code the initial speed to be I3C_BUS_TYP_I3C_SCL_RATE (12.5MHz) And because of Synopsys's I3C controller limit (hcnt/lcnt register length) and core-clk provided, there is a limit to bus speed, too. For example, when core-clk is 250 MHz, the bus speed cannot be lowered below 1MHz. Tested: tested with an i3c sensor and captured with a logic analyzer. Signed-off-by: Jack Chen Link: https://lore.kernel.org/r/20230216151057.293764-1-zenghuchen@google.com Signed-off-by: Alexandre Belloni --- drivers/i3c/master/dw-i3c-master.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 51a8608203de..48954d3e6571 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -531,7 +531,7 @@ static int dw_i3c_clk_cfg(struct dw_i3c_master *master) if (hcnt < SCL_I3C_TIMING_CNT_MIN) hcnt = SCL_I3C_TIMING_CNT_MIN; - lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_TYP_I3C_SCL_RATE) - hcnt; + lcnt = DIV_ROUND_UP(core_rate, master->base.bus.scl_rate.i3c) - hcnt; if (lcnt < SCL_I3C_TIMING_CNT_MIN) lcnt = SCL_I3C_TIMING_CNT_MIN; @@ -541,7 +541,8 @@ static int dw_i3c_clk_cfg(struct dw_i3c_master *master) if (!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_I2C_SLAVE_PRESENT)) writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING); - lcnt = DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, core_period); + lcnt = max_t(u8, + DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, core_period), lcnt); scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt); writel(scl_timing, master->regs + SCL_I3C_OD_TIMING);