summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManikanta Mylavarapu <quic_mmanikan@quicinc.com>2024-09-30 20:17:09 +0530
committerAndi Shyti <andi.shyti@kernel.org>2024-11-17 11:58:14 +0100
commit506bb2ab00753a59c8a63b02e898098815dc3141 (patch)
tree92d5432b60d4ef3871fce2dd9542877e09c01e66
parent8284750a182937bf805f703311501730f02eb40e (diff)
downloadlwn-506bb2ab00753a59c8a63b02e898098815dc3141.tar.gz
lwn-506bb2ab00753a59c8a63b02e898098815dc3141.zip
i2c: qcom-geni: Support systems with 32MHz serial engine clock
In existing socs, I2C serial engine is sourced from XO (19.2MHz). Where as in IPQ5424, I2C serial engine is sourced from GPLL0 (32MHz). The existing map table is based on 19.2MHz. This patch incorporates the clock map table to derive the SCL clock from the 32MHz source clock frequency. Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com> Reviewed-by: Bjorn Andersson <andersson@kernel.org> Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-rw-r--r--drivers/i2c/busses/i2c-qcom-geni.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 212336f724a6..579c01686823 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -16,6 +16,7 @@
#include <linux/pm_runtime.h>
#include <linux/soc/qcom/geni-se.h>
#include <linux/spinlock.h>
+#include <linux/units.h>
#define SE_I2C_TX_TRANS_LEN 0x26c
#define SE_I2C_RX_TRANS_LEN 0x270
@@ -146,22 +147,36 @@ struct geni_i2c_clk_fld {
* clk_freq_out = t / t_cycle
* source_clock = 19.2 MHz
*/
-static const struct geni_i2c_clk_fld geni_i2c_clk_map[] = {
+static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {
{KHZ(100), 7, 10, 11, 26},
{KHZ(400), 2, 5, 12, 24},
{KHZ(1000), 1, 3, 9, 18},
+ {},
+};
+
+/* source_clock = 32 MHz */
+static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
+ {KHZ(100), 8, 14, 18, 40},
+ {KHZ(400), 4, 3, 11, 20},
+ {KHZ(1000), 2, 3, 6, 15},
+ {},
};
static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
{
- int i;
- const struct geni_i2c_clk_fld *itr = geni_i2c_clk_map;
+ const struct geni_i2c_clk_fld *itr;
+
+ if (clk_get_rate(gi2c->se.clk) == 32 * HZ_PER_MHZ)
+ itr = geni_i2c_clk_map_32mhz;
+ else
+ itr = geni_i2c_clk_map_19p2mhz;
- for (i = 0; i < ARRAY_SIZE(geni_i2c_clk_map); i++, itr++) {
+ while (itr->clk_freq_out != 0) {
if (itr->clk_freq_out == gi2c->clk_freq_out) {
gi2c->clk_fld = itr;
return 0;
}
+ itr++;
}
return -EINVAL;
}