Tegra: introduce plat_enable_console()

This patch introduces the 'plat_enable_console' handler to allow
the platform to enable the right console. Tegra194 platform supports
multiple console, while all the previous platforms support only one
console.

For Tegra194 platforms, the previous bootloader checks the platform
config and sets the uart-id boot parameter, to 0xFE. On seeing this
boot parameter, the platform port uses the proper memory aperture
base address to communicate with the SPE. This functionality is
currently protected by a platform macro, ENABLE_CONSOLE_SPE.

Change-Id: I3972aa376d66bd10d868495f561dc08fe32fcb10
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
This commit is contained in:
Varun Wadekar 2019-08-21 14:01:31 -07:00
parent f0222c23fd
commit 117dbe6ce9
8 changed files with 127 additions and 56 deletions

View File

@ -129,10 +129,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end, console_base;
uint32_t console_clock;
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
int32_t ret;
static console_16550_t console;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@ -182,31 +180,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
}
/*
* Reference clock used by the FPGAs is a lot slower.
* Enable console for the platform
*/
if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
/*
* Get the base address of the UART controller to be used for the
* console
*/
console_base = plat_get_console_from_id(plat_params->uart_id);
if (console_base != 0U) {
/*
* Configure the UART port to be used as the console
*/
(void)console_16550_register(console_base,
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&console);
console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
plat_enable_console(plat_params->uart_id);
/*
* The previous bootloader passes the base address of the shared memory

View File

@ -143,6 +143,12 @@
#define TEGRA_RNG1_BASE U(0x03AE0000)
#define RNG1_MUTEX_WATCHDOG_NS_LIMIT U(0xFE0)
/*******************************************************************************
* Tegra hardware synchronization primitives for the SPE engine
******************************************************************************/
#define TEGRA_AON_HSP_SM_6_7_BASE U(0x0c190000)
#define TEGRA_CONSOLE_SPE_BASE (TEGRA_AON_HSP_SM_6_7_BASE + U(0x8000))
/*******************************************************************************
* Tegra micro-seconds timer constants
******************************************************************************/

View File

@ -76,7 +76,7 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
/* Declarations for plat_setup.c */
const mmap_region_t *plat_get_mmio_map(void);
uint32_t plat_get_console_from_id(int32_t id);
void plat_enable_console(int32_t id);
void plat_gic_setup(void);
struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);

View File

@ -6,9 +6,11 @@
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <drivers/console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
/* sets of MMIO ranges setup */
@ -85,14 +87,30 @@ static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = {
};
/*******************************************************************************
* Retrieve the UART controller base to be used as the console
* Enable console corresponding to the console ID
******************************************************************************/
uint32_t plat_get_console_from_id(int id)
void plat_enable_console(int32_t id)
{
if (id > TEGRA132_MAX_UART_PORTS)
return 0;
static console_16550_t uart_console;
uint32_t console_clock;
return tegra132_uart_addresses[id];
if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
/*
* Reference clock used by the FPGAs is a lot slower.
*/
if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
(void)console_16550_register(tegra132_uart_addresses[id],
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
/*******************************************************************************

View File

@ -141,19 +141,30 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
};
/*******************************************************************************
* Retrieve the UART controller base to be used as the console
* Enable console corresponding to the console ID
******************************************************************************/
uint32_t plat_get_console_from_id(int32_t id)
void plat_enable_console(int32_t id)
{
uint32_t ret;
static console_16550_t uart_console;
uint32_t console_clock;
if (id > TEGRA186_MAX_UART_PORTS) {
ret = 0;
} else {
ret = tegra186_uart_addresses[id];
if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) {
/*
* Reference clock used by the FPGAs is a lot slower.
*/
if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
(void)console_16550_register(tegra186_uart_addresses[id],
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
return ret;
}
/*******************************************************************************

View File

@ -21,12 +21,16 @@
#include <mce.h>
#include <mce_private.h>
#include <plat/common/platform.h>
#include <spe.h>
#include <tegra_def.h>
#include <tegra_mc_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
/* ID for spe-console */
#define TEGRA_CONSOLE_SPE_ID 0xFE
/*******************************************************************************
* The Tegra power domain tree has a single system level power domain i.e. a
* single root node. The first entry in the power domain descriptor specifies
@ -68,12 +72,14 @@ static const mmap_region_t tegra_mmap[] = {
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
#if !ENABLE_CONSOLE_SPE
MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
#endif
MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
@ -84,6 +90,10 @@ static const mmap_region_t tegra_mmap[] = {
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
#if ENABLE_CONSOLE_SPE
MAP_REGION_FLAT(TEGRA_AON_HSP_SM_6_7_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
#endif
MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
@ -120,6 +130,7 @@ uint32_t plat_get_syscnt_freq2(void)
return 31250000;
}
#if !ENABLE_CONSOLE_SPE
/*******************************************************************************
* Maximum supported UART controllers
******************************************************************************/
@ -138,21 +149,47 @@ static uint32_t tegra194_uart_addresses[TEGRA194_MAX_UART_PORTS + 1] = {
TEGRA_UARTF_BASE,
TEGRA_UARTG_BASE
};
#endif
/*******************************************************************************
* Retrieve the UART controller base to be used as the console
* Enable console corresponding to the console ID
******************************************************************************/
uint32_t plat_get_console_from_id(int32_t id)
void plat_enable_console(int32_t id)
{
uint32_t ret;
uint32_t console_clock = 0U;
if (id > TEGRA194_MAX_UART_PORTS) {
ret = 0;
} else {
ret = tegra194_uart_addresses[id];
#if ENABLE_CONSOLE_SPE
static console_spe_t spe_console;
if (id == TEGRA_CONSOLE_SPE_ID) {
(void)console_spe_register(TEGRA_CONSOLE_SPE_BASE,
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&spe_console);
console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#else
static console_16550_t uart_console;
return ret;
if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) {
/*
* Reference clock used by the FPGAs is a lot slower.
*/
if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
(void)console_16550_register(tegra194_uart_addresses[id],
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#endif
}
/*******************************************************************************

View File

@ -5,6 +5,9 @@
#
# platform configs
ENABLE_CONSOLE_SPE := 0
$(eval $(call add_define,ENABLE_CONSOLE_SPE))
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 0
$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
@ -42,7 +45,7 @@ $(eval $(call add_define,MAX_MMAP_REGIONS))
# platform files
PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
${COMMON_DIR}/drivers/smmu/smmu.c \
@ -57,3 +60,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
${SOC_DIR}/plat_sip_calls.c \
${SOC_DIR}/plat_smmu.c \
${SOC_DIR}/plat_trampoline.S
ifeq (${ENABLE_CONSOLE_SPE},1)
BL31_SOURCES += ${COMMON_DIR}/drivers/spe/shared_console.S
endif

View File

@ -114,14 +114,30 @@ static uint32_t tegra210_uart_addresses[TEGRA210_MAX_UART_PORTS + 1] = {
};
/*******************************************************************************
* Retrieve the UART controller base to be used as the console
* Enable console corresponding to the console ID
******************************************************************************/
uint32_t plat_get_console_from_id(int id)
void plat_enable_console(int32_t id)
{
if (id > TEGRA210_MAX_UART_PORTS)
return 0;
static console_16550_t uart_console;
uint32_t console_clock;
return tegra210_uart_addresses[id];
if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) {
/*
* Reference clock used by the FPGAs is a lot slower.
*/
if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
(void)console_16550_register(tegra210_uart_addresses[id],
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
/*******************************************************************************