aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2019-07-19 06:40:44 -0700
committerPalmer Dabbelt <palmer@sifive.com>2019-09-17 08:42:42 -0700
commit44e6dcd30a10e5b5d70cbf1bc248b146eabcec03 (patch)
treef7cda0a3252e19937f08223662db382fe982a87e /hw
parent0f8d4462498afd2f071cb5c837750b703a48ba18 (diff)
downloadqemu-44e6dcd30a10e5b5d70cbf1bc248b146eabcec03.zip
qemu-44e6dcd30a10e5b5d70cbf1bc248b146eabcec03.tar.gz
qemu-44e6dcd30a10e5b5d70cbf1bc248b146eabcec03.tar.bz2
riscv: sivive_u: Add dummy serial clock and aliases entry for uart
The riscv uart needs valid clocks. This requires a refereence to the clock node. Since the SOC clock is not emulated by qemu, add a reference to a fixed clock instead. The clock-frequency entry in the uart node does not seem to be necessary, so drop it. In addition to a reference to the clock, the driver also needs an aliases entry for the serial node. Add it as well. Without this patch, the serial driver fails to instantiate with the following error message. sifive-serial 10013000.uart: unable to find controller clock sifive-serial: probe of 10013000.uart failed with error -2 when trying to boot Linux. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/riscv/sifive_u.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 32167d0..8313f26 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -76,6 +76,7 @@ static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
char *nodename;
char ethclk_names[] = "pclk\0hclk\0tx_clk";
uint32_t plic_phandle, ethclk_phandle, phandle = 1;
+ uint32_t uartclk_phandle;
fdt = s->fdt = create_device_tree(&s->fdt_size);
if (!fdt) {
@@ -226,6 +227,17 @@ static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
g_free(nodename);
+ uartclk_phandle = phandle++;
+ nodename = g_strdup_printf("/soc/uartclk");
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+ qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+ qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", uartclk_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", uartclk_phandle);
+ uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
+ g_free(nodename);
+
nodename = g_strdup_printf("/soc/uart@%lx",
(long)memmap[SIFIVE_U_UART0].base);
qemu_fdt_add_subnode(fdt, nodename);
@@ -233,8 +245,7 @@ static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[SIFIVE_U_UART0].base,
0x0, memmap[SIFIVE_U_UART0].size);
- qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
- SIFIVE_U_CLOCK_FREQ / 2);
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks", uartclk_phandle);
qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
@@ -243,6 +254,10 @@ static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
if (cmdline) {
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
}
+
+ qemu_fdt_add_subnode(fdt, "/aliases");
+ qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
+
g_free(nodename);
return fdt;