History

Merge tag 'renesas-sh-sci-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/late

Renesas sh-sci updates for v3.11 HSCIF support by Ulrich Hecht. * tag 'renesas-sh-sci-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: serial: sh-sci: Initialise variables before access in sci_set_termios() ARM: shmobile: r8a7790: don't use external clock for SCIFs ARM: shmobile: r8a7790: HSCIF support serial: sh-sci: HSCIF support

Arnd Bergmann committed 13 years ago

Commit 0ad578e2 parents 4022acd d4759de4 files · +121 −14Browse files

Unified · Split

4 files
  1. arch/arm/mach-shmobile/setup-r8a7790.c +14 −2
  2. drivers/tty/serial/sh-sci.c +95 −9
  3. include/linux/serial_sci.h +9 −3
  4. include/uapi/linux/serial_core.h +3 −0
arch/arm/mach-shmobile/setup-r8a7790.c+14−2
@@ -98,10 +98,18 @@ void __init r8a7790_pinmux_init(void) · 97 unmodified lines
9898 [index] = { \
9999 SCIF_COMMON(PORT_SCIF, baseaddr, irq), \
100100 .scbrr_algo_id = SCBRR_ALGO_2, \
101− .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \
101+ .scscr = SCSCR_RE | SCSCR_TE, \
102102 }
103103
104−enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 };
104+#define HSCIF_DATA(index, baseaddr, irq) \
105+[index] = { \
106+ SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \
107+ .scbrr_algo_id = SCBRR_ALGO_6, \
108+ .scscr = SCSCR_RE | SCSCR_TE, \
109+}
110+
111+enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
112+ HSCIF0, HSCIF1 };
105113
106114 static struct plat_sci_port scif[] __initdata = {
107115 SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
@@ -112,6 +120,8 @@ static struct plat_sci_port scif[] __initdata = { · 4 unmodified lines
112120 SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */
113121 SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */
114122 SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */
123+ HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */
124+ HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */
115125 };
116126
117127 static inline void r8a7790_register_scif(int idx)
@@ -149,6 +159,8 @@ void __init r8a7790_add_standard_devices(void) · 31 unmodified lines
149159 r8a7790_register_scif(SCIFA2);
150160 r8a7790_register_scif(SCIF0);
151161 r8a7790_register_scif(SCIF1);
162+ r8a7790_register_scif(HSCIF0);
163+ r8a7790_register_scif(HSCIF1);
152164 r8a7790_register_irqc(0);
153165 }
154166
drivers/tty/serial/sh-sci.c+95−9
@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 145 unmodified lines
146146 [SCRFDR] = sci_reg_invalid,
147147 [SCSPTR] = sci_reg_invalid,
148148 [SCLSR] = sci_reg_invalid,
149+ [HSSRR] = sci_reg_invalid,
149150 },
150151
151152 /*
@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines
165166 [SCRFDR] = sci_reg_invalid,
166167 [SCSPTR] = sci_reg_invalid,
167168 [SCLSR] = sci_reg_invalid,
169+ [HSSRR] = sci_reg_invalid,
168170 },
169171
170172 /*
@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines
183185 [SCRFDR] = sci_reg_invalid,
184186 [SCSPTR] = sci_reg_invalid,
185187 [SCLSR] = sci_reg_invalid,
188+ [HSSRR] = sci_reg_invalid,
186189 },
187190
188191 /*
@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines
201204 [SCRFDR] = { 0x3c, 16 },
202205 [SCSPTR] = sci_reg_invalid,
203206 [SCLSR] = sci_reg_invalid,
207+ [HSSRR] = sci_reg_invalid,
204208 },
205209
206210 /*
@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines
220224 [SCRFDR] = sci_reg_invalid,
221225 [SCSPTR] = { 0x20, 16 },
222226 [SCLSR] = { 0x24, 16 },
227+ [HSSRR] = sci_reg_invalid,
223228 },
224229
225230 /*
@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines
238243 [SCRFDR] = sci_reg_invalid,
239244 [SCSPTR] = sci_reg_invalid,
240245 [SCLSR] = sci_reg_invalid,
246+ [HSSRR] = sci_reg_invalid,
241247 },
242248
243249 /*
@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines
256262 [SCRFDR] = sci_reg_invalid,
257263 [SCSPTR] = { 0x20, 16 },
258264 [SCLSR] = { 0x24, 16 },
265+ [HSSRR] = sci_reg_invalid,
266+ },
267+
268+ /*
269+ * Common HSCIF definitions.
270+ */
271+ [SCIx_HSCIF_REGTYPE] = {
272+ [SCSMR] = { 0x00, 16 },
273+ [SCBRR] = { 0x04, 8 },
274+ [SCSCR] = { 0x08, 16 },
275+ [SCxTDR] = { 0x0c, 8 },
276+ [SCxSR] = { 0x10, 16 },
277+ [SCxRDR] = { 0x14, 8 },
278+ [SCFCR] = { 0x18, 16 },
279+ [SCFDR] = { 0x1c, 16 },
280+ [SCTFDR] = sci_reg_invalid,
281+ [SCRFDR] = sci_reg_invalid,
282+ [SCSPTR] = { 0x20, 16 },
283+ [SCLSR] = { 0x24, 16 },
284+ [HSSRR] = { 0x40, 16 },
259285 },
260286
261287 /*
@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines
275301 [SCRFDR] = sci_reg_invalid,
276302 [SCSPTR] = sci_reg_invalid,
277303 [SCLSR] = { 0x24, 16 },
304+ [HSSRR] = sci_reg_invalid,
278305 },
279306
280307 /*
@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines
294321 [SCRFDR] = { 0x20, 16 },
295322 [SCSPTR] = { 0x24, 16 },
296323 [SCLSR] = { 0x28, 16 },
324+ [HSSRR] = sci_reg_invalid,
297325 },
298326
299327 /*
@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines
313341 [SCRFDR] = sci_reg_invalid,
314342 [SCSPTR] = sci_reg_invalid,
315343 [SCLSR] = sci_reg_invalid,
344+ [HSSRR] = sci_reg_invalid,
316345 },
317346 };
318347
@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) · 55 unmodified lines
374403 */
375404 cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
376405 break;
406+ case PORT_HSCIF:
407+ cfg->regtype = SCIx_HSCIF_REGTYPE;
408+ break;
377409 default:
378410 printk(KERN_ERR "Can't probe register map for given port\n");
379411 return -EINVAL;
@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, · 1418 unmodified lines
17981830 return ((freq + 16 * bps) / (32 * bps) - 1);
17991831 }
18001832
1833+/* calculate sample rate, BRR, and clock select for HSCIF */
1834+static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
1835+ int *brr, unsigned int *srr,
1836+ unsigned int *cks)
1837+{
1838+ int sr, c, br, err;
1839+ int min_err = 1000; /* 100% */
1840+
1841+ /* Find the combination of sample rate and clock select with the
1842+ smallest deviation from the desired baud rate. */
1843+ for (sr = 8; sr <= 32; sr++) {
1844+ for (c = 0; c <= 3; c++) {
1845+ /* integerized formulas from HSCIF documentation */
1846+ br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1;
1847+ if (br < 0 || br > 255)
1848+ continue;
1849+ err = freq / ((br + 1) * bps * sr *
1850+ (1 << (2 * c + 1)) / 1000) - 1000;
1851+ if (min_err > err) {
1852+ min_err = err;
1853+ *brr = br;
1854+ *srr = sr - 1;
1855+ *cks = c;
1856+ }
1857+ }
1858+ }
1859+
1860+ if (min_err == 1000) {
1861+ WARN_ON(1);
1862+ /* use defaults */
1863+ *brr = 255;
1864+ *srr = 15;
1865+ *cks = 0;
1866+ }
1867+}
1868+
18011869 static void sci_reset(struct uart_port *port)
18021870 {
18031871 struct plat_sci_reg *reg;
@@ -1819,8 +1887,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, · 15 unmodified lines
18191887 {
18201888 struct sci_port *s = to_sci_port(port);
18211889 struct plat_sci_reg *reg;
1822− unsigned int baud, smr_val, max_baud, cks;
1890+ unsigned int baud, smr_val, max_baud, cks = 0;
18231891 int t = -1;
1892+ unsigned int srr = 15;
18241893
18251894 /*
18261895 * 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, · 6 unmodified lines
18331902 max_baud = port->uartclk ? port->uartclk / 16 : 115200;
18341903
18351904 baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
1836− if (likely(baud && port->uartclk))
1837− t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk);
1905+ if (likely(baud && port->uartclk)) {
1906+ if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) {
1907+ sci_baud_calc_hscif(baud, port->uartclk, &t, &srr,
1908+ &cks);
1909+ } else {
1910+ t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud,
1911+ port->uartclk);
1912+ for (cks = 0; t >= 256 && cks <= 3; cks++)
1913+ t >>= 2;
1914+ }
1915+ }
18381916
18391917 sci_port_enable(s);
18401918
@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, · 12 unmodified lines
18531931
18541932 uart_update_timeout(port, termios->c_cflag, baud);
18551933
1856− for (cks = 0; t >= 256 && cks <= 3; cks++)
1857− t >>= 2;
1858−
18591934 dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n",
18601935 __func__, smr_val, cks, t, s->cfg->scscr);
18611936
18621937 if (t >= 0) {
18631938 serial_port_out(port, SCSMR, (smr_val & ~3) | cks);
18641939 serial_port_out(port, SCBRR, t);
1940+ reg = sci_getreg(port, HSSRR);
1941+ if (reg->size)
1942+ serial_port_out(port, HSSRR, srr | HSCIF_SRE);
18651943 udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
18661944 } else
18671945 serial_port_out(port, SCSMR, smr_val);
@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) · 79 unmodified lines
19472025 return "scifa";
19482026 case PORT_SCIFB:
19492027 return "scifb";
2028+ case PORT_HSCIF:
2029+ return "hscif";
19502030 }
19512031
19522032 return NULL;
@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) · 7 unmodified lines
19602040 * from platform resource data at such a time that ports begin to
19612041 * behave more erratically.
19622042 */
1963− return 64;
2043+ if (port->type == PORT_HSCIF)
2044+ return 96;
2045+ else
2046+ return 64;
19642047 }
19652048
19662049 static int sci_remap_port(struct uart_port *port)
@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, · 118 unmodified lines
20852168 case PORT_SCIFB:
20862169 port->fifosize = 256;
20872170 break;
2171+ case PORT_HSCIF:
2172+ port->fifosize = 128;
2173+ break;
20882174 case PORT_SCIFA:
20892175 port->fifosize = 64;
20902176 break;
@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) · 234 unmodified lines
23252411 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
23262412
23272413 static char banner[] __initdata =
2328− KERN_INFO "SuperH SCI(F) driver initialized\n";
2414+ KERN_INFO "SuperH (H)SCI(F) driver initialized\n";
23292415
23302416 static struct uart_driver sci_uart_driver = {
23312417 .owner = THIS_MODULE,
@@ -2484,4 +2570,4 @@ module_exit(sci_exit); · 152 unmodified lines
24842570 MODULE_LICENSE("GPL");
24852571 MODULE_ALIAS("platform:sh-sci");
24862572 MODULE_AUTHOR("Paul Mundt");
2487−MODULE_DESCRIPTION("SuperH SCI(F) serial driver");
2573+MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver");
include/linux/serial_sci.h+9−3
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 #include <linux/sh_dma.h>
66
77 /*
8− * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
8+ * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts)
99 */
1010
1111 #define SCIx_NOT_SUPPORTED (-1)
@@ -16,6 +16,7 @@ enum { · 4 unmodified lines
1616 SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */
1717 SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */
1818 SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */
19+ SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */
1920 };
2021
2122 #define SCSCR_TIE (1 << 7)
@@ -37,7 +38,7 @@ enum { · 15 unmodified lines
3738
3839 #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
3940
40−/* SCxSR SCIF */
41+/* SCxSR SCIF, HSCIF */
4142 #define SCIF_ER 0x0080
4243 #define SCIF_TEND 0x0040
4344 #define SCIF_TDFE 0x0020
@@ -55,6 +56,9 @@ enum { · 11 unmodified lines
5556 #define SCSPTR_SPB2IO (1 << 1)
5657 #define SCSPTR_SPB2DT (1 << 0)
5758
59+/* HSSRR HSCIF */
60+#define HSCIF_SRE 0x8000
61+
5862 /* Offsets into the sci_port->irqs array */
5963 enum {
6064 SCIx_ERI_IRQ,
@@ -90,6 +94,7 @@ enum { · 29 unmodified lines
9094 SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
9195 SCIx_SH4_SCIF_FIFODATA_REGTYPE,
9296 SCIx_SH7705_SCIF_REGTYPE,
97+ SCIx_HSCIF_REGTYPE,
9398
9499 SCIx_NR_REGTYPES,
95100 };
@@ -115,6 +120,7 @@ enum { · 19 unmodified lines
115120 SCSMR, SCBRR, SCSCR, SCxSR,
116121 SCFCR, SCFDR, SCxTDR, SCxRDR,
117122 SCLSR, SCTFDR, SCRFDR, SCSPTR,
123+ HSSRR,
118124
119125 SCIx_NR_REGS,
120126 };
@@ -137,7 +143,7 @@ struct plat_sci_port { · 16 unmodified lines
137143 unsigned long mapbase; /* resource base */
138144 unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
139145 unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */
140− unsigned int type; /* SCI / SCIF / IRDA */
146+ unsigned int type; /* SCI / SCIF / IRDA / HSCIF */
141147 upf_t flags; /* UPF_* flags */
142148 unsigned long capabilities; /* Port features/capabilities */
143149
include/uapi/linux/serial_core.h+3−0
@@ -226,4 +226,7 @@ · 225 unmodified lines
226226 /* Rocketport EXPRESS/INFINITY */
227227 #define PORT_RP2 102
228228
229+/* SH-SCI */
230+#define PORT_HSCIF 103
231+
229232 #endif /* _UAPILINUX_SERIAL_CORE_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t