/* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
#include <common.h>
+/* For get_bus_freq() */
+#include <clock_legacy.h>
#include <dm.h>
+#include <clk.h>
#include <errno.h>
#include <watchdog.h>
#include <asm/io.h>
unsigned int remainder;
unsigned int fraction;
- /*
- * Set baud rate
- *
- * IBRD = UART_CLK / (16 * BAUD_RATE)
- * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE)))
- * / (16 * BAUD_RATE))
- */
- temp = 16 * baudrate;
- divider = clock / temp;
- remainder = clock % temp;
- temp = (8 * remainder) / baudrate;
- fraction = (temp >> 1) + (temp & 1);
-
- writel(divider, ®s->pl011_ibrd);
- writel(fraction, ®s->pl011_fbrd);
+ /* Without a valid clock rate we cannot set up the baudrate. */
+ if (clock) {
+ /*
+ * Set baud rate
+ *
+ * IBRD = UART_CLK / (16 * BAUD_RATE)
+ * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE)))
+ * / (16 * BAUD_RATE))
+ */
+ temp = 16 * baudrate;
+ divider = clock / temp;
+ remainder = clock % temp;
+ temp = (8 * remainder) / baudrate;
+ fraction = (temp >> 1) + (temp & 1);
+
+ writel(divider, ®s->pl011_ibrd);
+ writel(fraction, ®s->pl011_fbrd);
+ }
pl011_set_line_control(regs);
/* Finally, enable the UART */
{}
};
+#ifndef CONFIG_PL011_CLOCK
+#define CONFIG_PL011_CLOCK 0
+#endif
+
int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
{
struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
+ struct clk clk;
fdt_addr_t addr;
+ int ret;
addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
plat->base = addr;
- plat->clock = dev_read_u32_default(dev, "clock", 1);
+ plat->clock = dev_read_u32_default(dev, "clock", CONFIG_PL011_CLOCK);
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (!ret) {
+ clk_enable(&clk);
+ plat->clock = clk_get_rate(&clk);
+ }
plat->type = dev_get_driver_data(dev);
plat->skip_init = dev_read_bool(dev, "skip-init");