* [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 @ 2013-06-17 3:38 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel Hi Olof, Hi Arnd, As requested the first patch is now includes an ack from Greg Kroah-Hartman. I have included the r8a7790 change in this patch as it depends on the first change in the pull-request but nothing else. This pull request will cause some conflicts though I believe all of them are not difficult to resolve. The renesas-next-20130613 tag in my tree illustrates how I have handled the conflicts with both changes already in arm-soc and changes I intend to send pull requests for in the near future. The following changes since commit c7788792a5e7b0d5d7f96d0766b4cb6112d47d75: Linux 3.10-rc2 (2013-05-20 14:37:38 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-sh-sci-for-v3.11 for you to fetch changes up to fe0b1091e41e0acae8ddf2da2a5a36b6867ff012: ARM: shmobile: r8a7790: don't use external clock for SCIFs (2013-06-17 12:17:48 +0900) ---------------------------------------------------------------- Renesas sh-sci updates for v3.11 HSCIF support by Ulrich Hecht. ---------------------------------------------------------------- Ulrich Hecht (2): serial: sh-sci: HSCIF support ARM: shmobile: r8a7790: don't use external clock for SCIFs arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++- include/uapi/linux/serial_core.h | 3 + 4 files changed, 120 insertions(+), 13 deletions(-) ^ permalink raw reply [flat|nested] 30+ messages in thread
* [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 @ 2013-06-17 3:38 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel Hi Olof, Hi Arnd, As requested the first patch is now includes an ack from Greg Kroah-Hartman. I have included the r8a7790 change in this patch as it depends on the first change in the pull-request but nothing else. This pull request will cause some conflicts though I believe all of them are not difficult to resolve. The renesas-next-20130613 tag in my tree illustrates how I have handled the conflicts with both changes already in arm-soc and changes I intend to send pull requests for in the near future. The following changes since commit c7788792a5e7b0d5d7f96d0766b4cb6112d47d75: Linux 3.10-rc2 (2013-05-20 14:37:38 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-sh-sci-for-v3.11 for you to fetch changes up to fe0b1091e41e0acae8ddf2da2a5a36b6867ff012: ARM: shmobile: r8a7790: don't use external clock for SCIFs (2013-06-17 12:17:48 +0900) ---------------------------------------------------------------- Renesas sh-sci updates for v3.11 HSCIF support by Ulrich Hecht. ---------------------------------------------------------------- Ulrich Hecht (2): serial: sh-sci: HSCIF support ARM: shmobile: r8a7790: don't use external clock for SCIFs arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++- include/uapi/linux/serial_core.h | 3 + 4 files changed, 120 insertions(+), 13 deletions(-) ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-17 3:38 ` Simon Horman @ 2013-06-17 3:38 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err = 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id = SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type = PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 3:38 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err == 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type == PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata = - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-17 3:38 ` Simon Horman @ 2013-06-17 12:54 ` Arnd Bergmann -1 siblings, 0 replies; 30+ messages in thread From: Arnd Bergmann @ 2013-06-17 12:54 UTC (permalink / raw) To: linux-arm-kernel On Monday 17 June 2013, Simon Horman wrote: > - if (likely(baud && port->uartclk)) > - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); > + if (likely(baud && port->uartclk)) { > + if (s->cfg->scbrr_algo_id = SCBRR_ALGO_6) { > + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, > + &cks); > + } else { > + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, > + port->uartclk); > + for (cks = 0; t >= 256 && cks <= 3; cks++) > + t >>= 2; > + } > + } This hunk causes build warnings in linux-next now: /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] serial_port_out(port, HSSRR, srr | HSCIF_SRE); ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here unsigned int srr; ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] serial_port_out(port, SCSMR, (smr_val & ~3) | cks); ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here unsigned int baud, smr_val, max_baud, cks; ^ Arnd ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 12:54 ` Arnd Bergmann 0 siblings, 0 replies; 30+ messages in thread From: Arnd Bergmann @ 2013-06-17 12:54 UTC (permalink / raw) To: linux-arm-kernel On Monday 17 June 2013, Simon Horman wrote: > - if (likely(baud && port->uartclk)) > - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); > + if (likely(baud && port->uartclk)) { > + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { > + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, > + &cks); > + } else { > + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, > + port->uartclk); > + for (cks = 0; t >= 256 && cks <= 3; cks++) > + t >>= 2; > + } > + } This hunk causes build warnings in linux-next now: /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] serial_port_out(port, HSSRR, srr | HSCIF_SRE); ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here unsigned int srr; ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] serial_port_out(port, SCSMR, (smr_val & ~3) | cks); ^ /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here unsigned int baud, smr_val, max_baud, cks; ^ Arnd ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-17 12:54 ` Arnd Bergmann @ 2013-06-18 1:19 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-18 1:19 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jun 17, 2013 at 02:54:48PM +0200, Arnd Bergmann wrote: > On Monday 17 June 2013, Simon Horman wrote: > > - if (likely(baud && port->uartclk)) > > - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); > > + if (likely(baud && port->uartclk)) { > > + if (s->cfg->scbrr_algo_id = SCBRR_ALGO_6) { > > + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, > > + &cks); > > + } else { > > + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, > > + port->uartclk); > > + for (cks = 0; t >= 256 && cks <= 3; cks++) > > + t >>= 2; > > + } > > + } > > > This hunk causes build warnings in linux-next now: > > /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': > /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] > serial_port_out(port, HSSRR, srr | HSCIF_SRE); > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here > unsigned int srr; > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] > serial_port_out(port, SCSMR, (smr_val & ~3) | cks); > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here > unsigned int baud, smr_val, max_baud, cks; Ulrich, could you please look into this? ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-18 1:19 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-18 1:19 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jun 17, 2013 at 02:54:48PM +0200, Arnd Bergmann wrote: > On Monday 17 June 2013, Simon Horman wrote: > > - if (likely(baud && port->uartclk)) > > - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); > > + if (likely(baud && port->uartclk)) { > > + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { > > + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, > > + &cks); > > + } else { > > + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, > > + port->uartclk); > > + for (cks = 0; t >= 256 && cks <= 3; cks++) > > + t >>= 2; > > + } > > + } > > > This hunk causes build warnings in linux-next now: > > /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': > /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] > serial_port_out(port, HSSRR, srr | HSCIF_SRE); > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here > unsigned int srr; > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] > serial_port_out(port, SCSMR, (smr_val & ~3) | cks); > ^ > /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here > unsigned int baud, smr_val, max_baud, cks; Ulrich, could you please look into this? ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-18 1:19 ` Simon Horman @ 2013-06-19 8:46 ` Ulrich Hecht -1 siblings, 0 replies; 30+ messages in thread From: Ulrich Hecht @ 2013-06-19 8:46 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jun 18, 2013 at 3:19 AM, Simon Horman <horms@verge.net.au> wrote: >> This hunk causes build warnings in linux-next now: >> >> /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] >> serial_port_out(port, HSSRR, srr | HSCIF_SRE); >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here >> unsigned int srr; >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] >> serial_port_out(port, SCSMR, (smr_val & ~3) | cks); >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here >> unsigned int baud, smr_val, max_baud, cks; > > Ulrich, could you please look into this? Hmmm... I get this warning with gcc 4.5, 4.6, and 4.8. Apparently gcc 4.7 is the only one that does not warn about this. Guess what I'm using... :( This is of course trivially fixed, but I have completely lost track of the transmogrifications this patch has been subjected to. What's the procedure? CU Uli ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-19 8:46 ` Ulrich Hecht 0 siblings, 0 replies; 30+ messages in thread From: Ulrich Hecht @ 2013-06-19 8:46 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jun 18, 2013 at 3:19 AM, Simon Horman <horms@verge.net.au> wrote: >> This hunk causes build warnings in linux-next now: >> >> /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] >> serial_port_out(port, HSSRR, srr | HSCIF_SRE); >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here >> unsigned int srr; >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] >> serial_port_out(port, SCSMR, (smr_val & ~3) | cks); >> ^ >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here >> unsigned int baud, smr_val, max_baud, cks; > > Ulrich, could you please look into this? Hmmm... I get this warning with gcc 4.5, 4.6, and 4.8. Apparently gcc 4.7 is the only one that does not warn about this. Guess what I'm using... :( This is of course trivially fixed, but I have completely lost track of the transmogrifications this patch has been subjected to. What's the procedure? CU Uli ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-19 8:46 ` Ulrich Hecht @ 2013-06-19 12:33 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-19 12:33 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 19, 2013 at 10:46:51AM +0200, Ulrich Hecht wrote: > On Tue, Jun 18, 2013 at 3:19 AM, Simon Horman <horms@verge.net.au> wrote: > >> This hunk causes build warnings in linux-next now: > >> > >> /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] > >> serial_port_out(port, HSSRR, srr | HSCIF_SRE); > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here > >> unsigned int srr; > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] > >> serial_port_out(port, SCSMR, (smr_val & ~3) | cks); > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here > >> unsigned int baud, smr_val, max_baud, cks; > > > > Ulrich, could you please look into this? > > Hmmm... I get this warning with gcc 4.5, 4.6, and 4.8. Apparently gcc > 4.7 is the only one that does not warn about this. Guess what I'm > using... :( > > This is of course trivially fixed, but I have completely lost track of > the transmogrifications this patch has been subjected to. What's the > procedure? Hi Ulrich, perhaps the best way forward would be for you to post an incremental patch on top of either the sh-sci branch or renesas-next-20130618 tag of my renesas tree on kernel.org. ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-19 12:33 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-19 12:33 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 19, 2013 at 10:46:51AM +0200, Ulrich Hecht wrote: > On Tue, Jun 18, 2013 at 3:19 AM, Simon Horman <horms@verge.net.au> wrote: > >> This hunk causes build warnings in linux-next now: > >> > >> /git/arm-soc/drivers/tty/serial/sh-sci.c: In function 'sci_set_termios': > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1942:37: warning: 'srr' may be used uninitialized in this function [-Wmaybe-uninitialized] > >> serial_port_out(port, HSSRR, srr | HSCIF_SRE); > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1892:15: note: 'srr' was declared here > >> unsigned int srr; > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1938:47: warning: 'cks' may be used uninitialized in this function [-Wmaybe-uninitialized] > >> serial_port_out(port, SCSMR, (smr_val & ~3) | cks); > >> ^ > >> /git/arm-soc/drivers/tty/serial/sh-sci.c:1890:40: note: 'cks' was declared here > >> unsigned int baud, smr_val, max_baud, cks; > > > > Ulrich, could you please look into this? > > Hmmm... I get this warning with gcc 4.5, 4.6, and 4.8. Apparently gcc > 4.7 is the only one that does not warn about this. Guess what I'm > using... :( > > This is of course trivially fixed, but I have completely lost track of > the transmogrifications this patch has been subjected to. What's the > procedure? Hi Ulrich, perhaps the best way forward would be for you to post an incremental patch on top of either the sh-sci branch or renesas-next-20130618 tag of my renesas tree on kernel.org. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-19 12:33 ` Simon Horman @ 2013-06-19 15:08 ` Arnd Bergmann -1 siblings, 0 replies; 30+ messages in thread From: Arnd Bergmann @ 2013-06-19 15:08 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 19 June 2013, Simon Horman wrote: > > This is of course trivially fixed, but I have completely lost track of > > the transmogrifications this patch has been subjected to. What's the > > procedure? > > Hi Ulrich, > > perhaps the best way forward would be for you to post an incremental patch > on top of either the sh-sci branch or renesas-next-20130618 tag of > my renesas tree on kernel.org. I'm not sure where we stand on this series at the moment. Should I pull v3, has Olof already pulled it, or should I wait for an update? Arnd ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-19 15:08 ` Arnd Bergmann 0 siblings, 0 replies; 30+ messages in thread From: Arnd Bergmann @ 2013-06-19 15:08 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 19 June 2013, Simon Horman wrote: > > This is of course trivially fixed, but I have completely lost track of > > the transmogrifications this patch has been subjected to. What's the > > procedure? > > Hi Ulrich, > > perhaps the best way forward would be for you to post an incremental patch > on top of either the sh-sci branch or renesas-next-20130618 tag of > my renesas tree on kernel.org. I'm not sure where we stand on this series at the moment. Should I pull v3, has Olof already pulled it, or should I wait for an update? Arnd ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-19 15:08 ` Arnd Bergmann @ 2013-06-20 12:08 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-20 12:08 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 19, 2013 at 05:08:46PM +0200, Arnd Bergmann wrote: > On Wednesday 19 June 2013, Simon Horman wrote: > > > This is of course trivially fixed, but I have completely lost track of > > > the transmogrifications this patch has been subjected to. What's the > > > procedure? > > > > Hi Ulrich, > > > > perhaps the best way forward would be for you to post an incremental patch > > on top of either the sh-sci branch or renesas-next-20130618 tag of > > my renesas tree on kernel.org. > > I'm not sure where we stand on this series at the moment. Should > I pull v3, has Olof already pulled it, or should I wait for an > update? Hi Arnd, my preference is for you to wait for an update. In order to move things forwards I will post a proposed fix shortly. I believe that the warnings are for conditions that can never occur and thus in my patch I will propose initialising the variables that are flagged as being used uninitialised. ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-20 12:08 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-20 12:08 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 19, 2013 at 05:08:46PM +0200, Arnd Bergmann wrote: > On Wednesday 19 June 2013, Simon Horman wrote: > > > This is of course trivially fixed, but I have completely lost track of > > > the transmogrifications this patch has been subjected to. What's the > > > procedure? > > > > Hi Ulrich, > > > > perhaps the best way forward would be for you to post an incremental patch > > on top of either the sh-sci branch or renesas-next-20130618 tag of > > my renesas tree on kernel.org. > > I'm not sure where we stand on this series at the moment. Should > I pull v3, has Olof already pulled it, or should I wait for an > update? Hi Arnd, my preference is for you to wait for an update. In order to move things forwards I will post a proposed fix shortly. I believe that the warnings are for conditions that can never occur and thus in my patch I will propose initialising the variables that are flagged as being used uninitialised. ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 2/2] ARM: shmobile: r8a7790: don't use external clock for SCIFs 2013-06-17 3:38 ` Simon Horman @ 2013-06-17 3:38 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> This is an external component and may or may not be there, while the internal clock always works. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 49de2d5..6531f3d 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -64,10 +64,18 @@ void __init r8a7790_pinmux_init(void) [index] = { \ SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ .scbrr_algo_id = SCBRR_ALGO_2, \ - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ + .scscr = SCSCR_RE | SCSCR_TE, \ } -enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 }; +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + HSCIF0, HSCIF1 }; static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ @@ -78,6 +86,8 @@ static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */ + HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */ }; static inline void r8a7790_register_scif(int idx) @@ -115,6 +125,8 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_scif(SCIFA2); r8a7790_register_scif(SCIF0); r8a7790_register_scif(SCIF1); + r8a7790_register_scif(HSCIF0); + r8a7790_register_scif(HSCIF1); r8a7790_register_irqc(0); } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 2/2] ARM: shmobile: r8a7790: don't use external clock for SCIFs @ 2013-06-17 3:38 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 3:38 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> This is an external component and may or may not be there, while the internal clock always works. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 49de2d5..6531f3d 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -64,10 +64,18 @@ void __init r8a7790_pinmux_init(void) [index] = { \ SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ .scbrr_algo_id = SCBRR_ALGO_2, \ - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ + .scscr = SCSCR_RE | SCSCR_TE, \ } -enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 }; +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + HSCIF0, HSCIF1 }; static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ @@ -78,6 +86,8 @@ static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */ + HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */ }; static inline void r8a7790_register_scif(int idx) @@ -115,6 +125,8 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_scif(SCIFA2); r8a7790_register_scif(SCIF0); r8a7790_register_scif(SCIF1); + r8a7790_register_scif(HSCIF0); + r8a7790_register_scif(HSCIF1); r8a7790_register_irqc(0); } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 2013-06-17 3:38 ` Simon Horman @ 2013-06-17 8:59 ` Simon Horman -1 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 8:59 UTC (permalink / raw) To: linux-arm-kernel Sorry, please ignore this, I realised that I have made an error when applying the second patch. On Mon, Jun 17, 2013 at 12:38:45PM +0900, Simon Horman wrote: > Hi Olof, Hi Arnd, > > As requested the first patch is now includes an ack from Greg Kroah-Hartman. > > I have included the r8a7790 change in this patch as it > depends on the first change in the pull-request but nothing else. > > This pull request will cause some conflicts though I believe all > of them are not difficult to resolve. The renesas-next-20130613 tag in > my tree illustrates how I have handled the conflicts with > both changes already in arm-soc and changes I intend to send > pull requests for in the near future. > > The following changes since commit c7788792a5e7b0d5d7f96d0766b4cb6112d47d75: > > Linux 3.10-rc2 (2013-05-20 14:37:38 -0700) > > are available in the git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-sh-sci-for-v3.11 > > for you to fetch changes up to fe0b1091e41e0acae8ddf2da2a5a36b6867ff012: > > ARM: shmobile: r8a7790: don't use external clock for SCIFs (2013-06-17 12:17:48 +0900) > > ---------------------------------------------------------------- > Renesas sh-sci updates for v3.11 > > HSCIF support by Ulrich Hecht. > > ---------------------------------------------------------------- > Ulrich Hecht (2): > serial: sh-sci: HSCIF support > ARM: shmobile: r8a7790: don't use external clock for SCIFs > > arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++- > drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++--- > include/linux/serial_sci.h | 12 +++- > include/uapi/linux/serial_core.h | 3 + > 4 files changed, 120 insertions(+), 13 deletions(-) > ^ permalink raw reply [flat|nested] 30+ messages in thread
* [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 @ 2013-06-17 8:59 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 8:59 UTC (permalink / raw) To: linux-arm-kernel Sorry, please ignore this, I realised that I have made an error when applying the second patch. On Mon, Jun 17, 2013 at 12:38:45PM +0900, Simon Horman wrote: > Hi Olof, Hi Arnd, > > As requested the first patch is now includes an ack from Greg Kroah-Hartman. > > I have included the r8a7790 change in this patch as it > depends on the first change in the pull-request but nothing else. > > This pull request will cause some conflicts though I believe all > of them are not difficult to resolve. The renesas-next-20130613 tag in > my tree illustrates how I have handled the conflicts with > both changes already in arm-soc and changes I intend to send > pull requests for in the near future. > > The following changes since commit c7788792a5e7b0d5d7f96d0766b4cb6112d47d75: > > Linux 3.10-rc2 (2013-05-20 14:37:38 -0700) > > are available in the git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-sh-sci-for-v3.11 > > for you to fetch changes up to fe0b1091e41e0acae8ddf2da2a5a36b6867ff012: > > ARM: shmobile: r8a7790: don't use external clock for SCIFs (2013-06-17 12:17:48 +0900) > > ---------------------------------------------------------------- > Renesas sh-sci updates for v3.11 > > HSCIF support by Ulrich Hecht. > > ---------------------------------------------------------------- > Ulrich Hecht (2): > serial: sh-sci: HSCIF support > ARM: shmobile: r8a7790: don't use external clock for SCIFs > > arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++- > drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++--- > include/linux/serial_sci.h | 12 +++- > include/uapi/linux/serial_core.h | 3 + > 4 files changed, 120 insertions(+), 13 deletions(-) > ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 0/2] serial: sh-sci: HSCIF support @ 2013-06-17 2:42 Simon Horman 2013-06-17 2:42 ` Simon Horman 0 siblings, 1 reply; 30+ messages in thread From: Simon Horman @ 2013-06-17 2:42 UTC (permalink / raw) To: linux-arm-kernel Hi Greg, Hi All, this short series adds HSCIF support to the sh-sci driver and enhances the r8a7790 SoC to not use external clocks for SCIF. I have included these two patches in a single series as the second patch has a build-time dependency on the first. Greg, would it be possible for you to review at least the first patch and if it is ok either: * Ack the first patch so I can merge it through the renesas tree or; * Take both patches, I have supplied Acks. In the case of the latter I can supply a pull request if you like. Ulrich Hecht (2): serial: sh-sci: HSCIF support ARM: shmobile: r8a7790: don't use external clock for SCIFs arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++- include/uapi/linux/serial_core.h | 3 + 4 files changed, 120 insertions(+), 13 deletions(-) -- 1.7.10.4 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-17 2:42 [PATCH 0/2] serial: sh-sci: HSCIF support Simon Horman 2013-06-17 2:42 ` Simon Horman @ 2013-06-17 2:42 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 2:42 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err = 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id = SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type = PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 2:42 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 2:42 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err == 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type == PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata = - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 2:42 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-17 2:42 UTC (permalink / raw) To: Greg Kroah-Hartman, linux-serial, linux-sh Cc: Jiri Slaby, Ulrich Hecht, Magnus Damm, Paul Mundt, Arnd Bergmann, Olof Johansson, linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 +++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err == 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type == PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata = - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-17 2:42 ` Simon Horman (?) @ 2013-06-17 3:00 ` Greg Kroah-Hartman -1 siblings, 0 replies; 30+ messages in thread From: Greg Kroah-Hartman @ 2013-06-17 3:00 UTC (permalink / raw) To: Simon Horman Cc: linux-serial, linux-sh, Jiri Slaby, Ulrich Hecht, Magnus Damm, Paul Mundt, Arnd Bergmann, Olof Johansson, linux-arm-kernel On Mon, Jun 17, 2013 at 11:42:13AM +0900, Simon Horman wrote: > From: Ulrich Hecht <ulrich.hecht@gmail.com> > > Adds support for "High Speed Serial Communications Interface with FIFO", > essentially a SCIF with 128-byte FIFOs and more accurate baud rate > generator. > > Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> > Acked-by: Paul Mundt <lethal@linux-sh.org> > Acked-by: Simon Horman <horms+renesas@verge.net.au> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 3:00 ` Greg Kroah-Hartman 0 siblings, 0 replies; 30+ messages in thread From: Greg Kroah-Hartman @ 2013-06-17 2:59 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jun 17, 2013 at 11:42:13AM +0900, Simon Horman wrote: > From: Ulrich Hecht <ulrich.hecht@gmail.com> > > Adds support for "High Speed Serial Communications Interface with FIFO", > essentially a SCIF with 128-byte FIFOs and more accurate baud rate > generator. > > Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> > Acked-by: Paul Mundt <lethal@linux-sh.org> > Acked-by: Simon Horman <horms+renesas@verge.net.au> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-17 3:00 ` Greg Kroah-Hartman 0 siblings, 0 replies; 30+ messages in thread From: Greg Kroah-Hartman @ 2013-06-17 3:00 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jun 17, 2013 at 11:42:13AM +0900, Simon Horman wrote: > From: Ulrich Hecht <ulrich.hecht@gmail.com> > > Adds support for "High Speed Serial Communications Interface with FIFO", > essentially a SCIF with 128-byte FIFOs and more accurate baud rate > generator. > > Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> > Acked-by: Paul Mundt <lethal@linux-sh.org> > Acked-by: Simon Horman <horms+renesas@verge.net.au> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ^ permalink raw reply [flat|nested] 30+ messages in thread
* [GIT PULL 0/2] Renesas sh-sci updates for v3.11 @ 2013-06-13 7:00 Simon Horman 2013-06-13 7:00 ` Simon Horman 0 siblings, 1 reply; 30+ messages in thread From: Simon Horman @ 2013-06-13 7:00 UTC (permalink / raw) To: linux-arm-kernel Hi Olof, Hi Arnd, I have included the r8a7790 change in this patch as it depends on the first change in the pull-request but nothing else. This pull request will cause some conflicts though I believe all of them are not difficult to resolve. The renesas-next-20130613 tag in my tree illustrates how I have handled the conflicts with both changes already in arm-soc and changes I intend to send pull requests for in the near future. The following changes since commit c7788792a5e7b0d5d7f96d0766b4cb6112d47d75: Linux 3.10-rc2 (2013-05-20 14:37:38 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git sh-sci for you to fetch changes up to d1b6515e2eeaac48eff47bf4987f106a982e14f3: ARM: shmobile: r8a7790: don't use external clock for SCIFs (2013-06-11 17:24:08 +0900) ---------------------------------------------------------------- Renesas sh-sci updates for v3.11 HSCIF support by Ulrich Hecht. ---------------------------------------------------------------- Ulrich Hecht (2): serial: sh-sci: HSCIF support ARM: shmobile: r8a7790: don't use external clock for SCIFs arch/arm/mach-shmobile/setup-r8a7790.c | 16 +++++- drivers/tty/serial/sh-sci.c | 102 ++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++- include/uapi/linux/serial_core.h | 3 + 4 files changed, 120 insertions(+), 13 deletions(-) ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-13 7:00 [GIT PULL 0/2] Renesas sh-sci updates for v3.11 Simon Horman @ 2013-06-13 7:00 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-13 7:00 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 ++++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err = 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id = SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type = PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.8.2.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-13 7:00 ` Simon Horman 0 siblings, 0 replies; 30+ messages in thread From: Simon Horman @ 2013-06-13 7:00 UTC (permalink / raw) To: linux-arm-kernel From: Ulrich Hecht <ulrich.hecht@gmail.com> Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> --- drivers/tty/serial/sh-sci.c | 102 ++++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1564186..931d6c3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err == 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type == PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata = - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763ad..d340497 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7..26eee07 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- 1.8.2.1 ^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 1/2] serial: sh-sci: HSCIF support 2013-06-13 7:00 ` Simon Horman @ 2013-06-15 1:03 ` Olof Johansson -1 siblings, 0 replies; 30+ messages in thread From: Olof Johansson @ 2013-06-15 1:03 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jun 13, 2013 at 04:00:53PM +0900, Simon Horman wrote: > From: Ulrich Hecht <ulrich.hecht@gmail.com> > > Adds support for "High Speed Serial Communications Interface with FIFO", > essentially a SCIF with 128-byte FIFOs and more accurate baud rate > generator. > > Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> > Acked-by: Paul Mundt <lethal@linux-sh.org> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au> I think this should go through Greg K-H, or at least get an Acked-by from him. Especially since it adds and allocates new UAPI IDs. -Olof ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/2] serial: sh-sci: HSCIF support @ 2013-06-15 1:03 ` Olof Johansson 0 siblings, 0 replies; 30+ messages in thread From: Olof Johansson @ 2013-06-15 1:03 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jun 13, 2013 at 04:00:53PM +0900, Simon Horman wrote: > From: Ulrich Hecht <ulrich.hecht@gmail.com> > > Adds support for "High Speed Serial Communications Interface with FIFO", > essentially a SCIF with 128-byte FIFOs and more accurate baud rate > generator. > > Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> > Acked-by: Paul Mundt <lethal@linux-sh.org> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au> I think this should go through Greg K-H, or at least get an Acked-by from him. Especially since it adds and allocates new UAPI IDs. -Olof ^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2013-06-20 12:08 UTC | newest] Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-06-17 3:38 [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 Simon Horman 2013-06-17 3:38 ` Simon Horman 2013-06-17 3:38 ` [PATCH 1/2] serial: sh-sci: HSCIF support Simon Horman 2013-06-17 3:38 ` Simon Horman 2013-06-17 12:54 ` Arnd Bergmann 2013-06-17 12:54 ` Arnd Bergmann 2013-06-18 1:19 ` Simon Horman 2013-06-18 1:19 ` Simon Horman 2013-06-19 8:46 ` Ulrich Hecht 2013-06-19 8:46 ` Ulrich Hecht 2013-06-19 12:33 ` Simon Horman 2013-06-19 12:33 ` Simon Horman 2013-06-19 15:08 ` Arnd Bergmann 2013-06-19 15:08 ` Arnd Bergmann 2013-06-20 12:08 ` Simon Horman 2013-06-20 12:08 ` Simon Horman 2013-06-17 3:38 ` [PATCH 2/2] ARM: shmobile: r8a7790: don't use external clock for SCIFs Simon Horman 2013-06-17 3:38 ` Simon Horman 2013-06-17 8:59 ` [GIT PULL 0/2 v2] Renesas sh-sci updates for v3.11 Simon Horman 2013-06-17 8:59 ` Simon Horman -- strict thread matches above, loose matches on Subject: below -- 2013-06-17 2:42 [PATCH 0/2] serial: sh-sci: HSCIF support Simon Horman 2013-06-17 2:42 ` [PATCH 1/2] " Simon Horman 2013-06-17 2:42 ` Simon Horman 2013-06-17 2:42 ` Simon Horman 2013-06-17 3:00 ` Greg Kroah-Hartman 2013-06-17 2:59 ` Greg Kroah-Hartman 2013-06-17 3:00 ` Greg Kroah-Hartman 2013-06-13 7:00 [GIT PULL 0/2] Renesas sh-sci updates for v3.11 Simon Horman 2013-06-13 7:00 ` [PATCH 1/2] serial: sh-sci: HSCIF support Simon Horman 2013-06-13 7:00 ` Simon Horman 2013-06-15 1:03 ` Olof Johansson 2013-06-15 1:03 ` Olof Johansson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.