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

José Miguel Gonçalves
2012-09-19T11:25:20Z

The values stored in the baud rate divisor register (UBRDIVn) and dividing
slot register (UDIVSLOTn), are used to determine the serial baudrate.
Previously only UBRDIVn was set. This patch initializes also UDIVSLOTn
which allows to obtain a more precise baudrate.

Signed-off-by: Jos? Miguel Gon?alves <jose.goncalves@inov.pt>
---
Changes for v2:
- New patch

Changes for v3:
- Verbose patch description

Changes for v4:
- None
---
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