aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-06-24 05:23:52 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-06-24 05:23:52 -0400
commit26c92f3728d738aaa7e4859d5581323cd68096dd (patch)
treeb7cc2f49a6ffe6a6b88d19b33547a370ae314de6 /drivers
parent00b9de9c249f51f09c19aa41cbbb3e3eb4eea807 (diff)
serial: sh-sci: Move SCBRR calculation algo in to platform data.
This permits each port to select its own SCBRR calculation algorithm, rather than having it all ifdef'ed in the header. There are presently only 5 different variations that all parts fall under. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/sh-sci.c27
-rw-r--r--drivers/serial/sh-sci.h56
2 files changed, 25 insertions, 58 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 3a13e58e9c5d..386fb878680c 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -82,6 +82,9 @@ struct sci_port {
82 /* SCSCR initialization */ 82 /* SCSCR initialization */
83 unsigned int scscr; 83 unsigned int scscr;
84 84
85 /* SCBRR calculation algo */
86 unsigned int scbrr_algo_id;
87
85#ifdef CONFIG_HAVE_CLK 88#ifdef CONFIG_HAVE_CLK
86 /* Interface clock */ 89 /* Interface clock */
87 struct clk *iclk; 90 struct clk *iclk;
@@ -928,6 +931,27 @@ static void sci_shutdown(struct uart_port *port)
928 s->disable(port); 931 s->disable(port);
929} 932}
930 933
934static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
935 unsigned long freq)
936{
937 switch (algo_id) {
938 case SCBRR_ALGO_1:
939 return ((freq + 16 * bps) / (16 * bps) - 1);
940 case SCBRR_ALGO_2:
941 return ((freq + 16 * bps) / (32 * bps) - 1);
942 case SCBRR_ALGO_3:
943 return (((freq * 2) + 16 * bps) / (16 * bps) - 1);
944 case SCBRR_ALGO_4:
945 return (((freq * 2) + 16 * bps) / (32 * bps) - 1);
946 case SCBRR_ALGO_5:
947 return (((freq * 1000 / 32) / bps) - 1);
948 }
949
950 /* Warn, but use a safe default */
951 WARN_ON(1);
952 return ((freq + 16 * bps) / (32 * bps) - 1);
953}
954
931static void sci_set_termios(struct uart_port *port, struct ktermios *termios, 955static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
932 struct ktermios *old) 956 struct ktermios *old)
933{ 957{
@@ -937,7 +961,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
937 961
938 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 962 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
939 if (likely(baud)) 963 if (likely(baud))
940 t = SCBRR_VALUE(baud, port->uartclk); 964 t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk);
941 965
942 do { 966 do {
943 status = sci_in(port, SCxSR); 967 status = sci_in(port, SCxSR);
@@ -1108,7 +1132,6 @@ static void __devinit sci_init_single(struct platform_device *dev,
1108 sci_port->type = sci_port->port.type = p->type; 1132 sci_port->type = sci_port->port.type = p->type;
1109 1133
1110 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); 1134 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
1111
1112} 1135}
1113 1136
1114#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 1137#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 4aa0ac8e67dd..81104777a0a6 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -713,59 +713,3 @@ static inline int sci_rxd_in(struct uart_port *port)
713 return 1; 713 return 1;
714} 714}
715#endif 715#endif
716
717/*
718 * Values for the BitRate Register (SCBRR)
719 *
720 * The values are actually divisors for a frequency which can
721 * be internal to the SH3 (14.7456MHz) or derived from an external
722 * clock source. This driver assumes the internal clock is used;
723 * to support using an external clock source, config options or
724 * possibly command-line options would need to be added.
725 *
726 * Also, to support speeds below 2400 (why?) the lower 2 bits of
727 * the SCSMR register would also need to be set to non-zero values.
728 *
729 * -- Greg Banks 27Feb2000
730 *
731 * Answer: The SCBRR register is only eight bits, and the value in
732 * it gets larger with lower baud rates. At around 2400 (depending on
733 * the peripherial module clock) you run out of bits. However the
734 * lower two bits of SCSMR allow the module clock to be divided down,
735 * scaling the value which is needed in SCBRR.
736 *
737 * -- Stuart Menefy - 23 May 2000
738 *
739 * I meant, why would anyone bother with bitrates below 2400.
740 *
741 * -- Greg Banks - 7Jul2000
742 *
743 * You "speedist"! How will I use my 110bps ASR-33 teletype with paper
744 * tape reader as a console!
745 *
746 * -- Mitch Davis - 15 Jul 2000
747 */
748
749#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
750 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
751 defined(CONFIG_CPU_SUBTYPE_SH7786)
752#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
753#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
754 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
755 defined(CONFIG_CPU_SUBTYPE_SH7721)
756#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
757#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
758 defined(CONFIG_CPU_SUBTYPE_SH7724)
759static inline int scbrr_calc(struct uart_port *port, int bps, int clk)
760{
761 if (port->type == PORT_SCIF)
762 return (clk+16*bps)/(32*bps)-1;
763 else
764 return ((clk*2)+16*bps)/(16*bps)-1;
765}
766#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk)
767#elif defined(__H8300H__) || defined(__H8300S__)
768#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
769#else /* Generic SH */
770#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
771#endif