Renesas sh-sci updates for v3.11
Subsystems (5)
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(-)
PATCH 1/2 serial: sh-sci: HSCIF support
From: Ulrich Hecht <[email protected]>
Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator.
--- 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(-)
drivers/tty/serial/sh-sci.c +94 -8
@@ -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" );
include/linux/serial_sci.h +9 -3
@@ -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 */
include/uapi/linux/serial_core.h +3 -0
@@ -226,4 +226,7 @@/* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 +#endif /* _UAPILINUX_SERIAL_CORE_H */
Signature · 1 line
1.8.2.1
PATCH 1/2 serial: sh-sci: HSCIF support
Quoted 9 lines · Simon Horman
From: Ulrich Hecht <[email protected]>
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 <[email protected]>Acked-by Paul Mundt <[email protected]>Signed-off-by Simon Horman <[email protected]>
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
PATCH 2/2 ARM: shmobile: r8a7790: don't use external clock for SCIFs
In reply to Simon HormanFrom: Ulrich Hecht <[email protected]>
This is an external component and may or may not be there, while the internal clock always works.
--- arch/arm/mach-shmobile/setup-r8a7790.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/arm/mach-shmobile/setup-r8a7790.c +14 -2
@@ -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 ); }
Signature · 1 line
1.8.2.1
PATCH 2/2 ARM: shmobile: r8a7790: don't use external clock for SCIFs
Quoted 7 lines · Simon Horman
From: Ulrich Hecht <[email protected]>
This is an external component and may or may not be there, while the internal clock always works.
Signed-off-by Ulrich Hecht <[email protected]>Signed-off-by Simon Horman <[email protected]>
Looks like this one is appropriate for arm-soc merging, but I'll hold off pulling this branch until the serial driver piece has been acked or dropped (to be merged by Greg).
-Olof
PATCH 2/2 ARM: shmobile: r8a7790: don't use external clock for SCIFs
Quoted 6 lines · Olof Johansson
Quoted 5 lines · Simon Horman
From: Ulrich Hecht <[email protected]>
This is an external component and may or may not be there, while the internal clock always works.
Quoted 6 lines
Quoted 2 lines
Signed-off-by Ulrich Hecht <[email protected]>Signed-off-by Simon Horman <[email protected]>Looks like this one is appropriate for arm-soc merging, but I'll hold off pulling this branch until the serial driver piece has been acked or dropped (to be merged by Greg).
This patch has a build-time dependency on the serial driver piece, which is why I included both patches in the same pull-request.
I'll talk with Greg to see how he would like to move this forwards.