feat(arm_fpga): write UART baud base clock frequency into DTB

Since we now autodetect the actual system frequency, which is also used
as the base for the UART baudrate generation, we should update the value
currently hard-coded in the DT. Otherwise Linux will reprogram the
divider using a potentially wrong base rate, which breaks the UART
output.

Find the DT node referenced by the UART node as the clock rate, and set
the "clock-frequency" property in that node to the detected system
frequency. This will let Linux reprogram the divider to the same value,
preserving the actual baudrate.

Change-Id: Ib5a936849f2198577b86509f032751d5386ed2f8
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Andre Przywara 2021-09-01 11:59:57 +01:00
parent d850169c9c
commit 422b44fb56
1 changed files with 46 additions and 1 deletions

View File

@ -21,6 +21,7 @@
#include <platform_def.h>
static entry_point_info_t bl33_image_ep_info;
static unsigned int system_freq;
volatile uint32_t secondary_core_spinlock;
uintptr_t plat_get_ns_image_entrypoint(void)
@ -206,7 +207,49 @@ static unsigned int fpga_get_system_frequency(void)
unsigned int plat_get_syscnt_freq2(void)
{
return fpga_get_system_frequency();
if (system_freq == 0U) {
system_freq = fpga_get_system_frequency();
}
return system_freq;
}
static void fpga_dtb_update_clock(void *fdt, unsigned int freq)
{
uint32_t freq_dtb = fdt32_to_cpu(freq);
uint32_t phandle;
int node, err;
node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011");
if (node < 0) {
WARN("%s(): No PL011 DT node found\n", __func__);
return;
}
err = fdt_read_uint32(fdt, node, "clocks", &phandle);
if (err != 0) {
WARN("Cannot find clocks property\n");
return;
}
node = fdt_node_offset_by_phandle(fdt, phandle);
if (node < 0) {
WARN("Cannot get phandle\n");
return;
}
err = fdt_setprop_inplace(fdt, node,
"clock-frequency",
&freq_dtb,
sizeof(freq_dtb));
if (err < 0) {
WARN("Could not update DT baud clock frequency\n");
return;
}
}
#define CMDLINE_SIGNATURE "CMD:"
@ -318,6 +361,8 @@ static void fpga_prepare_dtb(void)
}
}
fpga_dtb_update_clock(fdt, system_freq);
/* Check whether we support the SPE PMU. Remove the DT node if not. */
if (!spe_supported()) {
int node = fdt_node_offset_by_compatible(fdt, 0,