aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-11-18 05:12:26 -0500
committerGeert Uytterhoeven <geert+renesas@glider.be>2015-12-17 05:18:57 -0500
commit6af27bf299e2d66ade25f278f0c13d51007e9879 (patch)
tree37d63eba2c48ff4e24e323c681629af371f22116 /drivers/tty
parentf4998e55b8987428aa86de02c934fb6e0988d9a3 (diff)
serial: sh-sci: Add support for optional external (H)SCK input
Add support for using the SCIx clock pin "(H)SCK" as an external clock input on (H)SCI(F), providing the sampling clock. Note that this feature is not yet supported on the select SCIFA variants that also have it (e.g. sh7723, sh7724, and r8a7740). On (H)SCIF variants with an External Baud Rate Generator (BRG), the BRG Clock Select Register must be configured for the external clock. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sh-sci.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index fa3fd876105b..229162481fd6 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -79,6 +79,7 @@ enum {
79 79
80enum SCI_CLKS { 80enum SCI_CLKS {
81 SCI_FCK, /* Functional Clock */ 81 SCI_FCK, /* Functional Clock */
82 SCI_SCK, /* Optional External Clock */
82 SCI_NUM_CLKS 83 SCI_NUM_CLKS
83}; 84};
84 85
@@ -1924,6 +1925,39 @@ static void sci_shutdown(struct uart_port *port)
1924 sci_free_irq(s); 1925 sci_free_irq(s);
1925} 1926}
1926 1927
1928static int sci_sck_calc(struct sci_port *s, unsigned int bps,
1929 unsigned int *srr)
1930{
1931 unsigned long freq = s->clk_rates[SCI_SCK];
1932 unsigned int min_sr, max_sr, sr;
1933 int err, min_err = INT_MAX;
1934
1935 if (s->sampling_rate) {
1936 /* SCI(F) has a fixed sampling rate */
1937 min_sr = max_sr = s->sampling_rate / 2;
1938 } else {
1939 /* HSCIF has a variable 1/(8..32) sampling rate */
1940 min_sr = 8;
1941 max_sr = 32;
1942 }
1943
1944 for (sr = max_sr; sr >= min_sr; sr--) {
1945 err = DIV_ROUND_CLOSEST(freq, sr) - bps;
1946 if (abs(err) >= abs(min_err))
1947 continue;
1948
1949 min_err = err;
1950 *srr = sr - 1;
1951
1952 if (!err)
1953 break;
1954 }
1955
1956 dev_dbg(s->port.dev, "SCK: %u%+d bps using SR %u\n", bps, min_err,
1957 *srr + 1);
1958 return min_err;
1959}
1960
1927/* calculate sample rate, BRR, and clock select */ 1961/* calculate sample rate, BRR, and clock select */
1928static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, 1962static int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
1929 unsigned int *brr, unsigned int *srr, 1963 unsigned int *brr, unsigned int *srr,
@@ -2019,7 +2053,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
2019 struct ktermios *old) 2053 struct ktermios *old)
2020{ 2054{
2021 unsigned int baud, smr_val = 0, scr_val = 0, i; 2055 unsigned int baud, smr_val = 0, scr_val = 0, i;
2022 unsigned int brr = 255, cks = 0, srr = 15; 2056 unsigned int brr = 255, cks = 0, srr = 15, sccks = 0;
2023 unsigned int brr1 = 255, cks1 = 0, srr1 = 15; 2057 unsigned int brr1 = 255, cks1 = 0, srr1 = 15;
2024 struct sci_port *s = to_sci_port(port); 2058 struct sci_port *s = to_sci_port(port);
2025 const struct plat_sci_reg *reg; 2059 const struct plat_sci_reg *reg;
@@ -2062,10 +2096,26 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
2062 * that gives us the smallest deviation from the desired baud rate. 2096 * that gives us the smallest deviation from the desired baud rate.
2063 */ 2097 */
2064 2098
2099 /* Optional Undivided External Clock */
2100 if (s->clk_rates[SCI_SCK] && port->type != PORT_SCIFA &&
2101 port->type != PORT_SCIFB) {
2102 err = sci_sck_calc(s, baud, &srr1);
2103 if (abs(err) < abs(min_err)) {
2104 best_clk = SCI_SCK;
2105 scr_val = SCSCR_CKE1;
2106 sccks = SCCKS_CKS;
2107 min_err = err;
2108 srr = srr1;
2109 if (!err)
2110 goto done;
2111 }
2112 }
2113
2065 /* Divided Functional Clock using standard Bit Rate Register */ 2114 /* Divided Functional Clock using standard Bit Rate Register */
2066 err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1); 2115 err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1);
2067 if (abs(err) < abs(min_err)) { 2116 if (abs(err) < abs(min_err)) {
2068 best_clk = SCI_FCK; 2117 best_clk = SCI_FCK;
2118 scr_val = 0;
2069 min_err = err; 2119 min_err = err;
2070 brr = brr1; 2120 brr = brr1;
2071 srr = srr1; 2121 srr = srr1;
@@ -2079,14 +2129,23 @@ done:
2079 2129
2080 sci_port_enable(s); 2130 sci_port_enable(s);
2081 2131
2132 /*
2133 * Program the optional External Baud Rate Generator (BRG) first.
2134 * It controls the mux to select (H)SCK or frequency divided clock.
2135 */
2136 if (best_clk >= 0 && sci_getreg(port, SCCKS)->size)
2137 serial_port_out(port, SCCKS, sccks);
2138
2082 sci_reset(port); 2139 sci_reset(port);
2083 2140
2084 uart_update_timeout(port, termios->c_cflag, baud); 2141 uart_update_timeout(port, termios->c_cflag, baud);
2085 2142
2086 if (best_clk >= 0) { 2143 if (best_clk >= 0) {
2087 smr_val |= cks; 2144 smr_val |= cks;
2088 dev_dbg(port->dev, "SMR 0x%x BRR %u SRR %u\n", smr_val, brr, 2145 dev_dbg(port->dev,
2089 srr); 2146 "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x SRR %u\n",
2147 scr_val, smr_val, brr, sccks, srr);
2148 serial_port_out(port, SCSCR, scr_val);
2090 serial_port_out(port, SCSMR, smr_val); 2149 serial_port_out(port, SCSMR, smr_val);
2091 serial_port_out(port, SCBRR, brr); 2150 serial_port_out(port, SCBRR, brr);
2092 if (sci_getreg(port, HSSRR)->size) 2151 if (sci_getreg(port, HSSRR)->size)
@@ -2322,10 +2381,14 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
2322{ 2381{
2323 const char *clk_names[] = { 2382 const char *clk_names[] = {
2324 [SCI_FCK] = "fck", 2383 [SCI_FCK] = "fck",
2384 [SCI_SCK] = "sck",
2325 }; 2385 };
2326 struct clk *clk; 2386 struct clk *clk;
2327 unsigned int i; 2387 unsigned int i;
2328 2388
2389 if (sci_port->cfg->type == PORT_HSCIF)
2390 clk_names[SCI_SCK] = "hsck";
2391
2329 for (i = 0; i < SCI_NUM_CLKS; i++) { 2392 for (i = 0; i < SCI_NUM_CLKS; i++) {
2330 clk = devm_clk_get(dev, clk_names[i]); 2393 clk = devm_clk_get(dev, clk_names[i]);
2331 if (PTR_ERR(clk) == -EPROBE_DEFER) 2394 if (PTR_ERR(clk) == -EPROBE_DEFER)