[2/3] riscv: sivive_u: Add dummy serial clock and aliases entry for uart
diff mbox series

Message ID 1563543645-20804-2-git-send-email-linux@roeck-us.net
State New
Headers show
Series
  • Untitled series #147911
Related show

Commit Message

Guenter Roeck July 19, 2019, 1:40 p.m. UTC
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>
---
 hw/riscv/sifive_u.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

Comments

Alistair Francis July 26, 2019, 8:16 p.m. UTC | #1
On Fri, Jul 19, 2019 at 6:41 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> 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>

Alistair

> ---
>  hw/riscv/sifive_u.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 0657046..5a221c6 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;
> --
> 2.7.4
>
>

Patch
diff mbox series

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 0657046..5a221c6 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;