summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch')
-rw-r--r--meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch
new file mode 100644
index 000000000..014915772
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch
@@ -0,0 +1,143 @@
+From 292700faccff983b60a6bf210af36d9bf7a0ac1a Mon Sep 17 00:00:00 2001
+From: Jan Sowinski <jan.sowinski@intel.com>
+Date: Fri, 15 Oct 2021 23:34:10 +0200
+Subject: [PATCH] Enable I2C clock stretching and multi-master support for
+ AST2600
+
+Enabled I2C clock stretching by default to
+improve general compatibility with various devices.
+
+Added support for multi-master mode enabled with
+"multi-master" property set in DTS for every i2c node.
+
+Signed-off-by: Jan Sowinski <jan.sowinski@intel.com>
+---
+ arch/arm/dts/ast2600-intel.dts | 8 ++++++++
+ drivers/i2c/ast_i2c.c | 19 ++++++++++++-------
+ 2 files changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/dts/ast2600-intel.dts b/arch/arm/dts/ast2600-intel.dts
+index a76193716d..dba62fd254 100644
+--- a/arch/arm/dts/ast2600-intel.dts
++++ b/arch/arm/dts/ast2600-intel.dts
+@@ -168,6 +168,7 @@
+
+ &i2c4 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c5_default>;
+@@ -175,6 +176,7 @@
+
+ &i2c5 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c6_default>;
+@@ -182,6 +184,7 @@
+
+ &i2c6 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c7_default>;
+@@ -189,6 +192,7 @@
+
+ &i2c7 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c8_default>;
+@@ -196,6 +200,7 @@
+
+ &i2c8 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c9_default>;
+@@ -203,6 +208,7 @@
+
+ &i2c9 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c10_default>;
+@@ -210,6 +216,7 @@
+
+ &i2c12 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c13_default>;
+@@ -217,6 +224,7 @@
+
+ &i2c13 {
+ status = "okay";
++ multi-master;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c14_default>;
+diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
+index bbc32d6cdb..974641220b 100644
+--- a/drivers/i2c/ast_i2c.c
++++ b/drivers/i2c/ast_i2c.c
+@@ -31,6 +31,8 @@ struct ast_i2c_priv {
+ struct ast_i2c_regs *regs;
+ /* I2C speed in Hz */
+ int speed;
++ /* Multi-master mode */
++ bool multi_master;
+ };
+
+ /*
+@@ -67,14 +69,14 @@ static void ast_i2c_clear_interrupts(struct udevice *dev)
+ static void ast_i2c_init_bus(struct udevice *dev)
+ {
+ struct ast_i2c_priv *priv = dev_get_priv(dev);
++ u32 fun_ctrl_reg = I2CD_MASTER_EN;
+
+ /* Reset device */
+ writel(0, &priv->regs->fcr);
+- /* Enable Master Mode. Assuming single-master */
+- writel(I2CD_MASTER_EN
+- | I2CD_M_SDA_LOCK_EN
+- | I2CD_MULTI_MASTER_DIS | I2CD_M_SCL_DRIVE_EN,
+- &priv->regs->fcr);
++ /* Enable Single-Master or Multi-Master Mode. */
++ if (!priv->multi_master)
++ fun_ctrl_reg |= I2CD_MULTI_MASTER_DIS;
++ writel(fun_ctrl_reg, &priv->regs->fcr);
+ /* Enable Interrupts */
+ writel(I2CD_INTR_TX_ACK
+ | I2CD_INTR_TX_NAK
+@@ -100,6 +102,9 @@ static int ast_i2c_ofdata_to_platdata(struct udevice *dev)
+ return ret;
+ }
+
++ if (dev_read_bool(dev, "multi-master"))
++ priv->multi_master = true;
++
+ return 0;
+ }
+
+@@ -246,8 +251,8 @@ static int ast_i2c_deblock(struct udevice *dev)
+ bool scl_high = csr & I2CD_SCL_LINE_STS;
+ int ret = 0;
+
+- if (sda_high && scl_high) {
+- /* Bus is idle, no deblocking needed. */
++ if ((sda_high && scl_high) || priv->multi_master) {
++ /* Bus is idle or multi-master mode enabled, no deblocking needed. */
+ return 0;
+ } else if (sda_high) {
+ /* Send stop command */
+--
+2.25.1
+