// SPDX-License-Identifier: GPL-2.0-only
/*
 * Carsten Langgaard, carstenl@mips.com
 * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
 *
 * Putting things on the screen/serial line using YAMONs facilities.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/serial_reg.h>
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/string.h>
#include <linux/io.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>

#include <asm/mach-ar7/ar7.h>
#include <asm/mach-ar7/prom.h>

#define MAX_ENTRY 80

struct env_var {
	char	*name;
	char	*value;
};

static struct env_var adam2_env[MAX_ENTRY];

char *prom_getenv(const char *name)
{
	int i;

	for (i = 0; (i < MAX_ENTRY) && adam2_env[i].name; i++)
		if (!strcmp(name, adam2_env[i].name))
			return adam2_env[i].value;

	return NULL;
}
EXPORT_SYMBOL(prom_getenv);

static void  __init ar7_init_cmdline(int argc, char *argv[])
{
	int i;

	for (i = 1; i < argc; i++) {
		strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
		if (i < (argc - 1))
			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
	}
}

struct psbl_rec {
	u32	psbl_size;
	u32	env_base;
	u32	env_size;
	u32	ffs_base;
	u32	ffs_size;
};

static const char psp_env_version[] __initconst = "TIENV0.8";

struct psp_env_chunk {
	u8	num;
	u8	ctrl;
	u16	csum;
	u8	len;
	char	data[11];
} __packed;

struct psp_var_map_entry {
	u8	num;
	char	*value;
};

static const struct psp_var_map_entry psp_var_map[] = {
	{  1,	"cpufrequency" },
	{  2,	"memsize" },
	{  3,	"flashsize" },
	{  4,	"modetty0" },
	{  5,	"modetty1" },
	{  8,	"maca" },
	{  9,	"macb" },
	{ 28,	"sysfrequency" },
	{ 38,	"mipsfrequency" },
};

/*

Well-known variable (num is looked up in table above for matching variable name)
Example: cpufrequency=211968000
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
| 01 |CTRL|CHECKSUM | 01 | _2 | _1 | _1 | _9 | _6 | _8 | _0 | _0 | _0 | \0 | FF
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---

Name=Value pair in a single chunk
Example: NAME=VALUE
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
| 00 |CTRL|CHECKSUM | 01 | _N | _A | _M | _E | _0 | _V | _A | _L | _U | _E | \0
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---

Name=Value pair in 2 chunks (len is the number of chunks)
Example: bootloaderVersion=1.3.7.15
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
| 00 |CTRL|CHECKSUM | 02 | _b | _o | _o | _t | _l | _o | _a | _d | _e | _r | _V
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
| _e | _r | _s | _i | _o | _n | \0 | _1 | _. | _3 | _. | _7 | _. | _1 | _5 | \0
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---

Data is padded with 0xFF

*/

#define PSP_ENV_SIZE  4096

static char psp_env_data[PSP_ENV_SIZE] = { 0, };

static char * __init lookup_psp_var_map(u8 num)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(psp_var_map); i++)
		if (psp_var_map[i].num == num)
			return psp_var_map[i].value;

	return NULL;
}

static void __init add_adam2_var(char *name, char *value)
{
	int i;

	for (i = 0; i < MAX_ENTRY; i++) {
		if (!adam2_env[i].name) {
			adam2_env[i].name = name;
			adam2_env[i].value = value;
			return;
		} else if (!strcmp(adam2_env[i].name, name)) {
			adam2_env[i].value = value;
			return;
		}
	}
}

static int __init parse_psp_env(void *psp_env_base)
{
	int i, n;
	char *name, *value;
	struct psp_env_chunk *chunks = (struct psp_env_chunk *)psp_env_data;

	memcpy_fromio(chunks, psp_env_base, PSP_ENV_SIZE);

	i = 1;
	n = PSP_ENV_SIZE / sizeof(struct psp_env_chunk);
	while (i < n) {
		if ((chunks[i].num == 0xff) || ((i + chunks[i].len) > n))
			break;
		value = chunks[i].data;
		if (chunks[i].num) {
			name = lookup_psp_var_map(chunks[i].num);
		} else {
			name = value;
			value += strlen(name) + 1;
		}
		if (name)
			add_adam2_var(name, value);
		i += chunks[i].len;
	}
	return 0;
}

static void __init ar7_init_env(struct env_var *env)
{
	int i;
	struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300));
	void *psp_env = (void *)KSEG1ADDR(psbl->env_base);

	if (strcmp(psp_env, psp_env_version) == 0) {
		parse_psp_env(psp_env);
	} else {
		for (i = 0; i < MAX_ENTRY; i++, env++)
			if (env->name)
				add_adam2_var(env->name, env->value);
	}
}

static void __init console_config(void)
{
#ifdef CONFIG_SERIAL_8250_CONSOLE
	char console_string[40];
	int baud = 0;
	char parity = '\0', bits = '\0', flow = '\0';
	char *s, *p;

	if (strstr(arcs_cmdline, "console="))
		return;

	s = prom_getenv("modetty0");
	if (s) {
		baud = simple_strtoul(s, &p, 10);
		s = p;
		if (*s == ',')
			s++;
		if (*s)
			parity = *s++;
		if (*s == ',')
			s++;
		if (*s)
			bits = *s++;
		if (*s == ',')
			s++;
		if (*s == 'h')
			flow = 'r';
	}

	if (baud == 0)
		baud = 38400;
	if (parity != 'n' && parity != 'o' && parity != 'e')
		parity = 'n';
	if (bits != '7' && bits != '8')
		bits = '8';

	if (flow == 'r')
		sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
			parity, bits, flow);
	else
		sprintf(console_string, " console=ttyS0,%d%c%c", baud, parity,
			bits);
	strlcat(arcs_cmdline, console_string, COMMAND_LINE_SIZE);
#endif
}

void __init prom_init(void)
{
	ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
	ar7_init_env((struct env_var *)fw_arg2);
	console_config();
}

#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
static inline unsigned int serial_in(int offset)
{
	return readl((void *)PORT(offset));
}

static inline void serial_out(int offset, int value)
{
	writel(value, (void *)PORT(offset));
}

void prom_putchar(char c)
{
	while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0)
		;
	serial_out(UART_TX, c);
}
