blob: 038797b1968b4c0fbae5db184b65aaeb1d3103dd [file] [log] [blame]
Andrew Jeffery9a373e82016-09-14 20:40:07 +09301From 5362492a7546230866dc4a45269bb3dae65306cb Mon Sep 17 00:00:00 2001
2From: Andrew Jeffery <andrew@aj.id.au>
3Date: Fri, 2 Sep 2016 12:22:41 +0930
4Subject: [PATCH] work-around: aspeed-bmc-opp-palmetto: Add GPIO hogs to
5 devicetree
6
7This is a work-in-progress patch that attempts to emulate the GPIO
8state originally written by the mach-aspeed board file.
9
10It isn't entirely analogous: Whilst values might be set in the GPIO
11data/direction registers, this doesn't mean the GPIO IP was in control
12of the pins affected by the bits in question. However, the content of
13the patch is derived directly from the data and direction values that
14Steve Faure reported[1] from a Palmetto running the OpenBMC stable branch.
15
16Secondly, the patch pays no regard to the prescribed active state of the lines
17and assumes active high for all pins. This is not a reflection of the
18description in the schematic, and neither do the configured GPIO values
19necessarily reflect the prescribed initial values from the schematic.
20
21A starting point for the patch was generated from the following Python script:
22
23 #!/usr/bin/python3
24 import sys
25
26 from collections import namedtuple
27
28 GpioRegsetConfig = namedtuple("GpioRegsetConfig", "banks value direction")
29 banks = ( "ABCD", "EFGH" )
30
31 broken = (
32 GpioRegsetConfig(banks[0], 0x130F8CE3, 0x01706074),
33 GpioRegsetConfig(banks[1], 0x9F48F7FF, 0x00004002)
34 )
35
36 working = (
37 GpioRegsetConfig(banks[0], 0x130F8CE3, 0x0370E677),
38 GpioRegsetConfig(banks[1], 0x0370E677, 0xC738F202)
39 )
40
41 GpioConfig = namedtuple("GpioConfig", "bank index direction state active")
42
43 def gpio_dt(name, config):
44 fmt = "pin_gpio_{} {{\n\tgpio-hog;\n\tgpios = <ASPEED_GPIO({}, {}) {}>;\n\t{};\n\tline-name = \"{}\";\n}};"
45 if "output" == config.direction:
46 state = "{}-{}".format(config.direction, config.state)
47 else:
48 state = config.direction
49 return fmt.format(
50 name.lower(),
51 config.bank,
52 config.index,
53 "GPIO_ACTIVE_HIGH",
54 state,
55 name)
56
57 def tell_gpios(config, change):
58 for i, bank in enumerate(config.banks):
59 for j in range(0, 8):
60 bi = i * 8 + j;
61 if ((1 << bi) & change) > 0:
62 gpio = "{}{}".format(bank, j)
63 if (bi & config.direction) > 0:
64 sd = "output"
65 value = "high" if (bi & config.value) > 0 else "low"
66 else:
67 sd = "input"
68 value = None
69 dtconfig = GpioConfig(bank, j, sd, value, "GPIO_ACTIVE_HIGH")
70 print(gpio_dt(gpio, dtconfig))
71 print()
72
73 def main():
74 for b, w in zip(broken, working):
75 cd = b.direction ^ w.direction
76 tell_gpios(w, cd)
77
78 if __name__ == "__main__":
79 main()
80
81The generated patch was tested on a Pass 2 Palmetto. It was found that with the
82patch and an OpenBMC userspace generated at v1.99.0-60-g2b717d8489c1, the host
83could:
84
85* Boot to Petitboot
86* Reboot to Petitboot
87* Survive a reboot of the BMC (remain functional at the Petitboot shell)
88* Be powered off by the BMC after reboot
89
90Reports from Andrew Geissler[2] and Cédric Le Goater[3] suggest mixed results
91across the Palmetto fleet, but this patch at least represents a step forwards.
92
93For the above reasons and those below, this patch is a temporary work-around:
94
95* GPIOs configured as hogs cannot have their line state changed once initialised
96* GPIOs configured as hogs will not be exposed to userspace even if requested
97
98These two issues combined deny capabilities such as Cronus. The ultimate
99solution is userspace daemon(s) requesting and controlling the GPIOs as
100desired.
101
102[1] https://github.com/openbmc/openbmc/issues/527#issuecomment-244239595
103[2] https://github.com/openbmc/openbmc/issues/513#issuecomment-244454018
104[3] https://github.com/openbmc/openbmc/issues/513#issuecomment-244414523
105
106Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
107---
108 arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 127 ++++++++++++++++++++++++++
109 1 file changed, 127 insertions(+)
110
111diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
112index 21619fd8cd8d..5c689613e5bd 100644
113--- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
114+++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts
115@@ -167,6 +167,133 @@
116 output-low;
117 line-name = "func_mode2";
118 };
119+
120+ pin_gpio_a0 {
121+ gpio-hog;
122+ gpios = <ASPEED_GPIO(A, 0) GPIO_ACTIVE_HIGH>;
123+ input;
124+ line-name = "A0";
125+ };
126+
127+ pin_gpio_a1 {
128+ gpio-hog;
129+ gpios = <ASPEED_GPIO(A, 1) GPIO_ACTIVE_HIGH>;
130+ output-high;
131+ line-name = "A1";
132+ };
133+
134+ pin_gpio_b1 {
135+ gpio-hog;
136+ gpios = <ASPEED_GPIO(B, 1) GPIO_ACTIVE_HIGH>;
137+ output-high;
138+ line-name = "B1";
139+ };
140+
141+ pin_gpio_b2 {
142+ gpio-hog;
143+ gpios = <ASPEED_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
144+ output-high;
145+ line-name = "B2";
146+ };
147+
148+ pin_gpio_b7 {
149+ gpio-hog;
150+ gpios = <ASPEED_GPIO(B, 7) GPIO_ACTIVE_HIGH>;
151+ output-high;
152+ line-name = "B7";
153+ };
154+
155+ pin_gpio_d1 {
156+ gpio-hog;
157+ gpios = <ASPEED_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
158+ output-high;
159+ line-name = "D1";
160+ };
161+
162+ pin_gpio_f1 {
163+ gpio-hog;
164+ gpios = <ASPEED_GPIO(F, 1) GPIO_ACTIVE_HIGH>;
165+ input;
166+ line-name = "F1";
167+ };
168+
169+ pin_gpio_f4 {
170+ gpio-hog;
171+ gpios = <ASPEED_GPIO(F, 4) GPIO_ACTIVE_HIGH>;
172+ input;
173+ line-name = "F4";
174+ };
175+
176+ pin_gpio_f5 {
177+ gpio-hog;
178+ gpios = <ASPEED_GPIO(F, 5) GPIO_ACTIVE_HIGH>;
179+ input;
180+ line-name = "F5";
181+ };
182+
183+ pin_gpio_f7 {
184+ gpio-hog;
185+ gpios = <ASPEED_GPIO(F, 7) GPIO_ACTIVE_HIGH>;
186+ output-high;
187+ line-name = "F7";
188+ };
189+
190+ pin_gpio_g3 {
191+ gpio-hog;
192+ gpios = <ASPEED_GPIO(G, 3) GPIO_ACTIVE_HIGH>;
193+ output-high;
194+ line-name = "G3";
195+ };
196+
197+ pin_gpio_g4 {
198+ gpio-hog;
199+ gpios = <ASPEED_GPIO(G, 4) GPIO_ACTIVE_HIGH>;
200+ input;
201+ line-name = "G4";
202+ };
203+
204+ pin_gpio_g5 {
205+ gpio-hog;
206+ gpios = <ASPEED_GPIO(G, 5) GPIO_ACTIVE_HIGH>;
207+ input;
208+ line-name = "G5";
209+ };
210+
211+ pin_gpio_h0 {
212+ gpio-hog;
213+ gpios = <ASPEED_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
214+ input;
215+ line-name = "H0";
216+ };
217+
218+ pin_gpio_h1 {
219+ gpio-hog;
220+ gpios = <ASPEED_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
221+ input;
222+ line-name = "H1";
223+ };
224+
225+ pin_gpio_h2 {
226+ gpio-hog;
227+ gpios = <ASPEED_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
228+ output-high;
229+ line-name = "H2";
230+ };
231+
232+ pin_gpio_h6 {
233+ gpio-hog;
234+ gpios = <ASPEED_GPIO(H, 6) GPIO_ACTIVE_HIGH>;
235+ output-high;
236+ line-name = "H6";
237+ };
238+
239+ pin_gpio_h7 {
240+ gpio-hog;
241+ gpios = <ASPEED_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
242+ output-high;
243+ line-name = "H7";
244+ };
245+
246 };
247
248 &vuart {
249--
2502.7.4
251