summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0031-Add-high-speed-baud-rate-support-for-UART.patch
blob: 8037012864f0c42b97f0778197cfc7ce8154a100 (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
From 01c8d6a5146cd39c2286f659e21f1a1042aa741a 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                 | 41 +++++++++++++++++++++++++++-----
 include/dt-bindings/clock/aspeed-clock.h |  2 ++
 2 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
index 42b4df6ba249..97c27820db3e 100644
--- a/drivers/clk/clk-aspeed.c
+++ b/drivers/clk/clk-aspeed.c
@@ -14,7 +14,9 @@
 
 #include <dt-bindings/clock/aspeed-clock.h>
 
-#define ASPEED_NUM_CLKS		36
+#define ASPEED_NUM_CLKS		ASPEED_CLK_MAX
+#define UART_HIGH_SPEED_CLK		192000000
+#define UART_LOW_SPEED_CLK		24000000
 
 #define ASPEED_RESET2_OFFSET	32
 
@@ -28,6 +30,12 @@
 #define  AST2400_HPLL_BYPASS_EN	BIT(17)
 #define ASPEED_MISC_CTRL	0x2c
 #define  UART_DIV13_EN		BIT(12)
+#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)
@@ -446,7 +454,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, uart_clock_div;
 	int i, ret;
 
 	map = syscon_node_to_regmap(dev->of_node);
@@ -481,15 +489,23 @@ 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;
+		uart_clock_div = 13;
 	else
-		rate = 24000000;
+		uart_clock_div = 1;
+
 	/* TODO: Find the parent data for the uart clock */
-	hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate);
+	hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0,
+					UART_LOW_SPEED_CLK / uart_clock_div);
 	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,
+					UART_HIGH_SPEED_CLK / uart_clock_div);
+	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.
@@ -570,9 +586,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.
@@ -580,7 +609,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 f43738607d77..335879505a72 100644
--- a/include/dt-bindings/clock/aspeed-clock.h
+++ b/include/dt-bindings/clock/aspeed-clock.h
@@ -39,6 +39,8 @@
 #define ASPEED_CLK_BCLK			33
 #define ASPEED_CLK_MPLL			34
 #define ASPEED_CLK_24M			35
+#define ASPEED_CLK_UART_HS		36
+#define ASPEED_CLK_MAX			37
 
 #define ASPEED_RESET_XDMA		0
 #define ASPEED_RESET_MCTP		1
-- 
2.7.4