diff options
| author | 2016-01-04 14:45:22 +0100 | |
|---|---|---|
| committer | 2016-02-06 22:54:55 -0800 | |
| commit | 92a0574867f3329ca285b51adcf09ed3ee42e7a0 (patch) | |
| tree | 56cb0873c2787407212adffa3fb3e4d946caacc3 /drivers/tty/serial/sh-sci.c | |
| parent | serial: sh-sci: Use a bitmask to indicate supported sampling rates (diff) | |
| download | linux-dev-92a0574867f3329ca285b51adcf09ed3ee42e7a0.tar.xz linux-dev-92a0574867f3329ca285b51adcf09ed3ee42e7a0.zip  | |
serial: sh-sci: Add support for SCIFA/SCIFB variable sampling rates
Add support for sparse variable sampling rates on SCIFA and SCIFB.
According to the datasheet, sampling rate 1/5 needs a small quirk to
avoid corrupting the first byte received.
This increases the range and accuracy of supported baud rates.
E.g. on r8a7791/koelsch:
  - Supports now 134, 150, and standard 500000-4000000 bps,
  - Perfect match for 134, 150, 500000, 1000000, 2000000, and 4000000
    bps,
  - Accuracy has increased for most standard bps values.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
| -rw-r--r-- | drivers/tty/serial/sh-sci.c | 29 | 
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index dbf488b9ae27..4678d8f2dd7d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -88,6 +88,10 @@ enum SCI_CLKS {  #define SCI_SR(x)		BIT((x) - 1)  #define SCI_SR_RANGE(x, y)	GENMASK((y) - 1, (x) - 1) +#define SCI_SR_SCIFAB		SCI_SR(5) | SCI_SR(7) | SCI_SR(11) | \ +				SCI_SR(13) | SCI_SR(16) | SCI_SR(17) | \ +				SCI_SR(19) | SCI_SR(27) +  #define min_sr(_port)		ffs((_port)->sampling_rate_mask)  #define max_sr(_port)		fls((_port)->sampling_rate_mask) @@ -2179,6 +2183,17 @@ done:  	uart_update_timeout(port, termios->c_cflag, baud);  	if (best_clk >= 0) { +		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) +			switch (srr + 1) { +			case 5:  smr_val |= SCSMR_SRC_5;  break; +			case 7:  smr_val |= SCSMR_SRC_7;  break; +			case 11: smr_val |= SCSMR_SRC_11; break; +			case 13: smr_val |= SCSMR_SRC_13; break; +			case 16: smr_val |= SCSMR_SRC_16; break; +			case 17: smr_val |= SCSMR_SRC_17; break; +			case 19: smr_val |= SCSMR_SRC_19; break; +			case 27: smr_val |= SCSMR_SRC_27; break; +			}  		smr_val |= cks;  		dev_dbg(port->dev,  			 "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n", @@ -2227,6 +2242,16 @@ done:  	scr_val |= s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0);  	dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val);  	serial_port_out(port, SCSCR, scr_val); +	if ((srr + 1 == 5) && +	    (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) { +		/* +		 * In asynchronous mode, when the sampling rate is 1/5, first +		 * received data may become invalid on some SCIFA and SCIFB. +		 * To avoid this problem wait more than 1 serial data time (1 +		 * bit time x serial data number) after setting SCSCR.RE = 1. +		 */ +		udelay(DIV_ROUND_UP(10 * 1000000, baud)); +	}  #ifdef CONFIG_SERIAL_SH_SCI_DMA  	/* @@ -2523,7 +2548,7 @@ static int sci_init_single(struct platform_device *dev,  		port->fifosize = 256;  		sci_port->overrun_reg = SCxSR;  		sci_port->overrun_mask = SCIFA_ORER; -		sci_port->sampling_rate_mask = SCI_SR(16); +		sci_port->sampling_rate_mask = SCI_SR_SCIFAB;  		break;  	case PORT_HSCIF:  		port->fifosize = 128; @@ -2535,7 +2560,7 @@ static int sci_init_single(struct platform_device *dev,  		port->fifosize = 64;  		sci_port->overrun_reg = SCxSR;  		sci_port->overrun_mask = SCIFA_ORER; -		sci_port->sampling_rate_mask = SCI_SR(16); +		sci_port->sampling_rate_mask = SCI_SR_SCIFAB;  		break;  	case PORT_SCIF:  		port->fifosize = 16;  | 
