summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0031-Add-high-speed-baud-rate-support-for-UART.patch
blob: 5240a05f58166f416bdea07f0869d1ccee349582 (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
From 0bc792097e73c07bc324e2c9b0172fb27b51a087 Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
Date: Wed, 2 Jan 2019 15:06:43 +0800
Subject: [PATCH] Add high speed baud rate support for UART

In order to support high speed baud rate(921600 bps),
the default UART clock(24MHz) needs to be switched
to 192MHz(from USB2.0 port1 PHY).

Create a new 192M Hz clock and assign it to uart,
based on uart clock source configuration in SCU4C.

bootloader(u-boot) will set SCU4C based on the environment configuration

Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
---
 drivers/clk/clk-aspeed.c                 | 44 +++++++++++++++++++++++++++-----
 include/dt-bindings/clock/aspeed-clock.h |  2 ++
 2 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
index 411ff5fb2c07..5e1c87bc8a99 100644
--- a/drivers/clk/clk-aspeed.c
+++ b/drivers/clk/clk-aspeed.c
@@ -14,7 +14,9 @@
 
 #include "clk-aspeed.h"
 
-#define ASPEED_NUM_CLKS		38
+#define ASPEED_NUM_CLKS		ASPEED_CLK_MAX
+#define UART_HIGH_SPEED_CLK	192000000
+#define UART_LOW_SPEED_CLK	24000000
 
 #define ASPEED_RESET2_OFFSET	32
 
@@ -29,6 +31,12 @@
 #define ASPEED_MISC_CTRL	0x2c
 #define  UART_DIV13_EN		BIT(12)
 #define ASPEED_MAC_CLK_DLY	0x48
+#define ASPEED_MISC2_CTRL	0x4c
+#define  UART1_HS_CLK_EN	BIT(24)
+#define  UART2_HS_CLK_EN	BIT(25)
+#define  UART3_HS_CLK_EN	BIT(26)
+#define  UART4_HS_CLK_EN	BIT(27)
+#define  UART5_HS_CLK_EN	BIT(28)
 #define ASPEED_STRAP		0x70
 #define  CLKIN_25MHZ_EN		BIT(23)
 #define  AST2400_CLK_SOURCE_SEL	BIT(18)
@@ -386,7 +394,7 @@ static int aspeed_clk_probe(struct platform_device *pdev)
 	struct aspeed_reset *ar;
 	struct regmap *map;
 	struct clk_hw *hw;
-	u32 val, rate;
+	u32 val, rate, rate_hi;
 	int i, ret;
 
 	map = syscon_node_to_regmap(dev->of_node);
@@ -420,16 +428,25 @@ static int aspeed_clk_probe(struct platform_device *pdev)
 
 	/* UART clock div13 setting */
 	regmap_read(map, ASPEED_MISC_CTRL, &val);
-	if (val & UART_DIV13_EN)
-		rate = 24000000 / 13;
-	else
-		rate = 24000000;
+	if (val & UART_DIV13_EN) {
+		rate = UART_LOW_SPEED_CLK / 13;
+		rate_hi = UART_HIGH_SPEED_CLK / 13;
+	} else {
+		rate = UART_LOW_SPEED_CLK;
+		rate_hi = UART_HIGH_SPEED_CLK;
+	}
 	/* TODO: Find the parent data for the uart clock */
 	hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
 	aspeed_clk_data->hws[ASPEED_CLK_UART] = hw;
 
+	hw = clk_hw_register_fixed_rate(dev, "uart-hs", "usb-port1-gate", 0,
+					rate_hi);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+	aspeed_clk_data->hws[ASPEED_CLK_UART_HS] = hw;
+
 	/*
 	 * Memory controller (M-PLL) PLL. This clock is configured by the
 	 * bootloader, and is exposed to Linux as a read-only clock rate.
@@ -539,9 +556,22 @@ static int aspeed_clk_probe(struct platform_device *pdev)
 	 *   UART[1..5] clock source mux
 	 */
 
+	/* Get the uart clock source configuration from SCU4C*/
+	regmap_read(map, ASPEED_MISC2_CTRL, &val);
 	for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {
 		const struct aspeed_gate_data *gd = &aspeed_gates[i];
 		u32 gate_flags;
+		char *parent_name;
+
+		/* For uart, needs to adjust the clock based on SCU4C value */
+		if ((i == ASPEED_CLK_GATE_UART1CLK && (val & UART1_HS_CLK_EN)) ||
+		    (i == ASPEED_CLK_GATE_UART2CLK && (val & UART2_HS_CLK_EN)) ||
+		    (i == ASPEED_CLK_GATE_UART5CLK && (val & UART5_HS_CLK_EN)) ||
+		    (i == ASPEED_CLK_GATE_UART3CLK && (val & UART3_HS_CLK_EN)) ||
+		    (i == ASPEED_CLK_GATE_UART4CLK && (val & UART4_HS_CLK_EN)))
+			parent_name = "uart-hs";
+		else
+			parent_name = gd->parent_name;
 
 		/* Special case: the USB port 1 clock (bit 14) is always
 		 * working the opposite way from the other ones.
@@ -549,7 +579,7 @@ static int aspeed_clk_probe(struct platform_device *pdev)
 		gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
 		hw = aspeed_clk_hw_register_gate(dev,
 				gd->name,
-				gd->parent_name,
+				parent_name,
 				gd->flags,
 				map,
 				gd->clock_idx,
diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h
index 9ff4f6e4558c..41d531dd0b48 100644
--- a/include/dt-bindings/clock/aspeed-clock.h
+++ b/include/dt-bindings/clock/aspeed-clock.h
@@ -41,6 +41,8 @@
 #define ASPEED_CLK_24M			35
 #define ASPEED_CLK_MAC1RCLK		36
 #define ASPEED_CLK_MAC2RCLK		37
+#define ASPEED_CLK_UART_HS		38
+#define ASPEED_CLK_MAX			39
 
 #define ASPEED_RESET_XDMA		0
 #define ASPEED_RESET_MCTP		1
-- 
2.7.4