summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-04-30 11:40:25 +0200
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2019-04-30 11:40:25 +0200
commit36299ed972f2bb79b4f536816c83828556d79818 (patch)
treeb8fba44d9f7dfb14077bc2b45f7a7d3689833198
parentd71e6d83612df896774ec4c03d49500312d2c324 (diff)
rockchip: Allow console device to be set by DTB.
Currently the compile-time constant PLAT_RK_UART_BASE defines which UART is used as console device. E.g. on RK3399 it is set to UART0. That means, that a single bl31 image can not be used for two boards, which just differ on the UART console. This patch addresses this limitation by parsing the "stdout-path" property from the "chosen" node in the DTB. The expected property string is expected to have the form "serialN:XXX", with N being either 0, 1, 2 or 3. When the property is found, it will be used to override PLAT_RK_UART_BASE. Tested on RK3399-Q7, with a stdout-path of "serial0:115200n8". Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
-rw-r--r--plat/rockchip/common/bl31_plat_setup.c14
-rw-r--r--plat/rockchip/common/include/plat_private.h1
-rw-r--r--plat/rockchip/common/params_setup.c51
3 files changed, 62 insertions, 4 deletions
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 0a41f216..0afc5272 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -38,6 +38,7 @@ unsigned long __RO_END__;
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
+static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
@@ -65,6 +66,11 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
#endif
}
+void rockchip_set_uart_base(uint32_t uart_base)
+{
+ rk_uart_base = uart_base;
+}
+
/*******************************************************************************
* Perform any BL3-1 early platform setup. Here is an opportunity to copy
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
@@ -79,7 +85,10 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
- console_init(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
+ /* there may have some board specific data */
+ params_early_setup(plat_params_from_bl2);
+
+ console_init(rk_uart_base, PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE);
INFO("%s: from_bl2 %p plat_params_from_bl2 %p",
@@ -98,9 +107,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
bl32_ep_info = *from_bl2->bl32_ep_info;
bl33_ep_info = *from_bl2->bl33_ep_info;
- /* there may have some board specific data */
- params_early_setup(plat_params_from_bl2);
-
INFO("bl33_ep_info.pc: %p\n", (void*)(bl33_ep_info.pc));
plat_rockchip_pmusram_prepare();
}
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 867d9add..0df8c02d 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -119,6 +119,7 @@ extern const mmap_region_t plat_rk_mmap[];
void rockchip_plat_sram_mmu_el3(void);
void plat_rockchip_mem_prepare(void);
+void rockchip_set_uart_base(uint32_t uart_base);
#endif /* __ASSEMBLY__ */
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index 3943c1f0..ad5588af 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -117,6 +117,56 @@ void dt_relocate_pmu_firmware(void)
INFO("%s: relocated PMU firmware\n", __func__);
}
+static void plat_rockchip_dt_process_fdt_uart(void *fdt)
+{
+ const char *path_name = "/chosen";
+ const char *prop_name = "stdout-path";
+ int node_offset;
+ int stdout_path_len;
+ const char *stdout_path;
+ char serial_char;
+ int serial_no;
+ uint32_t uart_base;
+
+ node_offset = fdt_path_offset(fdt, path_name);
+ if (node_offset < 0)
+ return;
+
+ stdout_path = fdt_getprop(fdt, node_offset, prop_name,
+ &stdout_path_len);
+ if (stdout_path == NULL)
+ return;
+
+ /*
+ * We expect something like:
+ * "serial0:...""
+ */
+ if (strncmp("serial", stdout_path, 6) != 0)
+ return;
+
+ serial_char = stdout_path[6];
+ serial_no = serial_char - '0';
+
+ switch (serial_no) {
+ case 0:
+ uart_base = UART0_BASE;
+ break;
+ case 1:
+ uart_base = UART1_BASE;
+ break;
+ case 2:
+ uart_base = UART2_BASE;
+ break;
+ case 3:
+ uart_base = UART3_BASE;
+ break;
+ default:
+ return;
+ }
+
+ rockchip_set_uart_base(uart_base);
+}
+
bool dt_board_is_compatible(const char *board)
{
void *fdt = plat_get_fdt();
@@ -135,6 +185,7 @@ static int dt_process_fdt(void* blob)
}
INFO("%s: opened FDT at %p\n", __func__, blob);
+ plat_rockchip_dt_process_fdt_uart(fdt);
dt_relocate_pmu_firmware();
dt_get_reset_gpio();