On Fri, Sep 27, 2024 at 12:22:17PM +0800, Michael Wu wrote: > In commit 35eba185fd1a ("i2c: designware: Calculate SCL timing parameter > for High Speed Mode") hs_hcnt and hs_lcnt are calculated based on fixed > tHIGH = 160 and tLOW = 120. However, the set of these fixed values only > applies to the combination of hardware parameters IC_CAP_LOADING = 400pF > and IC_CLK_FREQ_OPTIMIZATION = 1. Outside of this combination, if these > fixed tHIGH = 160 and tLOW = 120 are still used, the calculated hs_hcnt > and hs_lcnt may not be small enough, making it impossible for the SCL > frequency to reach 3.4 MHz. > > Section 3.15.4.5 in DesignWare DW_apb_i2b Databook v2.03 says that when > IC_CLK_FREQ_OPTIMIZATION = 0, > > MIN_SCL_HIGHtime = 60 ns for 3.4 Mbps, bus loading = 100pF > = 120 ns for 3.4 Mbps, bus loading = 400pF > MIN_SCL_LOWtime = 160 ns for 3.4 Mbps, bus loading = 100pF > = 320 ns for 3.4 Mbps, bus loading = 400pF > > and section 3.15.4.6 says that when IC_CLK_FREQ_OPTIMIZATION = 1, > > MIN_SCL_HIGHtime = 60 ns for 3.4 Mbps, bus loading = 100pF > = 160 ns for 3.4 Mbps, bus loading = 400pF > MIN_SCL_LOWtime = 120 ns for 3.4 Mbps, bus loading = 100pF > = 320 ns for 3.4 Mbps, bus loading = 400pF > > In order to calculate more accurate hs_hcnt amd hs_lcnt, two hardware > parameters IC_CAP_LOADING and IC_CLK_FREQ_OPTIMIZATION must be > considered together. ... > +static void i2c_dw_fw_parse_hw_params(struct dw_i2c_dev *dev) Separate function is an overkill. Just inline its contents... ... > + ret = device_property_read_u32(device, "bus-capacitance-pf", &dev->bus_capacitance_pf); > + if (ret || dev->bus_capacitance_pf < 400) > + dev->bus_capacitance_pf = 100; > + else > + dev->bus_capacitance_pf = 400; > + > + dev->clk_freq_optimized = device_property_read_bool(device, "clk-freq-optimized"); ... > i2c_parse_fw_timings(device, t, false); > > + i2c_dw_fw_parse_hw_params(dev); ...here. > i2c_dw_adjust_bus_speed(dev); ... > + * @bus_capacitance_pf: bus capacitance in picofarad picofarads ... > + u32 t_high, t_low; > + > + if (dev->bus_capacitance_pf == 400) { > + t_high = dev->clk_freq_optimized ? 160 : 120; > + t_low = 320; > + } else { Yeah, this has no protection against wrong values in the DT/ACPI. So, perhaps } else if (...) { and assign defaults or bail out with an error? > + t_high = 60; > + t_low = dev->clk_freq_optimized ? 120 : 160; > + } -- With Best Regards, Andy Shevchenko