summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0017-Manufacturing-mode-physical-presence-detection.patch
blob: c0d409592df08f2d5e0983ec9e05030f1c02c861 (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
From 5d3f9d42ba9b1f634a65ae52f6263b1c4a95b947 Mon Sep 17 00:00:00 2001
From: AppaRao Puli <apparao.puli@linux.intel.com>
Date: Thu, 20 Jun 2019 18:11:43 +0530
Subject: [PATCH] Manufacturing mode physical presence detection

Support for physical presence of manufacturing mode added.
Front panel power button press for 15 seconds will be detected
and marked as special mode for manufacturing request.
There will be Status LED blink for 10 seconds to do the physical
indication to the user. This indicates the user that he has
pressed power button long enough for manufacturing mode detection.

Tested:
1. Verified by holding the power button when u-boot boots for
15 seconds, and confirmed that bootargs passed to linux has
special=mfg string and status led blink physical indication
has been provided
2. Verified in normal condition special=mfg string is not passed
and no physical indication has been provided

Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
 board/aspeed/ast2600_intel/intel.c | 74 ++++++++++++++++++++++++++++--
 common/autoboot.c                  | 12 ++++-
 2 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/board/aspeed/ast2600_intel/intel.c b/board/aspeed/ast2600_intel/intel.c
index fb9075f93945..a644010dd339 100644
--- a/board/aspeed/ast2600_intel/intel.c
+++ b/board/aspeed/ast2600_intel/intel.c
@@ -8,6 +8,8 @@
 #include <led.h>
 #include <malloc.h>
 
+#define SYS_PWR_RESET_FLAG	BIT(0) /* from scu_info.c */
+
 /* use GPIOC0 on intel boards */
 #define FFUJ_GPIO "gpio@1e78000016"
 
@@ -60,6 +62,26 @@ int gpio_abort(void)
 	return value <= 0 ? 0 : 1;
 }
 
+int read_frontpanel_power_button(void)
+{
+#define FP_PWRBTN_GPIO "gpio@1e780000122" /* GPIOP2 */
+	struct gpio_desc desc;
+	int ret;
+
+	ret = dm_gpio_lookup_name(FP_PWRBTN_GPIO, &desc);
+	if (ret)
+		return ret;
+	ret = dm_gpio_request(&desc, "fp_pwrbtn");
+	if (ret)
+		return ret;
+	ret = dm_gpio_set_dir_flags(&desc, GPIOD_ACTIVE_LOW);
+	if (ret)
+		return ret;
+	ret = dm_gpio_get_value(&desc);
+	dm_gpio_free(desc.dev, &desc);
+	return ret;
+}
+
 #define SCU_BASE 0x1E6E2000
 #define SCU_338 0x338 //Generate UART 24 MHz Reference from UXCLK
 #define SCU_33C 0x33c //Generate UART 24 MHz Reference from HUXCLK
@@ -119,6 +141,11 @@ static void gpio_passthru_init(void)
 	       SCU_BASE | SCU_418);
 }
 
+void board_pre_abort_autoboot(void)
+{
+	gpio_passthru_init();
+}
+
 #define AST_LPC_BASE 0x1e789000
 #define LPC_SNOOP_ADDR 0x80
 #define HICR5 0x080   /* Host Interface Control Register 5 */
@@ -300,8 +327,6 @@ int board_early_init_f(void)
 
 	set_gpio_default_state();
 
-	gpio_passthru_init();
-
 	port80h_snoop_init();
 
 	sgpio_init();
@@ -388,6 +413,43 @@ static void update_bootargs_cmd(const char *key, const char *value)
 	free(buf);
 }
 
+static bool is_mfg_mode_phy_req(void)
+{
+	/*
+	 * Assume mfg mode physical request is made, if power button
+	 * is pressed continously for 15 seconds, indicate the
+	 * same in bootargs
+	 */
+	const uint32_t delay_in_ms = 100;
+	const uint32_t read_count = ((15 * 1000) / delay_in_ms);
+	const uint32_t delay_for_indication = 10 * 1000;
+#ifdef CONFIG_LED_BLINK
+	struct udevice *dev;
+	int ret;
+#endif
+
+	for (uint32_t count = 0; count < read_count; ++count) {
+		if (read_frontpanel_power_button() != 1)
+			return false;
+
+		mdelay(delay_in_ms);
+	}
+
+	printf("MFG mode is requested.\n");
+
+#ifdef CONFIG_LED_BLINK
+	ret = led_get_by_label("green", &dev);
+	if (!ret) {
+		led_set_period(dev, 160);
+	}
+#endif
+
+	/* Delay the boot to do physical indication for mfg mode */
+	mdelay(delay_for_indication);
+
+	return true;
+}
+
 extern void espi_init(void);
 extern void kcs_init(void);
 extern void timer_enable(int n, u32 interval_us, interrupt_handler_t *handler,
@@ -413,8 +475,14 @@ int board_late_init(void)
 	snprintf(value, sizeof(value), "0x%x", gd->reset_reason);
 	update_bootargs_cmd("resetreason", value);
 
-	if (read_ffuj())
+	/* Update the special mode in bootargs */
+	if (gd->reset_reason & SYS_PWR_RESET_FLAG && is_mfg_mode_phy_req())
+		update_bootargs_cmd("special", "mfg");
+
+	if (read_ffuj()) {
+		gpio_passthru_init();
 		kcs_init();
+	}
 
 	return 0;
 }
diff --git a/common/autoboot.c b/common/autoboot.c
index 5e69000b848b..8a9978042386 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -261,13 +261,19 @@ int gpio_abort(void)
 	return 0;
 }
 
+/* Allow for board specific config when we check abort condition */
+__weak void board_pre_abort_autoboot(void)
+{
+	/* please define board specific board_pre_abort_autoboot() */
+}
+
 static int abortboot(int bootdelay)
 {
 	int abort = 0;
 
 	abort =	gpio_abort();
 	if (abort)
-		return abort;
+		goto exit;
 
 	if (bootdelay >= 0)
 		abort = __abortboot(bootdelay);
@@ -277,6 +283,10 @@ static int abortboot(int bootdelay)
 		gd->flags &= ~GD_FLG_SILENT;
 #endif
 
+exit:
+	if (abort)
+		board_pre_abort_autoboot();
+
 	return abort;
 }
 
-- 
2.17.1