| @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 145 unmodified lines |
| 146 | 146 | [SCRFDR] = sci_reg_invalid, |
| 147 | 147 | [SCSPTR] = sci_reg_invalid, |
| 148 | 148 | [SCLSR] = sci_reg_invalid, |
| 149 | + [HSSRR] = sci_reg_invalid, |
| 149 | 150 | }, |
| 150 | 151 | |
| 151 | 152 | /* |
| @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines |
| 165 | 166 | [SCRFDR] = sci_reg_invalid, |
| 166 | 167 | [SCSPTR] = sci_reg_invalid, |
| 167 | 168 | [SCLSR] = sci_reg_invalid, |
| 169 | + [HSSRR] = sci_reg_invalid, |
| 168 | 170 | }, |
| 169 | 171 | |
| 170 | 172 | /* |
| @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines |
| 183 | 185 | [SCRFDR] = sci_reg_invalid, |
| 184 | 186 | [SCSPTR] = sci_reg_invalid, |
| 185 | 187 | [SCLSR] = sci_reg_invalid, |
| 188 | + [HSSRR] = sci_reg_invalid, |
| 186 | 189 | }, |
| 187 | 190 | |
| 188 | 191 | /* |
| @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines |
| 201 | 204 | [SCRFDR] = { 0x3c, 16 }, |
| 202 | 205 | [SCSPTR] = sci_reg_invalid, |
| 203 | 206 | [SCLSR] = sci_reg_invalid, |
| 207 | + [HSSRR] = sci_reg_invalid, |
| 204 | 208 | }, |
| 205 | 209 | |
| 206 | 210 | /* |
| @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines |
| 220 | 224 | [SCRFDR] = sci_reg_invalid, |
| 221 | 225 | [SCSPTR] = { 0x20, 16 }, |
| 222 | 226 | [SCLSR] = { 0x24, 16 }, |
| 227 | + [HSSRR] = sci_reg_invalid, |
| 223 | 228 | }, |
| 224 | 229 | |
| 225 | 230 | /* |
| @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines |
| 238 | 243 | [SCRFDR] = sci_reg_invalid, |
| 239 | 244 | [SCSPTR] = sci_reg_invalid, |
| 240 | 245 | [SCLSR] = sci_reg_invalid, |
| 246 | + [HSSRR] = sci_reg_invalid, |
| 241 | 247 | }, |
| 242 | 248 | |
| 243 | 249 | /* |
| @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 12 unmodified lines |
| 256 | 262 | [SCRFDR] = sci_reg_invalid, |
| 257 | 263 | [SCSPTR] = { 0x20, 16 }, |
| 258 | 264 | [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 }, |
| 259 | 285 | }, |
| 260 | 286 | |
| 261 | 287 | /* |
| @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines |
| 275 | 301 | [SCRFDR] = sci_reg_invalid, |
| 276 | 302 | [SCSPTR] = sci_reg_invalid, |
| 277 | 303 | [SCLSR] = { 0x24, 16 }, |
| 304 | + [HSSRR] = sci_reg_invalid, |
| 278 | 305 | }, |
| 279 | 306 | |
| 280 | 307 | /* |
| @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines |
| 294 | 321 | [SCRFDR] = { 0x20, 16 }, |
| 295 | 322 | [SCSPTR] = { 0x24, 16 }, |
| 296 | 323 | [SCLSR] = { 0x28, 16 }, |
| 324 | + [HSSRR] = sci_reg_invalid, |
| 297 | 325 | }, |
| 298 | 326 | |
| 299 | 327 | /* |
| @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { · 13 unmodified lines |
| 313 | 341 | [SCRFDR] = sci_reg_invalid, |
| 314 | 342 | [SCSPTR] = sci_reg_invalid, |
| 315 | 343 | [SCLSR] = sci_reg_invalid, |
| 344 | + [HSSRR] = sci_reg_invalid, |
| 316 | 345 | }, |
| 317 | 346 | }; |
| 318 | 347 | |
| @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) · 55 unmodified lines |
| 374 | 403 | */ |
| 375 | 404 | cfg->regtype = SCIx_SH4_SCIF_REGTYPE; |
| 376 | 405 | break; |
| 406 | + case PORT_HSCIF: |
| 407 | + cfg->regtype = SCIx_HSCIF_REGTYPE; |
| 408 | + break; |
| 377 | 409 | default: |
| 378 | 410 | printk(KERN_ERR "Can't probe register map for given port\n"); |
| 379 | 411 | return -EINVAL; |
| @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, · 1418 unmodified lines |
| 1798 | 1830 | return ((freq + 16 * bps) / (32 * bps) - 1); |
| 1799 | 1831 | } |
| 1800 | 1832 | |
| 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 | + |
| 1801 | 1869 | static void sci_reset(struct uart_port *port) |
| 1802 | 1870 | { |
| 1803 | 1871 | struct plat_sci_reg *reg; |
| @@ -1819,8 +1887,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, · 15 unmodified lines |
| 1819 | 1887 | { |
| 1820 | 1888 | struct sci_port *s = to_sci_port(port); |
| 1821 | 1889 | struct plat_sci_reg *reg; |
| 1822 | | − unsigned int baud, smr_val, max_baud, cks; |
| 1890 | + unsigned int baud, smr_val, max_baud, cks = 0; |
| 1823 | 1891 | int t = -1; |
| 1892 | + unsigned int srr = 15; |
| 1824 | 1893 | |
| 1825 | 1894 | /* |
| 1826 | 1895 | * 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 |
| 1833 | 1902 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; |
| 1834 | 1903 | |
| 1835 | 1904 | 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 | + } |
| 1838 | 1916 | |
| 1839 | 1917 | sci_port_enable(s); |
| 1840 | 1918 | |
| @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, · 12 unmodified lines |
| 1853 | 1931 | |
| 1854 | 1932 | uart_update_timeout(port, termios->c_cflag, baud); |
| 1855 | 1933 | |
| 1856 | | − for (cks = 0; t >= 256 && cks <= 3; cks++) |
| 1857 | | − t >>= 2; |
| 1858 | | − |
| 1859 | 1934 | dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", |
| 1860 | 1935 | __func__, smr_val, cks, t, s->cfg->scscr); |
| 1861 | 1936 | |
| 1862 | 1937 | if (t >= 0) { |
| 1863 | 1938 | serial_port_out(port, SCSMR, (smr_val & ~3) | cks); |
| 1864 | 1939 | 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); |
| 1865 | 1943 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ |
| 1866 | 1944 | } else |
| 1867 | 1945 | serial_port_out(port, SCSMR, smr_val); |
| @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) · 79 unmodified lines |
| 1947 | 2025 | return "scifa"; |
| 1948 | 2026 | case PORT_SCIFB: |
| 1949 | 2027 | return "scifb"; |
| 2028 | + case PORT_HSCIF: |
| 2029 | + return "hscif"; |
| 1950 | 2030 | } |
| 1951 | 2031 | |
| 1952 | 2032 | return NULL; |
| @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) · 7 unmodified lines |
| 1960 | 2040 | * from platform resource data at such a time that ports begin to |
| 1961 | 2041 | * behave more erratically. |
| 1962 | 2042 | */ |
| 1963 | | − return 64; |
| 2043 | + if (port->type == PORT_HSCIF) |
| 2044 | + return 96; |
| 2045 | + else |
| 2046 | + return 64; |
| 1964 | 2047 | } |
| 1965 | 2048 | |
| 1966 | 2049 | 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 |
| 2085 | 2168 | case PORT_SCIFB: |
| 2086 | 2169 | port->fifosize = 256; |
| 2087 | 2170 | break; |
| 2171 | + case PORT_HSCIF: |
| 2172 | + port->fifosize = 128; |
| 2173 | + break; |
| 2088 | 2174 | case PORT_SCIFA: |
| 2089 | 2175 | port->fifosize = 64; |
| 2090 | 2176 | break; |
| @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) · 234 unmodified lines |
| 2325 | 2411 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
| 2326 | 2412 | |
| 2327 | 2413 | static char banner[] __initdata = |
| 2328 | | − KERN_INFO "SuperH SCI(F) driver initialized\n"; |
| 2414 | + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; |
| 2329 | 2415 | |
| 2330 | 2416 | static struct uart_driver sci_uart_driver = { |
| 2331 | 2417 | .owner = THIS_MODULE, |
| @@ -2484,4 +2570,4 @@ module_exit(sci_exit); · 152 unmodified lines |
| 2484 | 2570 | MODULE_LICENSE("GPL"); |
| 2485 | 2571 | MODULE_ALIAS("platform:sh-sci"); |
| 2486 | 2572 | MODULE_AUTHOR("Paul Mundt"); |
| 2487 | | −MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); |
| 2573 | +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); |