summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0021-Config-host-uart-clock-source-using-environment-vari.patch
blob: 32a40261f29093530df05735c5f06643edd375b4 (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
From 30c634b4969b8a3cd3afc079d60d23d2cb9f5f5c Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
Date: Mon, 11 Feb 2019 15:19:56 +0800
Subject: [PATCH] Config host uart clock source using environment variable

In order to support high speed uart for host uarts,
the uart clock needs to be switched between 24M and 192M.
Config SCU4C based on environment variable hostserialcfg,
this variable is set by IPMI OEM commands.

Tested:
Change the hostserialcfg variable to 0/1/2/3,
using the below commands:

ipmitool raw 0x32 0x90 1 0; reboot
cat /sys/class/tty/ttyS*/uartclk, all should be 24MHz

ipmitool raw 0x32 0x90 1 1; reboot
cat /sys/class/tty/ttyS*/uartclk, ttyS0/2/3 should be 192MHz

ipmitool raw 0x32 0x90 1 2; reboot
cat /sys/class/tty/ttyS*/uartclk, ttyS1 should be 192MHz

ipmitool raw 0x32 0x90 1 3; reboot
cat /sys/class/tty/ttyS*/uartclk, ttyS0/12/3 should be 192MHz

Signed-off-by: Yong Li <yong.b.li@linux.intel.com>

---
 arch/arm/include/asm/arch-aspeed/regs-scu.h |  5 ++++
 board/aspeed/ast-g5/ast-g5-intel.c          | 39 +++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/include/asm/arch-aspeed/regs-scu.h b/arch/arm/include/asm/arch-aspeed/regs-scu.h
index 10b983a..8a596ce 100644
--- a/arch/arm/include/asm/arch-aspeed/regs-scu.h
+++ b/arch/arm/include/asm/arch-aspeed/regs-scu.h
@@ -529,6 +529,11 @@
 /* AST_SCU_MAC_CLK			0x48 - MAC interface clock delay setting register */
 
 /* AST_SCU_MISC2_CTRL			0x4C - Misc. 2 Control register */
+#define SCU_UART5_HS_CLOCK		(1 << 28)
+#define SCU_UART4_HS_CLOCK		(1 << 27)
+#define SCU_UART3_HS_CLOCK		(1 << 26)
+#define SCU_UART2_HS_CLOCK		(1 << 25)
+#define SCU_UART1_HS_CLOCK		(1 << 24)
 #ifdef AST_SOC_G5
 #define SCU_PCIE_MAPPING_HIGH		(1 << 15)
 #define SCU_MALI_DTY_MODE		(1 << 8)
diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
index e0bf9ee..e19df03 100644
--- a/board/aspeed/ast-g5/ast-g5-intel.c
+++ b/board/aspeed/ast-g5/ast-g5-intel.c
@@ -103,6 +103,9 @@ static const GPIOValue gpio_table[] = {
 #define SGPIO_ENABLE 1
 #define GPIO254 0x254
 
+#define HOST_SERIAL_A_HIGH_SPEED (1 << 0)
+#define HOST_SERIAL_B_HIGH_SPEED (1 << 1)
+
 static void sgpio_init(void)
 {
 	uint32_t value;
@@ -368,6 +371,42 @@ void ast_g5_intel_late_init(void)
 	char value[32];
 	u32 reset_reason = 0;
 
+	/* By default host serail A and B use normal speed */
+	uint32_t host_serial_cfg = 0;
+	char *host_serial_cfg_txt = NULL;
+
+	/* Config the uart clock source based on environment configuration */
+	host_serial_cfg_txt = getenv("hostserialcfg");
+
+	if (host_serial_cfg_txt != NULL)
+		host_serial_cfg = simple_strtoul(host_serial_cfg_txt, NULL, 16);
+
+	if (host_serial_cfg > (HOST_SERIAL_A_HIGH_SPEED | HOST_SERIAL_B_HIGH_SPEED)) {
+		printf("Invalided hostserialcfg %x, use default!\n", host_serial_cfg);
+		host_serial_cfg = 0;
+	}
+
+	/* SOL implementation requires uart1/uart3/uart4 have the same clock
+	 * source for data forwarding, config uart3 and uart4
+	 */
+	if (host_serial_cfg & HOST_SERIAL_A_HIGH_SPEED) {
+		ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) |
+			SCU_UART1_HS_CLOCK | SCU_UART3_HS_CLOCK |
+			SCU_UART4_HS_CLOCK, AST_SCU_MISC2_CTRL);
+	} else {
+		ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
+				~SCU_UART1_HS_CLOCK & ~SCU_UART3_HS_CLOCK &
+				~SCU_UART4_HS_CLOCK, AST_SCU_MISC2_CTRL);
+	}
+
+	if (host_serial_cfg & HOST_SERIAL_B_HIGH_SPEED) {
+		ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) |
+				SCU_UART2_HS_CLOCK, AST_SCU_MISC2_CTRL);
+	} else {
+		ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
+				~SCU_UART2_HS_CLOCK, AST_SCU_MISC2_CTRL);
+	}
+
 	/* save and clear reset status */
 	reset_reason = ast_scu_read(AST_SCU_SYS_CTRL);
 	snprintf(value, sizeof(value), "0x%x", reset_reason);