[U-Boot] [PATCH v2 04/11] serial: Use a more precise baud rate generation for serial_s3c24x0

José Miguel Gonçalves jose.goncalves at inov.pt
Fri Sep 14 19:28:55 CEST 2012


Program udivslot register in order to obtain a more precise baudrate.

Signed-off-by: José Miguel Gonçalves <jose.goncalves at inov.pt>
---
Changes for v2:
   - New patch
---
 drivers/serial/serial_s3c24x0.c |   24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index 280cd2d..c9bc121 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -92,16 +92,32 @@ DECLARE_GLOBAL_DATA_PTR;
 static int hwflow;
 #endif
 
+/*
+ * The values stored in the baud rate divisor register (UBRDIVn) and dividing
+ * slot register (UDIVSLOTn), are used to determine the serial Tx/Rx clock rate
+ * (baud rate) as follows:
+ *     DIV_VAL = UBRDIVn + (num of 1’s in UDIVSLOTn) / 16
+ * Using UDIVSLOT, which is the factor of floating point divisor, you can make
+ * more accurate baud rate. Section 2.1.10 of the S3C2416 User's Manual suggests
+ * using the constants on the following table.
+ */
+static const int udivslot[] = {
+	0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4A52, 0x54AA,
+	0x5555, 0xD555, 0xD5D5, 0xDDD5, 0xDDDD, 0xDFDD, 0xDFDF, 0xFFDF,
+};
+
 void _serial_setbrg(const int dev_index)
 {
 	struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
-	unsigned int reg = 0;
+	u32 pclk;
+	u32 baudrate;
 	int i;
 
-	/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
-	reg = get_PCLK() / (16 * gd->baudrate) - 1;
+	pclk = get_PCLK();
+	baudrate = gd->baudrate;
 
-	writel(reg, &uart->ubrdiv);
+	writel((pclk / baudrate / 16) - 1, &uart->ubrdiv);
+	writel(udivslot[(pclk / baudrate) % 16], &uart->udivslot);
 	for (i = 0; i < 100; i++)
 		/* Delay */ ;
 }
-- 
1.7.9.5



More information about the U-Boot mailing list