/*
 * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <string.h>

#include <lib/bl_aux_params/bl_aux_params.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/console.h>
#include <drivers/gpio.h>
#include <libfdt.h>
#include <lib/coreboot.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>

#include <plat_params.h>
#include <plat_private.h>

static struct bl_aux_gpio_info rst_gpio = { .index = UINT_MAX } ;
static struct bl_aux_gpio_info poweroff_gpio = { .index = UINT_MAX };
static struct bl_aux_gpio_info suspend_gpio[10];
uint32_t suspend_gpio_cnt;
static struct bl_aux_rk_apio_info suspend_apio;

#if COREBOOT
static int dt_process_fdt(u_register_t param_from_bl2)
{
	return -ENODEV;
}
#else
static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE;
static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK;
#define FDT_BUFFER_SIZE 0x20000
static uint8_t fdt_buffer[FDT_BUFFER_SIZE];

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;
	const char *separator;
	const char *baud_start;
	char serial_char;
	int serial_no;
	uint32_t uart_base;
	uint32_t baud;

	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:baudrate"
	 */
	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
#ifdef UART5_BASE
	case 5:
		uart_base = UART5_BASE;
		break;
#endif
	default:
		return;
	}

	rk_uart_base = uart_base;

	separator = strchr(stdout_path, ':');
	if (!separator)
		return;

	baud = 0;
	baud_start = separator + 1;
	while (*baud_start != '\0') {
		/*
		 * uart binding is <baud>{<parity>{<bits>{...}}}
		 * So the baudrate either is the whole string, or
		 * we end in the parity characters.
		 */
		if (*baud_start == 'n' || *baud_start == 'o' ||
		    *baud_start == 'e')
			break;

		baud = baud * 10 + (*baud_start - '0');
		baud_start++;
	}

	rk_uart_baudrate = baud;
}

static int dt_process_fdt(u_register_t param_from_bl2)
{
	void *fdt = plat_get_fdt();
	int ret;

	ret = fdt_open_into((void *)param_from_bl2, fdt, FDT_BUFFER_SIZE);
	if (ret < 0)
		return ret;

	plat_rockchip_dt_process_fdt_uart(fdt);

	return 0;
}
#endif

uint32_t rockchip_get_uart_base(void)
{
#if COREBOOT
	return coreboot_serial.baseaddr;
#else
	return rk_uart_base;
#endif
}

uint32_t rockchip_get_uart_baudrate(void)
{
#if COREBOOT
	return coreboot_serial.baud;
#else
	return rk_uart_baudrate;
#endif
}

uint32_t rockchip_get_uart_clock(void)
{
#if COREBOOT
	return coreboot_serial.input_hertz;
#else
	return rk_uart_clock;
#endif
}

struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void)
{
	if (rst_gpio.index == UINT_MAX)
		return NULL;

	return &rst_gpio;
}

struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void)
{
	if (poweroff_gpio.index == UINT_MAX)
		return NULL;

	return &poweroff_gpio;
}

struct bl_aux_gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count)
{
	*count = suspend_gpio_cnt;

	return &suspend_gpio[0];
}

struct bl_aux_rk_apio_info *plat_get_rockchip_suspend_apio(void)
{
	return &suspend_apio;
}

static bool rk_aux_param_handler(struct bl_aux_param_header *param)
{
	/* Store platform parameters for later processing if needed. */
	switch (param->type) {
	case BL_AUX_PARAM_RK_RESET_GPIO:
		rst_gpio = ((struct bl_aux_param_gpio *)param)->gpio;
		return true;
	case BL_AUX_PARAM_RK_POWEROFF_GPIO:
		poweroff_gpio = ((struct bl_aux_param_gpio *)param)->gpio;
		return true;
	case BL_AUX_PARAM_RK_SUSPEND_GPIO:
		if (suspend_gpio_cnt >= ARRAY_SIZE(suspend_gpio)) {
			ERROR("Exceeded the supported suspend GPIO number.\n");
			return true;
		}
		suspend_gpio[suspend_gpio_cnt++] =
			((struct bl_aux_param_gpio *)param)->gpio;
		return true;
	case BL_AUX_PARAM_RK_SUSPEND_APIO:
		suspend_apio = ((struct bl_aux_param_rk_apio *)param)->apio;
		return true;
	}

	return false;
}

void params_early_setup(u_register_t plat_param_from_bl2)
{
	int ret;

	/*
	 * Test if this is a FDT passed as a platform-specific parameter
	 * block.
	 */
	ret = dt_process_fdt(plat_param_from_bl2);
	if (!ret) {
		return;
	} else if (ret != -FDT_ERR_BADMAGIC) {
		/*
		 * If we found an FDT but couldn't parse it (e.g. corrupt, not
		 * enough space), return and don't attempt to parse the param
		 * as something else, since we know that will also fail. All
		 * we're doing is setting up UART, this doesn't need to be
		 * fatal.
		 */
		WARN("%s: found FDT but could not parse: error %d\n",
		     __func__, ret);
		return;
	}

	bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler);
}
