// SPDX-License-Identifier: GPL-2.0-only
/*
 * Joshua Henderson <joshua.henderson@microchip.com>
 * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
 */
#include <asm/mach-pic32/pic32.h>
#include <asm/fw/fw.h>
#include <asm/setup.h>

#include "pic32mzda.h"
#include "early_pin.h"

/* Default early console parameters */
#define EARLY_CONSOLE_PORT	1
#define EARLY_CONSOLE_BAUDRATE	115200

#define UART_ENABLE		BIT(15)
#define UART_ENABLE_RX		BIT(12)
#define UART_ENABLE_TX		BIT(10)
#define UART_TX_FULL		BIT(9)

/* UART1(x == 0) - UART6(x == 5) */
#define UART_BASE(x)	((x) * 0x0200)
#define U_MODE(x)	UART_BASE(x)
#define U_STA(x)	(UART_BASE(x) + 0x10)
#define U_TXR(x)	(UART_BASE(x) + 0x20)
#define U_BRG(x)	(UART_BASE(x) + 0x40)

static void __iomem *uart_base;
static int console_port = -1;

static int __init configure_uart_pins(int port)
{
	switch (port) {
	case 1:
		pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
		pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
		break;
	case 5:
		pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
		pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
		break;
	default:
		return -1;
	}

	return 0;
}

static void __init configure_uart(int port, int baud)
{
	u32 pbclk;

	pbclk = pic32_get_pbclk(2);

	__raw_writel(0, uart_base + U_MODE(port));
	__raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
	__raw_writel(UART_ENABLE, uart_base + U_MODE(port));
	__raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
		     uart_base + PIC32_SET(U_STA(port)));
}

static void __init setup_early_console(int port, int baud)
{
	if (configure_uart_pins(port))
		return;

	console_port = port;
	configure_uart(console_port, baud);
}

static char * __init pic32_getcmdline(void)
{
	/*
	 * arch_mem_init() has not been called yet, so we don't have a real
	 * command line setup if using CONFIG_CMDLINE_BOOL.
	 */
#ifdef CONFIG_CMDLINE_OVERRIDE
	return CONFIG_CMDLINE;
#else
	return fw_getcmdline();
#endif
}

static int __init get_port_from_cmdline(char *arch_cmdline)
{
	char *s;
	int port = -1;

	if (!arch_cmdline || *arch_cmdline == '\0')
		goto _out;

	s = strstr(arch_cmdline, "earlyprintk=");
	if (s) {
		s = strstr(s, "ttyS");
		if (s)
			s += 4;
		else
			goto _out;

		port = (*s) - '0';
	}

_out:
	return port;
}

static int __init get_baud_from_cmdline(char *arch_cmdline)
{
	char *s;
	int baud = -1;

	if (!arch_cmdline || *arch_cmdline == '\0')
		goto _out;

	s = strstr(arch_cmdline, "earlyprintk=");
	if (s) {
		s = strstr(s, "ttyS");
		if (s)
			s += 6;
		else
			goto _out;

		baud = 0;
		while (*s >= '0' && *s <= '9')
			baud = baud * 10 + *s++ - '0';
	}

_out:
	return baud;
}

void __init fw_init_early_console(void)
{
	char *arch_cmdline = pic32_getcmdline();
	int baud, port;

	uart_base = ioremap(PIC32_BASE_UART, 0xc00);

	baud = get_baud_from_cmdline(arch_cmdline);
	port = get_port_from_cmdline(arch_cmdline);

	if (port == -1)
		port = EARLY_CONSOLE_PORT;

	if (baud == -1)
		baud = EARLY_CONSOLE_BAUDRATE;

	setup_early_console(port, baud);
}

void prom_putchar(char c)
{
	if (console_port >= 0) {
		while (__raw_readl(
				uart_base + U_STA(console_port)) & UART_TX_FULL)
			;

		__raw_writel(c, uart_base + U_TXR(console_port));
	}
}
