/* master clock
* Baud rate = ---------------
* bgen*(bdiv+1)
- *
- * master clock = 50MHz (I think?)
- * bdiv remains at default (reset) 15
- *
- * Simplify RHS to base/bgen, where base == master/16
*/
- long base = XDFUART_BASECLK;
long baud = gd->baudrate;
- long bgen = base / baud;
- long base_err = base - (bgen*baud);
- long mod_bgen = bgen + (base_err >= 0 ? 1 : -1);
- long mod_err = base - (mod_bgen*baud);
- /* you'd think there'd be an abs() macro somewhere in include/... */
- mod_err = mod_err < 0 ? -mod_err : mod_err;
- base_err = base_err < 0 ? -base_err : base_err;
+ /* Variables to vary. */
+ unsigned int bdiv, bgen;
- bgen = mod_err < base_err ? mod_bgen : bgen;
+ /* Calculation results. */
+ long calc_baud = 0;
+ unsigned int calc_bauderror;
- xdfuart_writel(BAUDDIV,XDFUART_BDIV); /* Ensure it's 15 */
+ /* Find acceptable values for baud generation. */
+ for (bdiv = 4; bdiv < 255; bdiv++) {
+
+ bgen = XDFUART_MASTER / (baud * (bdiv + 1));
+ if (bgen < 2 || bgen > 65535)
+ continue;
+
+ calc_baud = XDFUART_MASTER / (bgen * (bdiv + 1));
+
+ /* Use first calculated baudrate with an acceptable
+ * (<3%) error.
+ */
+ if (baud > calc_baud)
+ calc_bauderror = baud - calc_baud;
+ else
+ calc_bauderror = calc_baud - baud;
+ if ( ((calc_bauderror * 100) / baud) < 3 )
+ break;
+
+ }
+
+ xdfuart_writel(BAUDDIV,bdiv);
xdfuart_writel(BAUDGEN,bgen);
}
#if defined(CONFIG_UART0)
# define UART_ID 0
# define UART_BASE XPSS_UART0_BASEADDR
+# define XDFUART_MASTER XPAR_XUARTPSS_0_CLOCK_HZ
#elif defined(CONFIG_UART1)
# define UART_ID 1
# define UART_BASE XPSS_UART1_BASEADDR
+# define XDFUART_MASTER XPAR_XUARTPSS_1_CLOCK_HZ
#else
# error "Need to configure a UART (0 or 1)"
#endif
-/* Some clock/baud constants */
-#define XDFUART_MASTER 50000000L /* Master clock source for UART */
-#define XDFUART_BDIV 15 /* Default/reset BDIV value */
-#define XDFUART_BASECLK 3125000L /* master/(bdiv+1) */
-
/* UART register offsets */
#define XDFUART_CR_OFFSET 0x00 /* Control Register [8:0] */
#define XDFUART_MR_OFFSET 0x04 /* Mode Register [10:0] */