ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/1.patch b/1.patch
new file mode 100755
index 0000000..48fb6ad
--- /dev/null
+++ b/1.patch
@@ -0,0 +1,260 @@
+commit 15e12c71ee848d275cf1f9ca8e1cf3676f0bb1af
+Author: Yu Zhang <yuzhang@asrmicro.com>
+Date: Tue Oct 10 04:28:07 2023 -0400
+
+ k-driver: uart: update uart clk and baudrate configuration
+
+ Summary:
+ type: design change
+
+ priority: normal
+
+ impact: uart support more clock sources and baudrates
+
+ details:
+ Use 58.5m clock source to derive 115200 and some other
+ baudrates, it's mainly used by AP UART to output logs.
+ Use 78m clock source to derive other high speed baudrates
+ for the UARTs which are used to connect peripherals.
+ This is for 1802s/1803/1828, 1826 use the old way.
+
+ Test Plan:
+ AP UARTs can work with different clock sources
+
+ dependency: None
+
+ onto branches: master
+
+ redmine: N/A
+
+ Reviewers: lianghu, xhtan, gaoxhong, feilv, xuepingwang
+
+ Reviewed By: xhtan
+
+ Differential Revision: http://10.26.128.140/D10291
+
+diff --git a/drivers/clk/mmp/clk-asr1802s.c b/drivers/clk/mmp/clk-asr1802s.c
+old mode 100755
+new mode 100644
+index 0492fce33..167123913
+--- a/drivers/clk/mmp/clk-asr1802s.c
++++ b/drivers/clk/mmp/clk-asr1802s.c
+@@ -115,10 +115,12 @@ static struct clk_factor_masks uart_factor_masks = {
+
+ static struct clk_factor_tbl uart_factor_tbl[] = {
+ {.num = 8125, .den = 1536}, /*14.745MHZ */
+- {.num = 0x1f3e, .den = 0x600}, /*14.97MHZ */
+- {.num = 0x1fdc, .den = 0x689}, /*15.99MHZ */
+- {.num = 3250, .den = 2000}, /*48MHZ */
++ {.num = 7998, .den = 1536}, /*14.97MHZ */
++ {.num = 8156, .den = 1673}, /*15.99MHZ */
++ {.num = 3900, .den = 2000}, /*40 MHZ */
++ {.num = 3250, .den = 2000}, /*48 MHZ */
+ {.num = 2100, .den = 1600}, /*59.429MHZ */
++ {.num = 2039, .den = 1673}, /*63.999MHZ */
+ };
+
+ static struct clk_factor_masks isccr1_factor_masks = {
+@@ -142,7 +144,8 @@ static const struct clk_div_table clk_ssp1_ref_table[] = {
+ { .val = 0, .div = 0 },
+ };
+
+-static const char *uart_parent[] = {"pll1_3_16", "uart_pll"};
++static const char *uart_parent[] = {"pll1_3_32", "uart_pll"};
++static const char *cpuart_parent[] = {"uart_pll", "pll1_3_32"};
+ static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12", "pll1_192", "pll1_384", "pll1_768"};
+ static const char *ssp1_parent[] = {"pll1_2", "vctcxo"};
+
+@@ -284,9 +287,9 @@ void __init asr1802s_pll_init(void *mpmu_base, void *apbs_base, void *apmu_base)
+ CLK_SET_RATE_PARENT, 2, 3);
+ clk_register_clkdev(clk, "pll1_2_1_5", NULL);
+
+- clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1_624",
+- CLK_SET_RATE_PARENT, 3, 16);
+- clk_register_clkdev(clk, "pll1_3_16", NULL);
++ clk = clk_register_fixed_factor(NULL, "pll1_3_32", "pll1_624",
++ CLK_SET_RATE_PARENT, 3, 32);
++ clk_register_clkdev(clk, "pll1_3_32", NULL);
+ }
+
+ /*
+@@ -1104,31 +1107,31 @@ void __init asr1802s_clk_init(void)
+ clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
+- clk_set_parent(clk, uart_pll);
++ //clk_set_parent(clk, uart_pll);
+ clk_register_clkdev(clk, "uart_mux.0", NULL);
+
+ clk = mmp_clk_register_apbc("uart0", "uart0_mux",
+- apbc_base + APBC_UART0, 10, 0, &clk_lock);
++ apbc_base + APBC_UART0, 10, APBC_MUX, &clk_lock);
+ clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
+
+ clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
+ ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
+ apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
+- clk_set_parent(clk, uart_pll);
++ //clk_set_parent(clk, uart_pll);
+ clk_register_clkdev(clk, "uart_mux.1", NULL);
+
+ clk = mmp_clk_register_apbc("uart1", "uart1_mux",
+- apbc_base + APBC_UART1, 10, 0, &clk_lock);
++ apbc_base + APBC_UART1, 10, APBC_MUX, &clk_lock);
+ clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
+
+- clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
+- ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
++ clk = clk_register_mux(NULL, "uart2_mux", cpuart_parent,
++ ARRAY_SIZE(cpuart_parent), CLK_SET_RATE_PARENT,
+ apbcp_base + APBCP_UART2, 4, 3, 0, &clk_lock);
+- clk_set_parent(clk, uart_pll);
++ //clk_set_parent(clk, uart_pll);
+ clk_register_clkdev(clk, "uart_mux.2", NULL);
+
+ clk = mmp_clk_register_apbc("uart2", "uart2_mux",
+- apbcp_base + APBCP_UART2, 10, 0, &clk_lock);
++ apbcp_base + APBCP_UART2, 10, APBC_MUX, &clk_lock);
+ clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
+
+ clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
+diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
+index 1a173dbb5..5914f59d3 100644
+--- a/drivers/tty/serial/pxa.c
++++ b/drivers/tty/serial/pxa.c
+@@ -1101,6 +1101,75 @@ static void serial_pxa_shutdown(struct uart_port *port)
+ serial_out(up, UART_FCR, 0);
+ }
+
++#ifdef CONFIG_CPU_ASR1802S
++static int pxa_set_baudrate_clk(struct uart_port *port, unsigned int baud)
++{
++ struct uart_pxa_port *up = (struct uart_pxa_port *)port;
++ unsigned long rate;
++ int ret;
++ struct clk *clk;
++
++ switch (baud) {
++ case 500000:
++ case 1000000:
++ case 1500000:
++ case 3000000:
++ rate = 48000000; /* from 78m, uart pll1 */
++ break;
++ case 38400:
++ case 57600:
++ case 115200:
++ case 576000:
++ case 1152000:
++ case 1842000:
++ case 3500000:
++ rate = 58500000; /* 58.5M, all SoCs have */
++ break;
++ case 2000000:
++ case 4000000:
++ rate = 63999000; /* from 78m, uart pll1 */
++ break;
++ case 2500000:
++ rate = 40000000; /* from 78m, uart pll1 */
++ break;
++ default:
++ if (cpu_is_asr1803())
++ rate = 14970000; /* from 78m, uart pll1 */
++ else
++ rate = 14740000; /* from 78m, uart pll1 */
++ break;
++ }
++
++ /*
++ * It seems that the clock driver can not change uart clk to a frequency
++ * supported by its M/N factor parent(uart_pll) from another pll1_3_32 parent.
++ * Therefore, we workaround it through change its uart_pll parent directly here.
++ * v2102 branch doesn't has such issue, need to debug in the furture.
++ */
++ if(rate != 58500000) { /* 58.5 is from pll1_3_32 */
++ clk = clk_get(NULL, "uart_pll");
++ if (clk)
++ clk_set_rate(clk, rate);
++ }
++
++ /* For one target baudrate, the quot is figured out
++ * by formula [quot] = clk_rate / 16 / baudrate, and
++ * choose the closest integral value above zero.
++ * So for different clk source, the real baudrate is
++ * baudrate = clk_rate / 16 / [quot]. */
++ ret = clk_set_rate(up->clk, rate);
++ if (ret < 0) {
++ dev_err(port->dev,
++ "Failed to set clk rate %lu\n", rate);
++ return ret;
++ }
++
++ up->port.uartclk = clk_get_rate(up->clk);
++
++ return 0;
++}
++#endif
++
+ static void
+ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+ struct ktermios *old)
+@@ -1110,6 +1179,9 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+ unsigned long flags;
+ unsigned int baud, quot = 0;
+ unsigned int dll;
++#ifdef CONFIG_CPU_ASR1802S
++ int ret;
++#endif
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+@@ -1134,12 +1206,29 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+ if (!(termios->c_cflag & PARODD))
+ cval |= UART_LCR_EPAR;
+
++#ifdef CONFIG_CPU_ASR1802S
++ baud = uart_get_baud_rate(port, termios, old, 0, PXA_MAX_BAUD*16*4/16);
++ if (!baud)
++ baud = 115200;
++
++ ret = pxa_set_baudrate_clk(port, baud);
++ if (ret < 0) {
++ dev_err(port->dev, "Failed to set baud rate clk: %d\n", ret);
++ return;
++ }
++
++ quot = uart_get_divisor(port, baud);
++#else
+ up->clk = clk_get(up->port.dev, "uart_pll");
+ if (unlikely(IS_ERR(up->clk))){
+ return;
+ }
+
+ baud = uart_get_baud_rate(port, termios, old, 0, PXA_MAX_BAUD*16*4/16);
++ if (!baud)
++ baud = 115200;
++
++ /* 1826 keeps the old way */
+ if (baud == 1842000 || baud > 3000000) {
+ clk_set_rate(up->clk, 59429000);
+ } else if (baud > 1000000) {
+@@ -1147,10 +1236,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+ } else if (baud > 921600) {
+ clk_set_rate(up->clk, 15990000);
+ }else{
+- if (cpu_is_asr1803())
+- clk_set_rate(up->clk, 14970000);
+- else
+- clk_set_rate(up->clk, 14740000);
++ clk_set_rate(up->clk, 14740000);
+ }
+
+ up->port.uartclk = clk_get_rate(up->clk);
+@@ -1170,6 +1256,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+ } else {
+ quot = uart_get_divisor(port, baud);
+ }
++#endif
+
+ if (up->dma_enable) {
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32 |