[PATCH 2/2] i2c: qcom-geni: Add I2C frequency table for firmware-based SEs
Kathiravan Thirumoorthy <[email protected]> Tue, 11 Aug 2026 14:53:17 +0530
| Newsgroups | org.kernel.vger.linux-i2c,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260811-ipq5424_i2c_scl_updates-v1-2-bddcb2ceebda@oss.qualcomm.com> |
On IPQ5424, RTL-based I2C can be supported by both minicore and firmware based SEs. For firmware-based SEs, use different SCL settings as recommended by the design team. Introduce a separate table for the same. Identify whether the SE is minicore or firmware-based and select the appropriate frequency table to achieve the desired bus frequencies. Move geni_i2c_clk_map_idx() from geni_i2c_resources_init() to geni_i2c_init() to ensure SE_HW_PARAM_2 is accessed only after the required clocks have been enabled. Signed-off-by: Kathiravan Thirumoorthy <[email protected]> --- drivers/i2c/busses/i2c-qcom-geni.c | 23 +++++++++++++++++------ include/linux/soc/qcom/geni-se.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 00013b41a6f5..2f3026602c0c 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -194,12 +194,21 @@ static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = { {} }; +static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz_fwcore[] = { + { I2C_MAX_STANDARD_MODE_FREQ, 12, 9, 10, 25 }, + { I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 18 }, + { I2C_MAX_FAST_MODE_PLUS_FREQ, 1, 6, 15, 29 }, + {} +}; + static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c) { const struct geni_i2c_clk_fld *itr; + bool is_minicore = FIELD_GET(GEN_USE_MINICORES, + readl_relaxed(gi2c->se.base + SE_HW_PARAM_2)); if (clk_get_rate(gi2c->se.clk) == 32 * HZ_PER_MHZ) - itr = geni_i2c_clk_map_32mhz; + itr = is_minicore ? geni_i2c_clk_map_32mhz : geni_i2c_clk_map_32mhz_fwcore; else itr = geni_i2c_clk_map_19p2mhz; @@ -1046,6 +1055,13 @@ static int geni_i2c_init(struct geni_i2c_dev *gi2c) return ret; } + ret = geni_i2c_clk_map_idx(gi2c); + if (ret) { + return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n", + gi2c->clk_freq_out); + goto err; + } + proto = geni_se_read_proto(&gi2c->se); if (proto == GENI_SE_INVALID_PROTO) { ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C); @@ -1109,11 +1125,6 @@ static int geni_i2c_resources_init(struct geni_se *se) if (ret) return ret; - ret = geni_i2c_clk_map_idx(gi2c); - if (ret) - return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n", - gi2c->clk_freq_out); - return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW, Bps_to_icc(gi2c->clk_freq_out)); } diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index 29a53bbc0dd4..7e8c0bb6d674 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -331,6 +331,7 @@ struct geni_se { #define RX_FIFO_DEPTH_SHFT 16 /* SE_HW_PARAM_2 fields */ +#define GEN_USE_MINICORES BIT(12) #define PROG_RAM_DEPTH_MSK GENMASK(10, 0) #define HW_VER_MAJOR_MASK GENMASK(31, 28) -- 2.34.1