blob: 48fb6ad32ce7a944e3b4c304aa8f185de8a0226c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001commit 15e12c71ee848d275cf1f9ca8e1cf3676f0bb1af
2Author: Yu Zhang <yuzhang@asrmicro.com>
3Date: Tue Oct 10 04:28:07 2023 -0400
4
5 k-driver: uart: update uart clk and baudrate configuration
6
7 Summary:
8 type: design change
9
10 priority: normal
11
12 impact: uart support more clock sources and baudrates
13
14 details:
15 Use 58.5m clock source to derive 115200 and some other
16 baudrates, it's mainly used by AP UART to output logs.
17 Use 78m clock source to derive other high speed baudrates
18 for the UARTs which are used to connect peripherals.
19 This is for 1802s/1803/1828, 1826 use the old way.
20
21 Test Plan:
22 AP UARTs can work with different clock sources
23
24 dependency: None
25
26 onto branches: master
27
28 redmine: N/A
29
30 Reviewers: lianghu, xhtan, gaoxhong, feilv, xuepingwang
31
32 Reviewed By: xhtan
33
34 Differential Revision: http://10.26.128.140/D10291
35
36diff --git a/drivers/clk/mmp/clk-asr1802s.c b/drivers/clk/mmp/clk-asr1802s.c
37old mode 100755
38new mode 100644
39index 0492fce33..167123913
40--- a/drivers/clk/mmp/clk-asr1802s.c
41+++ b/drivers/clk/mmp/clk-asr1802s.c
42@@ -115,10 +115,12 @@ static struct clk_factor_masks uart_factor_masks = {
43
44 static struct clk_factor_tbl uart_factor_tbl[] = {
45 {.num = 8125, .den = 1536}, /*14.745MHZ */
46- {.num = 0x1f3e, .den = 0x600}, /*14.97MHZ */
47- {.num = 0x1fdc, .den = 0x689}, /*15.99MHZ */
48- {.num = 3250, .den = 2000}, /*48MHZ */
49+ {.num = 7998, .den = 1536}, /*14.97MHZ */
50+ {.num = 8156, .den = 1673}, /*15.99MHZ */
51+ {.num = 3900, .den = 2000}, /*40 MHZ */
52+ {.num = 3250, .den = 2000}, /*48 MHZ */
53 {.num = 2100, .den = 1600}, /*59.429MHZ */
54+ {.num = 2039, .den = 1673}, /*63.999MHZ */
55 };
56
57 static struct clk_factor_masks isccr1_factor_masks = {
58@@ -142,7 +144,8 @@ static const struct clk_div_table clk_ssp1_ref_table[] = {
59 { .val = 0, .div = 0 },
60 };
61
62-static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
63+static const char *uart_parent[] = {"pll1_3_32", "uart_pll"};
64+static const char *cpuart_parent[] = {"uart_pll", "pll1_3_32"};
65 static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12", "pll1_192", "pll1_384", "pll1_768"};
66 static const char *ssp1_parent[] = {"pll1_2", "vctcxo"};
67
68@@ -284,9 +287,9 @@ void __init asr1802s_pll_init(void *mpmu_base, void *apbs_base, void *apmu_base)
69 CLK_SET_RATE_PARENT, 2, 3);
70 clk_register_clkdev(clk, "pll1_2_1_5", NULL);
71
72- clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1_624",
73- CLK_SET_RATE_PARENT, 3, 16);
74- clk_register_clkdev(clk, "pll1_3_16", NULL);
75+ clk = clk_register_fixed_factor(NULL, "pll1_3_32", "pll1_624",
76+ CLK_SET_RATE_PARENT, 3, 32);
77+ clk_register_clkdev(clk, "pll1_3_32", NULL);
78 }
79
80 /*
81@@ -1104,31 +1107,31 @@ void __init asr1802s_clk_init(void)
82 clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
83 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
84 apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
85- clk_set_parent(clk, uart_pll);
86+ //clk_set_parent(clk, uart_pll);
87 clk_register_clkdev(clk, "uart_mux.0", NULL);
88
89 clk = mmp_clk_register_apbc("uart0", "uart0_mux",
90- apbc_base + APBC_UART0, 10, 0, &clk_lock);
91+ apbc_base + APBC_UART0, 10, APBC_MUX, &clk_lock);
92 clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
93
94 clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
95 ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
96 apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
97- clk_set_parent(clk, uart_pll);
98+ //clk_set_parent(clk, uart_pll);
99 clk_register_clkdev(clk, "uart_mux.1", NULL);
100
101 clk = mmp_clk_register_apbc("uart1", "uart1_mux",
102- apbc_base + APBC_UART1, 10, 0, &clk_lock);
103+ apbc_base + APBC_UART1, 10, APBC_MUX, &clk_lock);
104 clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
105
106- clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
107- ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
108+ clk = clk_register_mux(NULL, "uart2_mux", cpuart_parent,
109+ ARRAY_SIZE(cpuart_parent), CLK_SET_RATE_PARENT,
110 apbcp_base + APBCP_UART2, 4, 3, 0, &clk_lock);
111- clk_set_parent(clk, uart_pll);
112+ //clk_set_parent(clk, uart_pll);
113 clk_register_clkdev(clk, "uart_mux.2", NULL);
114
115 clk = mmp_clk_register_apbc("uart2", "uart2_mux",
116- apbcp_base + APBCP_UART2, 10, 0, &clk_lock);
117+ apbcp_base + APBCP_UART2, 10, APBC_MUX, &clk_lock);
118 clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
119
120 clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
121diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
122index 1a173dbb5..5914f59d3 100644
123--- a/drivers/tty/serial/pxa.c
124+++ b/drivers/tty/serial/pxa.c
125@@ -1101,6 +1101,75 @@ static void serial_pxa_shutdown(struct uart_port *port)
126 serial_out(up, UART_FCR, 0);
127 }
128
129+#ifdef CONFIG_CPU_ASR1802S
130+static int pxa_set_baudrate_clk(struct uart_port *port, unsigned int baud)
131+{
132+ struct uart_pxa_port *up = (struct uart_pxa_port *)port;
133+ unsigned long rate;
134+ int ret;
135+ struct clk *clk;
136+
137+ switch (baud) {
138+ case 500000:
139+ case 1000000:
140+ case 1500000:
141+ case 3000000:
142+ rate = 48000000; /* from 78m, uart pll1 */
143+ break;
144+ case 38400:
145+ case 57600:
146+ case 115200:
147+ case 576000:
148+ case 1152000:
149+ case 1842000:
150+ case 3500000:
151+ rate = 58500000; /* 58.5M, all SoCs have */
152+ break;
153+ case 2000000:
154+ case 4000000:
155+ rate = 63999000; /* from 78m, uart pll1 */
156+ break;
157+ case 2500000:
158+ rate = 40000000; /* from 78m, uart pll1 */
159+ break;
160+ default:
161+ if (cpu_is_asr1803())
162+ rate = 14970000; /* from 78m, uart pll1 */
163+ else
164+ rate = 14740000; /* from 78m, uart pll1 */
165+ break;
166+ }
167+
168+ /*
169+ * It seems that the clock driver can not change uart clk to a frequency
170+ * supported by its M/N factor parent(uart_pll) from another pll1_3_32 parent.
171+ * Therefore, we workaround it through change its uart_pll parent directly here.
172+ * v2102 branch doesn't has such issue, need to debug in the furture.
173+ */
174+ if(rate != 58500000) { /* 58.5 is from pll1_3_32 */
175+ clk = clk_get(NULL, "uart_pll");
176+ if (clk)
177+ clk_set_rate(clk, rate);
178+ }
179+
180+ /* For one target baudrate, the quot is figured out
181+ * by formula [quot] = clk_rate / 16 / baudrate, and
182+ * choose the closest integral value above zero.
183+ * So for different clk source, the real baudrate is
184+ * baudrate = clk_rate / 16 / [quot]. */
185+ ret = clk_set_rate(up->clk, rate);
186+ if (ret < 0) {
187+ dev_err(port->dev,
188+ "Failed to set clk rate %lu\n", rate);
189+ return ret;
190+ }
191+
192+ up->port.uartclk = clk_get_rate(up->clk);
193+
194+ return 0;
195+}
196+#endif
197+
198 static void
199 serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
200 struct ktermios *old)
201@@ -1110,6 +1179,9 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
202 unsigned long flags;
203 unsigned int baud, quot = 0;
204 unsigned int dll;
205+#ifdef CONFIG_CPU_ASR1802S
206+ int ret;
207+#endif
208
209 switch (termios->c_cflag & CSIZE) {
210 case CS5:
211@@ -1134,12 +1206,29 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
212 if (!(termios->c_cflag & PARODD))
213 cval |= UART_LCR_EPAR;
214
215+#ifdef CONFIG_CPU_ASR1802S
216+ baud = uart_get_baud_rate(port, termios, old, 0, PXA_MAX_BAUD*16*4/16);
217+ if (!baud)
218+ baud = 115200;
219+
220+ ret = pxa_set_baudrate_clk(port, baud);
221+ if (ret < 0) {
222+ dev_err(port->dev, "Failed to set baud rate clk: %d\n", ret);
223+ return;
224+ }
225+
226+ quot = uart_get_divisor(port, baud);
227+#else
228 up->clk = clk_get(up->port.dev, "uart_pll");
229 if (unlikely(IS_ERR(up->clk))){
230 return;
231 }
232
233 baud = uart_get_baud_rate(port, termios, old, 0, PXA_MAX_BAUD*16*4/16);
234+ if (!baud)
235+ baud = 115200;
236+
237+ /* 1826 keeps the old way */
238 if (baud == 1842000 || baud > 3000000) {
239 clk_set_rate(up->clk, 59429000);
240 } else if (baud > 1000000) {
241@@ -1147,10 +1236,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
242 } else if (baud > 921600) {
243 clk_set_rate(up->clk, 15990000);
244 }else{
245- if (cpu_is_asr1803())
246- clk_set_rate(up->clk, 14970000);
247- else
248- clk_set_rate(up->clk, 14740000);
249+ clk_set_rate(up->clk, 14740000);
250 }
251
252 up->port.uartclk = clk_get_rate(up->clk);
253@@ -1170,6 +1256,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
254 } else {
255 quot = uart_get_divisor(port, baud);
256 }
257+#endif
258
259 if (up->dma_enable) {
260 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32 |