Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 May 2015 01:08:00 +0000 (UTC)
From:      Ganbold Tsagaankhuu <ganbold@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282517 - head/sys/arm/amlogic/aml8726
Message-ID:  <201505060108.t46180mi031257@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ganbold
Date: Wed May  6 01:07:59 2015
New Revision: 282517
URL: https://svnweb.freebsd.org/changeset/base/282517

Log:
  This patch adds support for the extended baud rate register
  available on the aml8726-m6 (and later) SoC which allows for
  lower speeds.
  
  Differential Revision:	https://reviews.freebsd.org/D2433
  Submitted by:	John Wehle

Modified:
  head/sys/arm/amlogic/aml8726/aml8726_uart.h
  head/sys/arm/amlogic/aml8726/uart_dev_aml8726.c

Modified: head/sys/arm/amlogic/aml8726/aml8726_uart.h
==============================================================================
--- head/sys/arm/amlogic/aml8726/aml8726_uart.h	Tue May  5 23:27:49 2015	(r282516)
+++ head/sys/arm/amlogic/aml8726/aml8726_uart.h	Wed May  6 01:07:59 2015	(r282517)
@@ -94,4 +94,14 @@
 #define	AML_UART_MISC_RECV_IRQ_CNT_MASK		0xff
 #define	AML_UART_MISC_RECV_IRQ_CNT_SHIFT	0
 
+/*
+ * The new baud rate register is available on the
+ * aml8726-m6 and later.
+ */
+#define	AML_UART_NEW_BAUD_REG			20
+#define	AML_UART_NEW_BAUD_USE_XTAL_CLK		(1 << 24)
+#define	AML_UART_NEW_BAUD_RATE_EN		(1 << 23)
+#define	AML_UART_NEW_BAUD_RATE_MASK		(0x7fffff << 0)
+#define	AML_UART_NEW_BAUD_RATE_SHIFT		0
+
 #endif /* _ARM_AMLOGIC_AML8726_UART_H */

Modified: head/sys/arm/amlogic/aml8726/uart_dev_aml8726.c
==============================================================================
--- head/sys/arm/amlogic/aml8726/uart_dev_aml8726.c	Tue May  5 23:27:49 2015	(r282516)
+++ head/sys/arm/amlogic/aml8726/uart_dev_aml8726.c	Wed May  6 01:07:59 2015	(r282517)
@@ -31,8 +31,8 @@
  * uarts.  For example ... though UART A as a 128 byte FIFO, the
  * others only have a 64 byte FIFO.
  *
- * Also, it's assumed that register 5 (the new baud rate register
- * present on the aml8726-m6) has not been activated.
+ * Also, it's assumed that the USE_XTAL_CLK feature (available on
+ * the aml8726-m6 and later) has not been activated.
  */
 
 #include <sys/cdefs.h>
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/uart/uart_cpu_fdt.h>
 #include <dev/uart/uart_bus.h>
 
+#include <arm/amlogic/aml8726/aml8726_soc.h>
 #include <arm/amlogic/aml8726/aml8726_uart.h>
 
 #include "uart_if.h"
@@ -89,7 +90,7 @@ aml8726_uart_divisor(int rclk, int baudr
 
 	/* integer version of (rclk / baudrate + .5) */
 	divisor = ((rclk << 1) + baudrate) / (baudrate << 1);
-	if (divisor == 0 || divisor >= 65536)
+	if (divisor == 0)
 		return (0);
 	actual_baud = rclk / divisor;
 
@@ -109,6 +110,7 @@ aml8726_uart_param(struct uart_bas *bas,
 {
 	uint32_t cr;
 	uint32_t mr;
+	uint32_t nbr;
 	int divisor;
 
 	cr = uart_getreg(bas, AML_UART_CONTROL_REG);
@@ -147,8 +149,29 @@ aml8726_uart_param(struct uart_bas *bas,
 	/* Set baudrate. */
 	if (baudrate > 0 && bas->rclk != 0) {
 		divisor = aml8726_uart_divisor(bas->rclk / 4, baudrate) - 1;
-		if (divisor > 0xffff)
-			return (EINVAL);
+
+		switch (aml8726_soc_hw_rev) {
+		case AML_SOC_HW_REV_M6:
+		case AML_SOC_HW_REV_M8:
+		case AML_SOC_HW_REV_M8B:
+			if (divisor > (AML_UART_NEW_BAUD_RATE_MASK >>
+			    AML_UART_NEW_BAUD_RATE_SHIFT))
+				return (EINVAL);
+
+			nbr = uart_getreg(bas, AML_UART_NEW_BAUD_REG);
+			nbr &= ~(AML_UART_NEW_BAUD_USE_XTAL_CLK |
+			    AML_UART_NEW_BAUD_RATE_MASK);
+			nbr |= AML_UART_NEW_BAUD_RATE_EN |
+			    (divisor << AML_UART_NEW_BAUD_RATE_SHIFT);
+			uart_setreg(bas, AML_UART_NEW_BAUD_REG, nbr);
+
+			divisor = 0;
+			break;
+		default:
+			if (divisor > 0xffff)
+				return (EINVAL);
+			break;
+		}
 
 		cr &= ~AML_UART_CONTROL_BAUD_MASK;
 		cr |= (divisor & AML_UART_CONTROL_BAUD_MASK);
@@ -187,7 +210,7 @@ aml8726_uart_init(struct uart_bas *bas, 
 	uint32_t cr;
 	uint32_t mr;
 
-	aml8726_uart_param(bas, baudrate, databits, stopbits, parity);
+	(void)aml8726_uart_param(bas, baudrate, databits, stopbits, parity);
 
 	cr = uart_getreg(bas, AML_UART_CONTROL_REG);
 	/* Disable all interrupt sources. */
@@ -466,7 +489,7 @@ aml8726_uart_bus_ioctl(struct uart_softc
 {
 	struct uart_bas *bas;
 	int baudrate, divisor, error;
-	uint32_t cr, mr;
+	uint32_t cr, mr, nbr;
 
 	bas = &sc->sc_bas;
 	uart_lock(sc->sc_hwmtx);
@@ -483,6 +506,20 @@ aml8726_uart_bus_ioctl(struct uart_softc
 		divisor = ((mr >> AML_UART_MISC_BAUD_EXT_SHIFT) <<
 		    AML_UART_CONTROL_BAUD_WIDTH) | cr;
 
+		switch (aml8726_soc_hw_rev) {
+		case AML_SOC_HW_REV_M6:
+		case AML_SOC_HW_REV_M8:
+		case AML_SOC_HW_REV_M8B:
+			nbr = uart_getreg(bas, AML_UART_NEW_BAUD_REG);
+			if ((nbr & AML_UART_NEW_BAUD_RATE_EN) != 0) {
+				divisor = (nbr & AML_UART_NEW_BAUD_RATE_MASK) >>
+				    AML_UART_NEW_BAUD_RATE_SHIFT;
+			}
+			break;
+		default:
+			break;
+		}
+
 		baudrate = bas->rclk / 4 / (divisor + 1);
 		if (baudrate > 0)
 			*(int*)data = baudrate;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505060108.t46180mi031257>