diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 2a5f256184..6e5d81ce34 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -11,7 +11,10 @@ /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */ #include +/* For get_bus_freq() */ +#include #include +#include #include #include #include @@ -149,21 +152,24 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, 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); + /* 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); + writel(divider, ®s->pl011_ibrd); + writel(fraction, ®s->pl011_fbrd); + } pl011_set_line_control(regs); /* Finally, enable the UART */ @@ -337,17 +343,28 @@ static const struct udevice_id pl01x_serial_id[] ={ {} }; +#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");