summaryrefslogtreecommitdiffstats
path: root/meta-openbmc-bsp/meta-aspeed/meta-ast2400/recipes-kernel/linux/linux-obmc/0001-work-around-aspeed-bmc-opp-palmetto-Add-GPIO-hogs-to.patch
blob: 038797b1968b4c0fbae5db184b65aaeb1d3103dd (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
From 5362492a7546230866dc4a45269bb3dae65306cb Mon Sep 17 00:00:00 2001
From: Andrew Jeffery <andrew@aj.id.au>
Date: Fri, 2 Sep 2016 12:22:41 +0930
Subject: [PATCH] work-around: aspeed-bmc-opp-palmetto: Add GPIO hogs to
 devicetree

This is a work-in-progress patch that attempts to emulate the GPIO
state originally written by the mach-aspeed board file.

It isn't entirely analogous: Whilst values might be set in the GPIO
data/direction registers, this doesn't mean the GPIO IP was in control
of the pins affected by the bits in question. However, the content of
the patch is derived directly from the data and direction values that
Steve Faure reported[1] from a Palmetto running the OpenBMC stable branch.

Secondly, the patch pays no regard to the prescribed active state of the lines
and assumes active high for all pins. This is not a reflection of the
description in the schematic, and neither do the configured GPIO values
necessarily reflect the prescribed initial values from the schematic.

A starting point for the patch was generated from the following Python script:

	 #!/usr/bin/python3
	 import sys

	 from collections import namedtuple

	 GpioRegsetConfig = namedtuple("GpioRegsetConfig", "banks value direction")
	 banks = ( "ABCD", "EFGH" )

	 broken = (
		 GpioRegsetConfig(banks[0], 0x130F8CE3, 0x01706074),
		 GpioRegsetConfig(banks[1], 0x9F48F7FF, 0x00004002)
	 )

	 working = (
		 GpioRegsetConfig(banks[0], 0x130F8CE3, 0x0370E677),
		 GpioRegsetConfig(banks[1], 0x0370E677, 0xC738F202)
	 )

	 GpioConfig = namedtuple("GpioConfig", "bank index direction state active")

	 def gpio_dt(name, config):
	     fmt = "pin_gpio_{} {{\n\tgpio-hog;\n\tgpios = <ASPEED_GPIO({}, {}) {}>;\n\t{};\n\tline-name = \"{}\";\n}};"
	     if "output" == config.direction:
		 state = "{}-{}".format(config.direction, config.state)
	     else:
		 state = config.direction
	     return fmt.format(
		 name.lower(),
		 config.bank,
		 config.index,
		 "GPIO_ACTIVE_HIGH",
		 state,
		 name)

	 def tell_gpios(config, change):
	     for i, bank in enumerate(config.banks):
		 for j in range(0, 8):
		     bi = i * 8 + j;
		     if ((1 << bi) & change) > 0:
			 gpio = "{}{}".format(bank, j)
			 if (bi & config.direction) > 0:
			     sd = "output"
			     value = "high" if (bi & config.value) > 0 else "low"
			 else:
			     sd = "input"
			     value = None
			 dtconfig = GpioConfig(bank, j, sd, value, "GPIO_ACTIVE_HIGH")
			 print(gpio_dt(gpio, dtconfig))
			 print()

	 def main():
	     for b, w in zip(broken, working):
		 cd = b.direction ^ w.direction
		 tell_gpios(w, cd)

	 if __name__ == "__main__":
	     main()

The generated patch was tested on a Pass 2 Palmetto. It was found that with the
patch and an OpenBMC userspace generated at v1.99.0-60-g2b717d8489c1, the host
could:

* Boot to Petitboot
* Reboot to Petitboot
* Survive a reboot of the BMC (remain functional at the Petitboot shell)
* Be powered off by the BMC after reboot

Reports from Andrew Geissler[2] and Cédric Le Goater[3] suggest mixed results
across the Palmetto fleet, but this patch at least represents a step forwards.

For the above reasons and those below, this patch is a temporary work-around:

* GPIOs configured as hogs cannot have their line state changed once initialised
* GPIOs configured as hogs will not be exposed to userspace even if requested

These two issues combined deny capabilities such as Cronus. The ultimate
solution is userspace daemon(s) requesting and controlling the GPIOs as
desired.

[1] https://github.com/openbmc/openbmc/issues/527#issuecomment-244239595
[2] https://github.com/openbmc/openbmc/issues/513#issuecomment-244454018
[3] https://github.com/openbmc/openbmc/issues/513#issuecomment-244414523

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 127 ++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
index 21619fd8cd8d..5c689613e5bd 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
@@ -167,6 +167,133 @@
 		output-low;
 		line-name = "func_mode2";
 	};
+
+	pin_gpio_a0 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(A, 0) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "A0";
+	};
+
+	pin_gpio_a1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(A, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "A1";
+	};
+
+	pin_gpio_b1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "B1";
+	};
+
+	pin_gpio_b2 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "B2";
+	};
+
+	pin_gpio_b7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(B, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "B7";
+	};
+
+	pin_gpio_d1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "D1";
+	};
+
+	pin_gpio_f1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 1) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "F1";
+	};
+
+	pin_gpio_f4 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 4) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "F4";
+	};
+
+	pin_gpio_f5 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 5) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "F5";
+	};
+
+	pin_gpio_f7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(F, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "F7";
+	};
+
+	pin_gpio_g3 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 3) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "G3";
+	};
+
+	pin_gpio_g4 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 4) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "G4";
+	};
+
+	pin_gpio_g5 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(G, 5) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "G5";
+	};
+
+	pin_gpio_h0 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "H0";
+	};
+
+	pin_gpio_h1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "H1";
+	};
+
+	pin_gpio_h2 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "H2";
+	};
+
+	pin_gpio_h6 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 6) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "H6";
+	};
+
+	pin_gpio_h7 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "H7";
+	};
+
 };
 
 &vuart {
-- 
2.7.4

OpenPOWER on IntegriCloud