serial: ns16550: support using pre-loader serial
- pass pre-loader serial configure by rk atags; - it depends on serial aliases to find uart port; - enabled by CONFIG_ROCKCHIP_USING_PRELOADER_SERIAL; Change-Id: I6723cccc5e1f3dac77203b4cc19cdac631f5133b Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
701d3ebca8
commit
064eb49314
|
|
@ -84,6 +84,7 @@ ENTRY(_main)
|
|||
/* set up gd here, outside any C code */
|
||||
mov r9, r0
|
||||
bl board_init_f_init_reserve
|
||||
bl board_init_f_init_serial
|
||||
|
||||
mov r0, #0
|
||||
bl board_init_f
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ ENTRY(_main)
|
|||
/* set up gd here, outside any C code */
|
||||
mov x18, x0
|
||||
bl board_init_f_init_reserve
|
||||
bl board_init_f_init_serial
|
||||
|
||||
mov x0, #0
|
||||
bl board_init_f
|
||||
|
|
|
|||
|
|
@ -519,6 +519,13 @@ config ROCKCHIP_PRELOADER_ATAGS
|
|||
tos, U-Boot, etc. It delivers boot and configure information, shared with pre-loaders
|
||||
and finally ends with U-Boot.
|
||||
|
||||
config ROCKCHIP_PRELOADER_SERIAL
|
||||
bool "Rockchip pre-loader serial"
|
||||
default y if ROCKCHIP_PRELOADER_ATAGS
|
||||
help
|
||||
This enable U-Boot using pre-loader atags serial configure to initialize console.
|
||||
It denpends on serial aliases to find pre-loader serial number.
|
||||
|
||||
config GICV2
|
||||
bool "ARM GICv2"
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/periph.h>
|
||||
#include <asm/arch/boot_mode.h>
|
||||
#include <asm/arch/rk_atags.h>
|
||||
#ifdef CONFIG_DM_CHARGE_DISPLAY
|
||||
#include <power/charge_display.h>
|
||||
#endif
|
||||
|
|
@ -274,6 +275,27 @@ void enable_caches(void)
|
|||
dcache_enable();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_PRELOADER_SERIAL
|
||||
int board_init_f_init_serial(void)
|
||||
{
|
||||
struct tag *t = atags_get_tag(ATAG_SERIAL);
|
||||
|
||||
if (t) {
|
||||
gd->serial.using_pre_serial = t->u.serial.enable;
|
||||
gd->serial.addr = t->u.serial.addr;
|
||||
gd->serial.baudrate = t->u.serial.baudrate;
|
||||
gd->serial.id = t->u.serial.id;
|
||||
|
||||
debug("%s: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n",
|
||||
__func__, gd->serial.using_pre_serial,
|
||||
gd->serial.addr, gd->serial.baudrate,
|
||||
gd->serial.id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
|
||||
#include <fdt_support.h>
|
||||
#include <usb.h>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,11 @@ __weak void board_add_ram_info(int use_default)
|
|||
|
||||
static int init_baud_rate(void)
|
||||
{
|
||||
gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE);
|
||||
if (gd && gd->serial.using_pre_serial)
|
||||
gd->baudrate = env_get_ulong("baudrate", 10, gd->serial.baudrate);
|
||||
else
|
||||
gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +146,16 @@ static int display_text_info(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL)
|
||||
static int announce_pre_serial(void)
|
||||
{
|
||||
if (gd && gd->serial.using_pre_serial)
|
||||
printf("PreSerial: %d\n", gd->serial.id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int announce_dram_init(void)
|
||||
{
|
||||
puts("DRAM: ");
|
||||
|
|
@ -803,6 +817,9 @@ static const init_fnc_t init_sequence_f[] = {
|
|||
#endif
|
||||
#if defined(CONFIG_HARD_SPI)
|
||||
init_func_spi,
|
||||
#endif
|
||||
#if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL)
|
||||
announce_pre_serial,
|
||||
#endif
|
||||
announce_dram_init,
|
||||
dram_init, /* configure available RAM banks */
|
||||
|
|
|
|||
|
|
@ -172,7 +172,22 @@ static int initr_reloc_global_data(void)
|
|||
|
||||
static int initr_serial(void)
|
||||
{
|
||||
/*
|
||||
* 1. Serial has been initialized in board_f.c => serial_init(), there is
|
||||
* no special reason to init it again;
|
||||
*
|
||||
* 2. Pre-serial works depending on aliases to get pre-serial phandle when
|
||||
* parse dtb. If CONFIG_USING_KERNEL_DTB is enabled, there are both kernel
|
||||
* dtb and U-Boot dtb aliases added into aliases_lookup, these nodes have
|
||||
* same names but different phanles(U-Boot nodes has high prior), this may
|
||||
* lead a wrong aliases node finding if try to get a node after kenrel dtb
|
||||
* unflattened, i.e. using U-Boot phandle to get kernel dtb node!!
|
||||
*
|
||||
* Notice: of_alias_dump() is provided to dump all aliases node.
|
||||
*/
|
||||
#ifndef CONFIG_USING_KERNEL_DTB
|
||||
serial_initialize();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,14 @@ void board_init_f_init_reserve(ulong base)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Board-specific Platform code can init serial earlier if needed
|
||||
*/
|
||||
__weak int board_init_f_init_serial(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Board-specific Platform code can reimplement show_boot_progress () if needed
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -804,5 +804,17 @@ struct device_node *of_alias_dump(void)
|
|||
|
||||
struct device_node *of_get_stdout(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (gd && gd->serial.using_pre_serial) {
|
||||
np = of_alias_get_dev("serial", gd->serial.id);
|
||||
if (!np)
|
||||
printf("Can't find alias serial%d\n", gd->serial.id);
|
||||
else
|
||||
debug("Find alias serial: %s\n", np->full_name);
|
||||
|
||||
of_stdout = np;
|
||||
}
|
||||
|
||||
return of_stdout;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,13 @@ static inline void _debug_uart_init(void)
|
|||
*/
|
||||
baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
|
||||
CONFIG_BAUDRATE);
|
||||
|
||||
if (gd && gd->serial.using_pre_serial) {
|
||||
com_port = (struct NS16550 *)gd->serial.addr;
|
||||
baud_divisor = ns16550_calc_divisor(com_port,
|
||||
CONFIG_DEBUG_UART_CLOCK, gd->serial.baudrate);
|
||||
}
|
||||
|
||||
serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
|
||||
serial_dout(&com_port->mcr, UART_MCRVAL);
|
||||
serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
|
||||
|
|
@ -268,6 +275,9 @@ static inline void _debug_uart_putc(int ch)
|
|||
{
|
||||
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
|
||||
|
||||
if (gd && gd->serial.using_pre_serial)
|
||||
com_port = (struct NS16550 *)gd->serial.addr;
|
||||
|
||||
while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
|
||||
;
|
||||
serial_dout(&com_port->thr, ch);
|
||||
|
|
@ -288,6 +298,13 @@ static inline void _debug_uart_init(void)
|
|||
|
||||
baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
|
||||
CONFIG_BAUDRATE);
|
||||
|
||||
if (gd && gd->serial.using_pre_serial) {
|
||||
com_port = (struct NS16550 *)gd->serial.addr;
|
||||
baud_divisor = ns16550_calc_divisor(com_port,
|
||||
CONFIG_DEBUG_UART_CLOCK, gd->serial.baudrate);
|
||||
}
|
||||
|
||||
serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
|
||||
serial_dout(&com_port->mdr1, 0x7);
|
||||
serial_dout(&com_port->mcr, UART_MCRVAL);
|
||||
|
|
@ -304,6 +321,9 @@ static inline void _debug_uart_putc(int ch)
|
|||
{
|
||||
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
|
||||
|
||||
if (gd && gd->serial.using_pre_serial)
|
||||
com_port = (struct NS16550 *)gd->serial.addr;
|
||||
|
||||
while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
|
||||
;
|
||||
serial_dout(&com_port->thr, ch);
|
||||
|
|
@ -456,6 +476,10 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
|
|||
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
plat->base = addr;
|
||||
#else
|
||||
|
||||
if (gd && gd->serial.using_pre_serial)
|
||||
addr = gd->serial.addr;
|
||||
|
||||
plat->base = (unsigned long)map_physmem(addr, 0, MAP_NOCACHE);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,23 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
|
|||
}
|
||||
if (node < 0)
|
||||
node = fdt_path_offset(blob, "console");
|
||||
|
||||
if (gd && gd->serial.using_pre_serial) {
|
||||
const char *serial_path;
|
||||
char serial[12];
|
||||
|
||||
snprintf(serial, 12, "serial%d", gd->serial.id);
|
||||
serial_path = fdt_get_alias(blob, serial);
|
||||
if (serial_path) {
|
||||
debug("Find alias %s, path: %s\n", serial, serial_path);
|
||||
node = fdt_path_offset(blob, serial_path);
|
||||
if (node < 0)
|
||||
printf("Can't find %s by path\n", serial);
|
||||
} else {
|
||||
printf("Can't find alias %s\n", serial);
|
||||
}
|
||||
}
|
||||
|
||||
if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, devp))
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ struct pm_ctx {
|
|||
unsigned long suspend_regs[15];
|
||||
};
|
||||
|
||||
struct pre_serial {
|
||||
u32 using_pre_serial;
|
||||
u32 id;
|
||||
u32 baudrate;
|
||||
ulong addr;
|
||||
};
|
||||
|
||||
typedef struct global_data {
|
||||
bd_t *bd;
|
||||
unsigned long flags;
|
||||
|
|
@ -126,7 +133,7 @@ typedef struct global_data {
|
|||
#ifdef CONFIG_BOOTSTAGE_PRINTF_TIMESTAMP
|
||||
int new_line;
|
||||
#endif
|
||||
|
||||
struct pre_serial serial;
|
||||
#ifdef CONFIG_LOG
|
||||
int log_drop_count; /* Number of dropped log messages */
|
||||
int default_log_level; /* For devices with no filters */
|
||||
|
|
|
|||
|
|
@ -144,6 +144,11 @@ ulong board_init_f_alloc_reserve(ulong top);
|
|||
*/
|
||||
void board_init_f_init_reserve(ulong base);
|
||||
|
||||
/*
|
||||
* Board-specific Platform code can init serial earlier if needed
|
||||
*/
|
||||
__weak int board_init_f_init_serial(void);
|
||||
|
||||
/**
|
||||
* arch_setup_gd() - Set up the global_data pointer
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue