aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2015-03-13 12:51:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-26 18:00:36 -0400
commitc1a67b48f6a5878b7ec9f49144faa02f94e965cc (patch)
tree1efe602835a2267abf95d90c588d6c8924277876 /drivers/tty/serial
parent21947ba654a685ab48f2d4089c5c2d27443c2d0d (diff)
serial: 8250_pci: replace switch-case by formula for Intel MID
This patch replaces a switch-case by a formula using rational best approximation that does necessary calculations for intel_mid_set_termios(). Below is a list of the calculations done for all defined baud rates. Each line in a format: 1) nominator, 2) denominator, 3) prescaler, 4) Fuart, 5) port UART clock, 6) list of baud rates with DLAB values. 24 25 12 48000000 64000000 4000000(1) 49 50 14 49000000 56000000 3500000(1) 4 5 16 40000000 40000000 2500000(1) 16 25 16 32000000 32000000 500000(4),1000000(2),2000000(1) 24 25 16 48000000 48000000 1500000(2),3000000(1) 2304 3125 16 36864000 36864000 576000(4),1152000(2) 8192 15625 16 26214400 26214400 50(32768),200(8192) 9216 15625 16 29491200 29491200 1800(1024),57600(32),115200(16), 230400(8),460800(4),921600(2),1843200(1) 12288 15625 16 39321600 39321600 75(32768),150(16384),300(8192), 600(4096),1200(2048),2400(1024),4800(512), 9600(256),19200(128),38400(64) 45056 78125 16 28835840 28835840 110(16384) 274432 390625 16 35127296 35127296 134(16384) Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/8250/8250_pci.c78
1 files changed, 34 insertions, 44 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 7e0519923eb5..0be8dd84f9dc 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1506,60 +1506,50 @@ byt_serial_setup(struct serial_private *priv,
1506 1506
1507#define INTEL_MID_UART_PS 0x30 1507#define INTEL_MID_UART_PS 0x30
1508#define INTEL_MID_UART_MUL 0x34 1508#define INTEL_MID_UART_MUL 0x34
1509#define INTEL_MID_UART_DIV 0x38
1509 1510
1510static void intel_mid_set_termios_50M(struct uart_port *p, 1511static void intel_mid_set_termios(struct uart_port *p,
1511 struct ktermios *termios, 1512 struct ktermios *termios,
1512 struct ktermios *old) 1513 struct ktermios *old,
1514 unsigned long fref)
1513{ 1515{
1514 unsigned int baud = tty_termios_baud_rate(termios); 1516 unsigned int baud = tty_termios_baud_rate(termios);
1515 u32 ps, mul; 1517 unsigned short ps = 16;
1516 1518 unsigned long fuart = baud * ps;
1517 /* 1519 unsigned long w = BIT(24) - 1;
1518 * The uart clk is 50Mhz, and the baud rate come from: 1520 unsigned long mul, div;
1519 * baud = 50M * MUL / (DIV * PS * DLAB) 1521
1520 * 1522 if (fref < fuart) {
1521 * For those basic low baud rate we can get the direct 1523 /* Find prescaler value that satisfies Fuart < Fref */
1522 * scalar from 2746800, like 115200 = 2746800/24. For those 1524 if (fref > baud)
1523 * higher baud rate, we handle them case by case, mainly by 1525 ps = fref / baud; /* baud rate too high */
1524 * adjusting the MUL/PS registers, and DIV register is kept 1526 else
1525 * as default value 0x3d09 to make things simple. 1527 ps = 1; /* PLL case */
1526 */ 1528 fuart = baud * ps;
1527 1529 } else {
1528 ps = 0x10; 1530 /* Get Fuart closer to Fref */
1529 1531 fuart *= rounddown_pow_of_two(fref / fuart);
1530 switch (baud) {
1531 case 500000:
1532 case 1000000:
1533 case 1500000:
1534 case 3000000:
1535 mul = 0x3a98;
1536 p->uartclk = 48000000;
1537 break;
1538 case 2000000:
1539 case 4000000:
1540 mul = 0x2710;
1541 ps = 0x08;
1542 p->uartclk = 64000000;
1543 break;
1544 case 2500000:
1545 mul = 0x30d4;
1546 p->uartclk = 40000000;
1547 break;
1548 case 3500000:
1549 mul = 0x3345;
1550 ps = 0x0c;
1551 p->uartclk = 56000000;
1552 break;
1553 default:
1554 mul = 0x2400;
1555 p->uartclk = 29491200;
1556 } 1532 }
1557 1533
1534 rational_best_approximation(fuart, fref, w, w, &mul, &div);
1535 p->uartclk = fuart * 16 / ps; /* core uses ps = 16 always */
1536
1558 writel(ps, p->membase + INTEL_MID_UART_PS); /* set PS */ 1537 writel(ps, p->membase + INTEL_MID_UART_PS); /* set PS */
1559 writel(mul, p->membase + INTEL_MID_UART_MUL); /* set MUL */ 1538 writel(mul, p->membase + INTEL_MID_UART_MUL); /* set MUL */
1539 writel(div, p->membase + INTEL_MID_UART_DIV);
1560 1540
1561 serial8250_do_set_termios(p, termios, old); 1541 serial8250_do_set_termios(p, termios, old);
1562} 1542}
1543static void intel_mid_set_termios_50M(struct uart_port *p,
1544 struct ktermios *termios,
1545 struct ktermios *old)
1546{
1547 /*
1548 * The uart clk is 50Mhz, and the baud rate come from:
1549 * baud = 50M * MUL / (DIV * PS * DLAB)
1550 */
1551 intel_mid_set_termios(p, termios, old, 50000000);
1552}
1563 1553
1564static bool intel_mid_dma_filter(struct dma_chan *chan, void *param) 1554static bool intel_mid_dma_filter(struct dma_chan *chan, void *param)
1565{ 1555{