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 |