diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-06-24 05:23:52 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-06-24 05:23:52 -0400 |
commit | 26c92f3728d738aaa7e4859d5581323cd68096dd (patch) | |
tree | b7cc2f49a6ffe6a6b88d19b33547a370ae314de6 /drivers | |
parent | 00b9de9c249f51f09c19aa41cbbb3e3eb4eea807 (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.c | 27 | ||||
-rw-r--r-- | drivers/serial/sh-sci.h | 56 |
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 | ||
934 | static 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 | |||
931 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 955 | static 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) | ||
759 | static 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 | ||