aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/imx.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-07-05 04:02:44 -0400
committerRobert Schwebel <r.schwebel@pengutronix.de>2008-07-05 04:02:44 -0400
commit036bb15ec94216e28cb1550af0fdcdfb90c549df (patch)
tree320dd6c0fdc59813f70090190020599304baff96 /drivers/serial/imx.c
parent63dd10846d4917534e9ec7bddf43be786effe8b8 (diff)
IMX UART: do not assume 16MHz reference frequency
We assumed a 16MHz reference frequency for the UART. While this is true for i.MX1 most of the time it is not true for MX27/MX31. Also, add handling for the ONEMS register which is present on newer versions of the chip and pass a sane minimum baudrate to uart_get_baud_rate(). Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r--drivers/serial/imx.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 5a375bf0ebf4..6226e66c7966 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -589,6 +589,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
589 unsigned long flags; 589 unsigned long flags;
590 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; 590 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
591 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 591 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
592 unsigned int div, num, denom, ufcr;
592 593
593 /* 594 /*
594 * If we don't support modem control lines, don't allow 595 * If we don't support modem control lines, don't allow
@@ -634,7 +635,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
634 /* 635 /*
635 * Ask the core to calculate the divisor for us. 636 * Ask the core to calculate the divisor for us.
636 */ 637 */
637 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 638 baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
638 quot = uart_get_divisor(port, baud); 639 quot = uart_get_divisor(port, baud);
639 640
640 spin_lock_irqsave(&sport->port.lock, flags); 641 spin_lock_irqsave(&sport->port.lock, flags);
@@ -684,14 +685,41 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
684 sport->port.membase + UCR2); 685 sport->port.membase + UCR2);
685 old_txrxen &= (UCR2_TXEN | UCR2_RXEN); 686 old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
686 687
687 /* set the baud rate. We assume uartclk = 16 MHz 688 div = sport->port.uartclk / (baud * 16);
688 * 689 if (div > 7)
689 * baud * 16 UBIR - 1 690 div = 7;
690 * --------- = -------- 691 if (!div)
691 * uartclk UBMR - 1 692 div = 1;
692 */ 693
693 writel((baud / 100) - 1, sport->port.membase + UBIR); 694 num = baud;
694 writel(10000 - 1, sport->port.membase + UBMR); 695 denom = port->uartclk / div / 16;
696
697 /* shift num and denom right until they fit into 16 bits */
698 while (num > 0x10000 || denom > 0x10000) {
699 num >>= 1;
700 denom >>= 1;
701 }
702 if (num > 0)
703 num -= 1;
704 if (denom > 0)
705 denom -= 1;
706
707 writel(num, sport->port.membase + UBIR);
708 writel(denom, sport->port.membase + UBMR);
709
710 if (div == 7)
711 div = 6; /* 6 in RFDIV means divide by 7 */
712 else
713 div = 6 - div;
714
715 ufcr = readl(sport->port.membase + UFCR);
716 ufcr = (ufcr & (~UFCR_RFDIV)) |
717 (div << 7);
718 writel(ufcr, sport->port.membase + UFCR);
719
720#ifdef ONEMS
721 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
722#endif
695 723
696 writel(old_ucr1, sport->port.membase + UCR1); 724 writel(old_ucr1, sport->port.membase + UCR1);
697 725
@@ -812,7 +840,6 @@ static struct imx_port imx_ports[] = {
812 .membase = (void *)IMX_UART1_BASE, 840 .membase = (void *)IMX_UART1_BASE,
813 .mapbase = 0x00206000, 841 .mapbase = 0x00206000,
814 .irq = UART1_MINT_RX, 842 .irq = UART1_MINT_RX,
815 .uartclk = 16000000,
816 .fifosize = 32, 843 .fifosize = 32,
817 .flags = UPF_BOOT_AUTOCONF, 844 .flags = UPF_BOOT_AUTOCONF,
818 .ops = &imx_pops, 845 .ops = &imx_pops,
@@ -828,7 +855,6 @@ static struct imx_port imx_ports[] = {
828 .membase = (void *)IMX_UART2_BASE, 855 .membase = (void *)IMX_UART2_BASE,
829 .mapbase = 0x00207000, 856 .mapbase = 0x00207000,
830 .irq = UART2_MINT_RX, 857 .irq = UART2_MINT_RX,
831 .uartclk = 16000000,
832 .fifosize = 32, 858 .fifosize = 32,
833 .flags = UPF_BOOT_AUTOCONF, 859 .flags = UPF_BOOT_AUTOCONF,
834 .ops = &imx_pops, 860 .ops = &imx_pops,
@@ -858,6 +884,8 @@ static void __init imx_init_ports(void)
858 init_timer(&imx_ports[i].timer); 884 init_timer(&imx_ports[i].timer);
859 imx_ports[i].timer.function = imx_timeout; 885 imx_ports[i].timer.function = imx_timeout;
860 imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; 886 imx_ports[i].timer.data = (unsigned long)&imx_ports[i];
887
888 imx_ports[i].port.uartclk = imx_get_perclk1();
861 } 889 }
862} 890}
863 891