aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/sh-sci.c37
-rw-r--r--include/linux/serial_sci.h2
2 files changed, 32 insertions, 7 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index d5239d5ff98b..e4bf0e435af6 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -65,6 +65,7 @@ struct sci_port {
65 struct plat_sci_port *cfg; 65 struct plat_sci_port *cfg;
66 int overrun_bit; 66 int overrun_bit;
67 unsigned int error_mask; 67 unsigned int error_mask;
68 unsigned int sampling_rate;
68 69
69 70
70 /* Break timer */ 71 /* Break timer */
@@ -1750,10 +1751,13 @@ static void sci_shutdown(struct uart_port *port)
1750 sci_free_irq(s); 1751 sci_free_irq(s);
1751} 1752}
1752 1753
1753static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, 1754static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
1754 unsigned long freq) 1755 unsigned long freq)
1755{ 1756{
1756 switch (algo_id) { 1757 if (s->sampling_rate)
1758 return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1;
1759
1760 switch (s->cfg->scbrr_algo_id) {
1757 case SCBRR_ALGO_1: 1761 case SCBRR_ALGO_1:
1758 return freq / (16 * bps); 1762 return freq / (16 * bps);
1759 case SCBRR_ALGO_2: 1763 case SCBRR_ALGO_2:
@@ -1843,12 +1847,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1843 1847
1844 baud = uart_get_baud_rate(port, termios, old, 0, max_baud); 1848 baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
1845 if (likely(baud && port->uartclk)) { 1849 if (likely(baud && port->uartclk)) {
1846 if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { 1850 if (s->cfg->type == PORT_HSCIF) {
1847 sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, 1851 sci_baud_calc_hscif(baud, port->uartclk, &t, &srr,
1848 &cks); 1852 &cks);
1849 } else { 1853 } else {
1850 t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, 1854 t = sci_scbrr_calc(s, baud, port->uartclk);
1851 port->uartclk);
1852 for (cks = 0; t >= 256 && cks <= 3; cks++) 1855 for (cks = 0; t >= 256 && cks <= 3; cks++)
1853 t >>= 2; 1856 t >>= 2;
1854 } 1857 }
@@ -2092,6 +2095,7 @@ static int sci_init_single(struct platform_device *dev,
2092{ 2095{
2093 struct uart_port *port = &sci_port->port; 2096 struct uart_port *port = &sci_port->port;
2094 const struct resource *res; 2097 const struct resource *res;
2098 unsigned int sampling_rate;
2095 unsigned int i; 2099 unsigned int i;
2096 int ret; 2100 int ret;
2097 2101
@@ -2143,28 +2147,47 @@ static int sci_init_single(struct platform_device *dev,
2143 case PORT_SCIFB: 2147 case PORT_SCIFB:
2144 port->fifosize = 256; 2148 port->fifosize = 256;
2145 sci_port->overrun_bit = 9; 2149 sci_port->overrun_bit = 9;
2150 sampling_rate = 16;
2146 break; 2151 break;
2147 case PORT_HSCIF: 2152 case PORT_HSCIF:
2148 port->fifosize = 128; 2153 port->fifosize = 128;
2154 sampling_rate = 0;
2149 sci_port->overrun_bit = 0; 2155 sci_port->overrun_bit = 0;
2150 break; 2156 break;
2151 case PORT_SCIFA: 2157 case PORT_SCIFA:
2152 port->fifosize = 64; 2158 port->fifosize = 64;
2153 sci_port->overrun_bit = 9; 2159 sci_port->overrun_bit = 9;
2160 sampling_rate = 16;
2154 break; 2161 break;
2155 case PORT_SCIF: 2162 case PORT_SCIF:
2156 port->fifosize = 16; 2163 port->fifosize = 16;
2157 if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) 2164 if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) {
2158 sci_port->overrun_bit = 9; 2165 sci_port->overrun_bit = 9;
2159 else 2166 sampling_rate = 16;
2167 } else {
2160 sci_port->overrun_bit = 0; 2168 sci_port->overrun_bit = 0;
2169 sampling_rate = 32;
2170 }
2161 break; 2171 break;
2162 default: 2172 default:
2163 port->fifosize = 1; 2173 port->fifosize = 1;
2164 sci_port->overrun_bit = 5; 2174 sci_port->overrun_bit = 5;
2175 sampling_rate = 32;
2165 break; 2176 break;
2166 } 2177 }
2167 2178
2179 /* Set the sampling rate if the baud rate calculation algorithm isn't
2180 * specified.
2181 */
2182 if (p->scbrr_algo_id == SCBRR_ALGO_NONE) {
2183 /* SCIFA on sh7723 and sh7724 need a custom sampling rate that
2184 * doesn't match the SoC datasheet, this should be investigated.
2185 * Let platform data override the sampling rate for now.
2186 */
2187 sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate
2188 : sampling_rate;
2189 }
2190
2168 if (!early) { 2191 if (!early) {
2169 sci_port->iclk = clk_get(&dev->dev, "sci_ick"); 2192 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
2170 if (IS_ERR(sci_port->iclk)) { 2193 if (IS_ERR(sci_port->iclk)) {
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index e9c3021a37ae..af414e1895a5 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -11,6 +11,7 @@
11#define SCIx_NOT_SUPPORTED (-1) 11#define SCIx_NOT_SUPPORTED (-1)
12 12
13enum { 13enum {
14 SCBRR_ALGO_NONE, /* Compute sampling rate in the driver */
14 SCBRR_ALGO_1, /* clk / (16 * bps) */ 15 SCBRR_ALGO_1, /* clk / (16 * bps) */
15 SCBRR_ALGO_2, /* DIV_ROUND_CLOSEST(clk, 32 * bps) - 1 */ 16 SCBRR_ALGO_2, /* DIV_ROUND_CLOSEST(clk, 32 * bps) - 1 */
16 SCBRR_ALGO_3, /* clk / (8 * bps) */ 17 SCBRR_ALGO_3, /* clk / (8 * bps) */
@@ -134,6 +135,7 @@ struct plat_sci_port {
134 upf_t flags; /* UPF_* flags */ 135 upf_t flags; /* UPF_* flags */
135 unsigned long capabilities; /* Port features/capabilities */ 136 unsigned long capabilities; /* Port features/capabilities */
136 137
138 unsigned int sampling_rate;
137 unsigned int scbrr_algo_id; /* SCBRR calculation algo */ 139 unsigned int scbrr_algo_id; /* SCBRR calculation algo */
138 unsigned int scscr; /* SCSCR initialization */ 140 unsigned int scscr; /* SCSCR initialization */
139 141