diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 07c11e2a446d..6754b5d11c52 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -117,6 +117,7 @@ struct cci_master {
 };
 
 struct cci_data {
+	bool read_params_from_dt;
 	unsigned int num_masters;
 	struct i2c_adapter_quirks quirks;
 	u16 queue_size[NUM_QUEUES];
@@ -520,11 +521,20 @@ static const struct dev_pm_ops qcom_cci_pm = {
 	SET_RUNTIME_PM_OPS(cci_suspend_runtime, cci_resume_runtime, NULL)
 };
 
+static struct cci_data cci_dt_data = {
+	.read_params_from_dt = true,
+	.quirks = {},
+	.params[I2C_MODE_STANDARD] = {},
+	.params[I2C_MODE_FAST] = {},
+	.params[I2C_MODE_FAST_PLUS] = {},
+};
+
 static int cci_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	unsigned long cci_clk_rate = 0;
 	struct device_node *child;
+	struct cci_data *dt_data;
 	struct resource *r;
 	struct cci *cci;
 	int ret, i;
@@ -540,6 +550,267 @@ static int cci_probe(struct platform_device *pdev)
 	if (!cci->data)
 		return -ENOENT;
 
+	if (cci->data->read_params_from_dt) {
+		dt_data = &cci_dt_data;
+
+		/* CCI params */
+		ret = of_property_read_u32(dev->of_node, "num-masters", &val);
+		if (ret) {
+			dev_err(dev, "Error reading num-masters from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->num_masters = val;
+
+		ret = of_property_read_u16_array(dev->of_node, "queue-size", dt_data->queue_size,
+			(size_t)&dt_data->num_masters);
+		if (ret) {
+			dev_err(dev, "Error reading queue-size from DT, ret = %d", ret);
+			return ret;
+		}
+
+		if (ARRAY_SIZE(dt_data->queue_size) != dt_data->num_masters) {
+			dev_err(dev, "num-masters doesn't match the number of queue-size elements!");
+			return -EINVAL;
+		}
+
+		ret = of_property_read_u32(dev->of_node, "max-write-len", &val);
+		if (ret) {
+			dev_err(dev, "Error reading max-write-len from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->quirks.max_write_len = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "max-read-len", &val);
+		if (ret) {
+			dev_err(dev, "Error reading max-read-len from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->quirks.max_read_len = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "cci-clk-rate", &val);
+		if (ret) {
+			dev_err(dev, "Error reading cci-clk-rate from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->cci_clk_rate = (unsigned long)val;
+
+		/* STANDARD mode params */
+		ret = of_property_read_u32(dev->of_node, "thigh-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thigh-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].thigh = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tlow-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tlow-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].tlow = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sto-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sto-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].tsu_sto = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sta-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sta-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].tsu_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-dat-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-dat-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].thd_dat = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-sta-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-sta-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].thd_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tbuf-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tbuf-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].tbuf = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "scl-stretch-en-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading scl-stretch-en-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].scl_stretch_en = (u8)val;
+
+		ret = of_property_read_u32(dev->of_node, "trdhld-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading trdhld-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].trdhld = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsp-standard", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsp-standard from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_STANDARD].tsp = (u16)val;
+
+		/* FAST mode params */
+		ret = of_property_read_u32(dev->of_node, "thigh-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thigh-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].thigh = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tlow-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tlow-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].tlow = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sto-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sto-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].tsu_sto = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sta-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sta-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].tsu_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-dat-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-dat-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].thd_dat = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-sta-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-sta-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].thd_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tbuf-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tbuf-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].tbuf = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "scl-stretch-en-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading scl-stretch-en-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].scl_stretch_en = (u8)val;
+
+		ret = of_property_read_u32(dev->of_node, "trdhld-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading trdhld-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].trdhld = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsp-fast", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsp-fast from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST].tsp = (u16)val;
+
+		/* FAST_PLUS mode params */
+		ret = of_property_read_u32(dev->of_node, "thigh-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thigh-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].thigh = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tlow-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tlow-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].tlow = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sto-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sto-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].tsu_sto = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsu-sta-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsu-sta-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].tsu_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-dat-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-dat-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].thd_dat = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "thd-sta-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading thd-sta-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].thd_sta = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tbuf-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tbuf-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].tbuf = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "scl-stretch-en-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading scl-stretch-en-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].scl_stretch_en = (u8)val;
+
+		ret = of_property_read_u32(dev->of_node, "trdhld-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading trdhld-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].trdhld = (u16)val;
+
+		ret = of_property_read_u32(dev->of_node, "tsp-fast-plus", &val);
+		if (ret) {
+			dev_err(dev, "Error reading tsp-fast-plus from DT, ret = %d", ret);
+			return ret;
+		}
+		dt_data->params[I2C_MODE_FAST_PLUS].tsp = (u16)val;
+
+		/* Let's ship it! */
+		cci->data = dt_data;
+	}
+
 	for_each_available_child_of_node(dev->of_node, child) {
 		u32 idx;
 
@@ -818,6 +1089,9 @@ static const struct cci_data cci_msm8994_data = {
 };
 
 static const struct of_device_id cci_dt_match[] = {
+	{ .compatible = "qcom,cci", .data = &cci_dt_data },
+
+	/* Legacy compatibles for older DTs */
 	{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
 	{ .compatible = "qcom,msm8994-cci", .data = &cci_msm8994_data},
 	{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
