From: Matthieu CASTET <matthieu.castet@parrot.com>
To: Linux Arm Mailing List <linux-arm-kernel@lists.arm.linux.org.uk>,
linux-serial@vger.kernel.org, Ben Dooks <ben@trinity.fluff.org>
Subject: [PATCH] s3c2412 serial : more accurate baudrate generation
Date: Thu, 03 Jan 2008 16:39:16 +0100 [thread overview]
Message-ID: <477D01A4.6070808@parrot.com> (raw)
[-- Attachment #1: s3c_uart_2412_UDIVSLOT --]
[-- Type: text/plain, Size: 3639 bytes --]
use UDIVSLOT register on 2412, to get better accuracy when computing the
baudrate.
The clock generation is divised on 16 slots.
UDIVSLOT : if the bit n is set to 1, then for the slot n the clock generator
divide clock source by (UBRDIV + 2) instead of (UBRDIV + 1).
So if m is the number of bit set to one, the baudrate is
CLOCK / (m*(UBRDIV + 2) + (16-m)*(UBRDIV + 1))
CLOCK / (16*(UBRDIV + 1) + m)
See 2412 datasheet for more info.
Signed-off-by: Matthieu Castet <matthieu.castet@parrot.com>
Index: linux-2.6/drivers/serial/s3c2410.c
===================================================================
--- linux-2.6.orig/drivers/serial/s3c2410.c 2008-01-02 16:24:20.000000000 +0100
+++ linux-2.6/drivers/serial/s3c2410.c 2008-01-02 18:43:38.000000000 +0100
@@ -625,6 +625,7 @@
struct s3c24xx_uart_clksrc *clksrc;
unsigned int calc;
unsigned int quot;
+ unsigned int slot;
struct clk *src;
};
@@ -643,8 +644,21 @@
rate /= clksrc->divisor;
calc->clksrc = clksrc;
- calc->quot = (rate + (8 * baud)) / (16 * baud);
- calc->calc = (rate / (calc->quot * 16));
+ if (port->type == PORT_S3C2412) {
+ unsigned long divisor;
+ unsigned long rem;
+ divisor = (rate + baud / 2) / baud;
+ calc->quot = divisor / 16; /* interger part */
+ rem = divisor % 16; /* remaining part */
+ /* slot contains rem bit(s) set to 1 */
+ calc->slot = (0xffff << (16 - rem)) & 0xffff;
+
+ calc->calc = rate / divisor;
+ }
+ else {
+ calc->quot = (rate + (8 * baud)) / (16 * baud);
+ calc->calc = (rate / (calc->quot * 16));
+ }
calc->quot--;
return 1;
@@ -652,7 +666,7 @@
static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
struct s3c24xx_uart_clksrc **clksrc,
- struct clk **clk,
+ struct clk **clk, unsigned int *slot,
unsigned int baud)
{
struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
@@ -733,6 +747,7 @@
*clksrc = best->clksrc;
*clk = best->src;
+ *slot = best->slot;
return best->quot;
}
@@ -746,7 +761,7 @@
struct s3c24xx_uart_clksrc *clksrc = NULL;
struct clk *clk = NULL;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, slot = 0;
unsigned int ulcon;
unsigned int umcon;
@@ -765,7 +780,7 @@
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
else
- quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
+ quot = s3c24xx_serial_getclk(port, &clksrc, &clk, &slot, baud);
/* check to see if we need to change clock source */
@@ -826,6 +841,8 @@
wr_regl(port, S3C2410_ULCON, ulcon);
wr_regl(port, S3C2410_UBRDIV, quot);
+ if (port->type == PORT_S3C2412)
+ wr_regl(port, S3C2412_UDIVSLOT, slot);
wr_regl(port, S3C2410_UMCON, umcon);
dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
Index: linux-2.6/include/asm-arm/plat-s3c/regs-serial.h
===================================================================
--- linux-2.6.orig/include/asm-arm/plat-s3c/regs-serial.h 2008-01-02 16:44:26.000000000 +0100
+++ linux-2.6/include/asm-arm/plat-s3c/regs-serial.h 2008-01-02 16:50:57.000000000 +0100
@@ -49,6 +49,7 @@
#define S3C2410_UFCON (0x08)
#define S3C2410_UMCON (0x0C)
#define S3C2410_UBRDIV (0x28)
+#define S3C2412_UDIVSLOT (0x2C)
#define S3C2410_UTRSTAT (0x10)
#define S3C2410_UERSTAT (0x14)
#define S3C2410_UFSTAT (0x18)
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
next reply other threads:[~2008-01-03 15:39 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-03 15:39 Matthieu CASTET [this message]
2008-01-03 22:49 ` [PATCH] s3c2412 serial : more accurate baudrate generation Ben Dooks
2008-01-04 8:34 ` Matthieu CASTET
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=477D01A4.6070808@parrot.com \
--to=matthieu.castet@parrot.com \
--cc=ben@trinity.fluff.org \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--cc=linux-serial@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox