@@ -99,6 +99,7 @@
#define UART_OSAMP 0x14
#define OSAMP_DEFAULT_DIVISOR 16
#define OSAMP_DIVISORS_MASK 0x3F3F3F3F
+#define OSAMP_MAX_DIVISOR 63
#define MVEBU_NR_UARTS 2
@@ -479,18 +480,60 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
return -EOPNOTSUPP;
/*
- * The baudrate is derived from the UART clock thanks to two divisors:
- * > D ("baud generator"): can divide the clock from 2 to 2^10 - 1.
- * > M ("fractional divisor"): allows a better accuracy for
- * baudrates higher than 230400.
+ * The baudrate is derived from the UART clock thanks to divisors:
+ * > d1 * d2 ("TBG divisors"): can divide only TBG clock from 1 to 6
+ * > D ("baud generator"): can divide the clock from 1 to 1023
+ * > M ("fractional divisor"): allows a better accuracy (from 1 to 63)
*
- * As the derivation of M is rather complicated, the code sticks to its
- * default value (x16) when all the prescalers are zeroed, and only
- * makes use of D to configure the desired baudrate.
+ * Exact formulas for calculating baudrate:
+ *
+ * with default x16 scheme:
+ * baudrate = xtal / (d * 16)
+ * baudrate = tbg / (d1 * d2 * d * 16)
+ *
+ * with fractional divisor:
+ * baudrate = 10 * xtal / (d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+ * baudrate = 10 * tbg / (d1*d2 * d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+ *
+ * Oversampling value:
+ * osamp = (m1 << 0) | (m2 << 8) | (m3 << 16) | (m4 << 24);
+ *
+ * Where m1 controls number of clock cycles per bit for bits 1,2,3;
+ * m2 for bits 4,5,6; m3 for bits 7,8 and m4 for bits 9,10.
+ *
+ * To simplify baudrate setup set all the M prescalers to the same
+ * value. For baudrates 9600 Bd and higher, it is enough to use the
+ * default (x16) divisor or fractional divisor with M = 63, so there
+ * is no need to use real fractional support (where the M prescalers
+ * are not equal).
+ *
+ * When all the M prescalers are zeroed then default (x16) divisor is
+ * used. Default x16 scheme is more stable than M (fractional divisor),
+ * so use M only when D divisor is not enough to derive baudrate.
+ *
+ * Member port->uartclk is either xtal clock rate or TBG clock rate
+ * divided by (d1 * d2). So d1 and d2 are already set by the UART clock
+ * driver (and UART driver itself cannot change them). Moreover they are
+ * shared between both UARTs.
*/
+
m_divisor = OSAMP_DEFAULT_DIVISOR;
d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
+ if (d_divisor > BRDV_BAUD_MAX) {
+ /*
+ * Experiments show that small M divisors are unstable.
+ * Use maximal possible M = 63 and calculate D divisor.
+ */
+ m_divisor = OSAMP_MAX_DIVISOR;
+ d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
+ }
+
+ if (d_divisor < 1)
+ d_divisor = 1;
+ else if (d_divisor > BRDV_BAUD_MAX)
+ d_divisor = BRDV_BAUD_MAX;
+
spin_lock_irqsave(&mvebu_uart_lock, flags);
brdv = readl(port->membase + UART_BRDV);
brdv &= ~BRDV_BAUD_MASK;
@@ -500,6 +543,9 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
osamp = readl(port->membase + UART_OSAMP);
osamp &= ~OSAMP_DIVISORS_MASK;
+ if (m_divisor != OSAMP_DEFAULT_DIVISOR)
+ osamp |= (m_divisor << 0) | (m_divisor << 8) |
+ (m_divisor << 16) | (m_divisor << 24);
writel(osamp, port->membase + UART_OSAMP);
return 0;
@@ -529,14 +575,16 @@ static void mvebu_uart_set_termios(struct uart_port *port,
port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
/*
- * Maximal divisor is 1023 * 16 when using default (x16) scheme.
- * Maximum achievable frequency with simple baudrate divisor is 230400.
- * Since the error per bit frame would be of more than 15%, achieving
- * higher frequencies would require to implement the fractional divisor
- * feature.
+ * Maximal divisor is 1023 and maximal fractional divisor is 63. And
+ * experiments show that baudrates above 1/80 of parent clock rate are
+ * not stable. So disallow baudrates above 1/80 of the parent clock
+ * rate. If port->uartclk is not available, then
+ * mvebu_uart_baud_rate_set() fails, so values min_baud and max_baud
+ * in this case do not matter.
*/
- min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
- max_baud = 230400;
+ min_baud = DIV_ROUND_UP(port->uartclk, BRDV_BAUD_MAX *
+ OSAMP_MAX_DIVISOR);
+ max_baud = port->uartclk / 80;
baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
if (mvebu_uart_baud_rate_set(port, baud)) {
@@ -1395,14 +1443,14 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
* Calculate the smallest TBG d1 and d2 divisors that
* still can provide 9600 baudrate.
*/
- d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+ d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
BRDV_BAUD_MAX);
if (d1 < 1)
d1 = 1;
else if (d1 > CLK_TBG_DIV1_MAX)
d1 = CLK_TBG_DIV1_MAX;
- d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+ d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
BRDV_BAUD_MAX * d1);
if (d2 < 1)
d2 = 1;
@@ -1417,8 +1465,7 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
}
/* Skip clock source which cannot provide 9600 baudrate */
- if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 *
- d2)
+ if (rate > 9600 * OSAMP_MAX_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
continue;
/*