diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-06-19 16:11:45 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-06-23 01:28:15 +0900 |
commit | 41bacb597e6a3bb9e0ba514d4280aa0af5391f43 (patch) | |
tree | 6919d60fed007a5abe0f72866bae67f1e002da6b /drivers/serial/serial_uniphier.c | |
parent | 157736a9eee056ff5accf6d5665132efebf99332 (diff) |
serial: uniphier: set clock rate without clock-frequency property
In Linux, the clock rate of the UART is given by the clock driver.
If you try to follow that in U-Boot, you would end up with adding
more u-boot,dm-pre-reloc properties, and also the clock driver would
be too big for SPL, which is used for UniPhier ARMv7 platform.
The current solution is to add 'clock-frequency' property to the
UART nodes, but it does not exist in the DT files in Linux. I do
not want to let DT diverge for U-Boot.
Check the SoC compatible and set the clock rate according to it.
This will be helpful to sync DT between Linux and U-Boot.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'drivers/serial/serial_uniphier.c')
-rw-r--r-- | drivers/serial/serial_uniphier.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index b06fc00f5f..c7f46e5598 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -7,6 +7,7 @@ #include <common.h> #include <dm.h> +#include <linux/bug.h> #include <linux/io.h> #include <linux/serial_reg.h> #include <linux/sizes.h> @@ -87,11 +88,34 @@ static int uniphier_serial_pending(struct udevice *dev, bool input) return !(readl(&port->lsr) & UART_LSR_THRE); } +/* + * SPL does not have enough memory footprint for the clock driver. + * Hardcode clock frequency for each SoC. + */ +struct uniphier_serial_clk_data { + const char *compatible; + unsigned int clk_rate; +}; + +static const struct uniphier_serial_clk_data uniphier_serial_clk_data[] = { + { .compatible = "socionext,uniphier-ld4", .clk_rate = 36864000 }, + { .compatible = "socionext,uniphier-pro4", .clk_rate = 73728000 }, + { .compatible = "socionext,uniphier-sld8", .clk_rate = 80000000 }, + { .compatible = "socionext,uniphier-pro5", .clk_rate = 73728000 }, + { .compatible = "socionext,uniphier-pxs2", .clk_rate = 88888888 }, + { .compatible = "socionext,uniphier-ld6b", .clk_rate = 88888888 }, + { .compatible = "socionext,uniphier-ld11", .clk_rate = 58823529 }, + { .compatible = "socionext,uniphier-ld20", .clk_rate = 58823529 }, + { .compatible = "socionext,uniphier-pxs3", .clk_rate = 58823529 }, + { /* sentinel */ }, +}; + static int uniphier_serial_probe(struct udevice *dev) { - DECLARE_GLOBAL_DATA_PTR; struct uniphier_serial_priv *priv = dev_get_priv(dev); struct uniphier_serial __iomem *port; + const struct uniphier_serial_clk_data *clk_data; + ofnode root_node; fdt_addr_t base; u32 tmp; @@ -105,8 +129,19 @@ static int uniphier_serial_probe(struct udevice *dev) priv->membase = port; - priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), - "clock-frequency", 0); + root_node = ofnode_path("/"); + clk_data = uniphier_serial_clk_data; + while (clk_data->compatible) { + if (ofnode_device_is_compatible(root_node, + clk_data->compatible)) + break; + clk_data++; + } + + if (WARN_ON(!clk_data->compatible)) + return -ENOTSUPP; + + priv->uartclk = clk_data->clk_rate; tmp = readl(&port->lcr_mcr); tmp &= ~LCR_MASK; |