From 36299ed972f2bb79b4f536816c83828556d79818 Mon Sep 17 00:00:00 2001 From: Christoph Muellner Date: Tue, 30 Apr 2019 11:40:25 +0200 Subject: 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 --- plat/rockchip/common/bl31_plat_setup.c | 14 +++++--- plat/rockchip/common/include/plat_private.h | 1 + plat/rockchip/common/params_setup.c | 51 +++++++++++++++++++++++++++++ 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(); -- cgit v1.2.3