Commit 41bacb597e6a3bb9e0ba514d4280aa0af5391f43
1 parent
157736a9ee
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
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>
Showing 1 changed file with 38 additions and 3 deletions Side-by-side Diff
drivers/serial/serial_uniphier.c
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | |
8 | 8 | #include <common.h> |
9 | 9 | #include <dm.h> |
10 | +#include <linux/bug.h> | |
10 | 11 | #include <linux/io.h> |
11 | 12 | #include <linux/serial_reg.h> |
12 | 13 | #include <linux/sizes.h> |
13 | 14 | |
14 | 15 | |
... | ... | @@ -87,11 +88,34 @@ |
87 | 88 | return !(readl(&port->lsr) & UART_LSR_THRE); |
88 | 89 | } |
89 | 90 | |
91 | +/* | |
92 | + * SPL does not have enough memory footprint for the clock driver. | |
93 | + * Hardcode clock frequency for each SoC. | |
94 | + */ | |
95 | +struct uniphier_serial_clk_data { | |
96 | + const char *compatible; | |
97 | + unsigned int clk_rate; | |
98 | +}; | |
99 | + | |
100 | +static const struct uniphier_serial_clk_data uniphier_serial_clk_data[] = { | |
101 | + { .compatible = "socionext,uniphier-ld4", .clk_rate = 36864000 }, | |
102 | + { .compatible = "socionext,uniphier-pro4", .clk_rate = 73728000 }, | |
103 | + { .compatible = "socionext,uniphier-sld8", .clk_rate = 80000000 }, | |
104 | + { .compatible = "socionext,uniphier-pro5", .clk_rate = 73728000 }, | |
105 | + { .compatible = "socionext,uniphier-pxs2", .clk_rate = 88888888 }, | |
106 | + { .compatible = "socionext,uniphier-ld6b", .clk_rate = 88888888 }, | |
107 | + { .compatible = "socionext,uniphier-ld11", .clk_rate = 58823529 }, | |
108 | + { .compatible = "socionext,uniphier-ld20", .clk_rate = 58823529 }, | |
109 | + { .compatible = "socionext,uniphier-pxs3", .clk_rate = 58823529 }, | |
110 | + { /* sentinel */ }, | |
111 | +}; | |
112 | + | |
90 | 113 | static int uniphier_serial_probe(struct udevice *dev) |
91 | 114 | { |
92 | - DECLARE_GLOBAL_DATA_PTR; | |
93 | 115 | struct uniphier_serial_priv *priv = dev_get_priv(dev); |
94 | 116 | struct uniphier_serial __iomem *port; |
117 | + const struct uniphier_serial_clk_data *clk_data; | |
118 | + ofnode root_node; | |
95 | 119 | fdt_addr_t base; |
96 | 120 | u32 tmp; |
97 | 121 | |
... | ... | @@ -105,8 +129,19 @@ |
105 | 129 | |
106 | 130 | priv->membase = port; |
107 | 131 | |
108 | - priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), | |
109 | - "clock-frequency", 0); | |
132 | + root_node = ofnode_path("/"); | |
133 | + clk_data = uniphier_serial_clk_data; | |
134 | + while (clk_data->compatible) { | |
135 | + if (ofnode_device_is_compatible(root_node, | |
136 | + clk_data->compatible)) | |
137 | + break; | |
138 | + clk_data++; | |
139 | + } | |
140 | + | |
141 | + if (WARN_ON(!clk_data->compatible)) | |
142 | + return -ENOTSUPP; | |
143 | + | |
144 | + priv->uartclk = clk_data->clk_rate; | |
110 | 145 | |
111 | 146 | tmp = readl(&port->lcr_mcr); |
112 | 147 | tmp &= ~LCR_MASK; |