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 UART2. 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, 3 or 4. 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 Müllner <christophm30@gmail.com>
Change-Id: Iafe1320e77ab006c121f8d52745d54cef68a48c7
This commit is contained in:
Christoph Müllner 2019-04-19 14:16:27 +02:00
parent f476e63f7a
commit 220c33a2c5
4 changed files with 69 additions and 2 deletions

View File

@ -78,7 +78,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
coreboot_serial.baud,
&console);
#else
console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
console_16550_register(rockchip_get_uart_base(), PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE, &console);
#endif

View File

@ -146,6 +146,8 @@ extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
extern const mmap_region_t plat_rk_mmap[];
uint32_t rockchip_get_uart_base(void);
#endif /* __ASSEMBLY__ */
/******************************************************************************

View File

@ -28,6 +28,12 @@ static struct gpio_info *poweroff_gpio;
static struct gpio_info suspend_gpio[10];
uint32_t suspend_gpio_cnt;
static struct apio_info *suspend_apio;
static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
uint32_t rockchip_get_uart_base(void)
{
return rk_uart_base;
}
#if COREBOOT
static int dt_process_fdt(void *blob)
@ -42,6 +48,63 @@ void *plat_get_fdt(void)
return &fdt_buffer[0];
}
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;
#ifdef UART3_BASE
case 3:
uart_base = UART3_BASE;
break;
#endif
#ifdef UART4_BASE
case 4:
uart_base = UART4_BASE;
break;
#endif
default:
return;
}
rk_uart_base = uart_base;
}
static int dt_process_fdt(void *blob)
{
void *fdt = plat_get_fdt();
@ -51,6 +114,8 @@ static int dt_process_fdt(void *blob)
if (ret < 0)
return ret;
plat_rockchip_dt_process_fdt_uart(fdt);
return 0;
}
#endif

View File

@ -65,7 +65,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
coreboot_serial.baud,
&console);
#else
console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
console_16550_register(rockchip_get_uart_base(), PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE, &console);
#endif
VERBOSE("sp_min_setup\n");