lib: utils: Add fdt_parse_sifive_uart_node() function
authorAnup Patel <anup.patel@wdc.com>
Sat, 25 Apr 2020 13:20:37 +0000 (18:50 +0530)
committerAnup Patel <anup@brainfault.org>
Fri, 1 May 2020 04:10:31 +0000 (09:40 +0530)
We add fdt_parse_sifive_uart_node() function which will allow
us to parse a particular DT node as SiFive UART node. This will
be useful in parsing the node pointed by stdout-path.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
include/sbi_utils/fdt/fdt_helper.h
lib/utils/fdt/fdt_helper.c

index a4ad1c1..3a15aca 100644 (file)
@@ -37,6 +37,9 @@ int fdt_find_match(void *fdt, const struct fdt_match *match_table,
 int fdt_get_node_addr_size(void *fdt, int node, unsigned long *addr,
                           unsigned long *size);
 
+int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset,
+                              struct platform_uart_data *uart);
+
 int fdt_parse_uart8250_node(void *fdt, int nodeoffset,
                            struct platform_uart_data *uart);
 
index 8fe4ace..3186f64 100644 (file)
 #define DEFAULT_UART_REG_SHIFT         0
 #define DEFAULT_UART_REG_IO_WIDTH      1
 
+#define DEFAULT_SIFIVE_UART_FREQ               0
+#define DEFAULT_SIFIVE_UART_BAUD               115200
+#define DEFAULT_SIFIVE_UART_REG_SHIFT          0
+#define DEFAULT_SIFIVE_UART_REG_IO_WIDTH       4
+
 const struct fdt_match *fdt_match_node(void *fdt, int nodeoff,
                                       const struct fdt_match *match_table)
 {
@@ -99,6 +104,44 @@ int fdt_get_node_addr_size(void *fdt, int node, unsigned long *addr,
        return 0;
 }
 
+int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset,
+                              struct platform_uart_data *uart)
+{
+       int len, rc;
+       const fdt32_t *val;
+       unsigned long reg_addr, reg_size;
+
+       if (nodeoffset < 0 || !uart || !fdt)
+               return SBI_ENODEV;
+
+       rc = fdt_get_node_addr_size(fdt, nodeoffset, &reg_addr, &reg_size);
+       if (rc < 0 || !reg_addr || !reg_size)
+               return SBI_ENODEV;
+       uart->addr = reg_addr;
+
+       /**
+        * UART address is mandaotry. clock-frequency and current-speed
+        * may not be present. Don't return error.
+        */
+       val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "clock-frequency", &len);
+       if (len > 0 && val)
+               uart->freq = fdt32_to_cpu(*val);
+       else
+               uart->freq = DEFAULT_SIFIVE_UART_FREQ;
+
+       val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "current-speed", &len);
+       if (len > 0 && val)
+               uart->baud = fdt32_to_cpu(*val);
+       else
+               uart->baud = DEFAULT_SIFIVE_UART_BAUD;
+
+       /* For SiFive UART, the reg-shift and reg-io-width are fixed .*/
+       uart->reg_shift = DEFAULT_SIFIVE_UART_REG_SHIFT;
+       uart->reg_io_width = DEFAULT_SIFIVE_UART_REG_IO_WIDTH;
+
+       return 0;
+}
+
 int fdt_parse_uart8250_node(void *fdt, int nodeoffset,
                            struct platform_uart_data *uart)
 {