summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0037-Enable-I2C-clock-stretching-and-multi-master-support.patch
blob: 0149157729e3f495442deb21cb7200a5c9a61151 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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