Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67f4aaa2 authored by Michal Simek's avatar Michal Simek
Browse files

microblaze: Support early console on uart16550



Early console support reuse setting from U-BOOT that's why
it is not necessary to setup baudrates, etc.

Signed-off-by: default avatarMichal Simek <monstr@monstr.eu>
parent 51f5fa50
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -10,7 +10,7 @@ source "lib/Kconfig.debug"


config EARLY_PRINTK
config EARLY_PRINTK
	bool "Early printk function for kernel"
	bool "Early printk function for kernel"
	depends on SERIAL_UARTLITE_CONSOLE
	depends on SERIAL_UARTLITE_CONSOLE || SERIAL_8250_CONSOLE
	default n
	default n
	help
	help
	  This option turns on/off early printk messages to console.
	  This option turns on/off early printk messages to console.
+1 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@


/* Other Prototypes */
/* Other Prototypes */
extern int early_uartlite_console(void);
extern int early_uartlite_console(void);
extern int early_uart16550_console(void);


#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
/*
/*
+63 −0
Original line number Original line Diff line number Diff line
@@ -65,6 +65,50 @@ static struct console early_serial_uartlite_console = {
};
};
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */


#ifdef CONFIG_SERIAL_8250_CONSOLE
static void early_printk_uart16550_putc(char c)
{
	/*
	 * Limit how many times we'll spin waiting for TX FIFO status.
	 * This will prevent lockups if the base address is incorrectly
	 * set, or any other issue on the UARTLITE.
	 * This limit is pretty arbitrary, unless we are at about 10 baud
	 * we'll never timeout on a working UART.
	 */

	#define UART_LSR_TEMT	0x40 /* Transmitter empty */
	#define UART_LSR_THRE	0x20 /* Transmit-hold-register empty */
	#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)

	unsigned retries = 10000;

	while (--retries &&
		!((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
		;

	if (retries)
		out_be32(base_addr, c & 0xff);
}

static void early_printk_uart16550_write(struct console *unused,
					const char *s, unsigned n)
{
	while (*s && n-- > 0) {
		early_printk_uart16550_putc(*s);
		if (*s == '\n')
			early_printk_uart16550_putc('\r');
		s++;
	}
}

static struct console early_serial_uart16550_console = {
	.name = "earlyser",
	.write = early_printk_uart16550_write,
	.flags = CON_PRINTBUFFER,
	.index = -1,
};
#endif /* CONFIG_SERIAL_8250_CONSOLE */

static struct console *early_console;
static struct console *early_console;


void early_printk(const char *fmt, ...)
void early_printk(const char *fmt, ...)
@@ -103,6 +147,25 @@ int __init setup_early_printk(char *opt)
	}
	}
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */


#ifdef CONFIG_SERIAL_8250_CONSOLE
	base_addr = early_uart16550_console();
	base_addr &= ~3; /* clear register offset */
	if (base_addr) {
		early_console_initialized = 1;
#ifdef CONFIG_MMU
		early_console_reg_tlb_alloc(base_addr);
#endif
		early_console = &early_serial_uart16550_console;

		early_printk("early_printk_console is enabled at 0x%08x\n",
							base_addr);

		/* register_console(early_console); */

		return 0;
	}
#endif /* CONFIG_SERIAL_8250_CONSOLE */

	return 1;
	return 1;
}
}


+34 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,40 @@ int __init early_uartlite_console(void)
{
{
	return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
	return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
}
}

/* MS this is Microblaze specifig function */
static int __init early_init_dt_scan_serial_full(unsigned long node,
				const char *uname, int depth, void *data)
{
	unsigned long l;
	char *p;
	unsigned int addr;

	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);

/* find all serial nodes */
	if (strncmp(uname, "serial", 6) != 0)
		return 0;

	early_init_dt_check_for_initrd(node);

/* find compatible node with uartlite */
	p = of_get_flat_dt_prop(node, "compatible", &l);

	if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
		(strncmp(p, "xlnx,axi-uart16550", 18) != 0))
		return 0;

	addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
	addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
	return addr; /* return address */
}

/* this function is looking for early uartlite console - Microblaze specific */
int __init early_uart16550_console(void)
{
	return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
}
#endif
#endif


void __init early_init_devtree(void *params)
void __init early_init_devtree(void *params)