// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 Imagination Technologies
 * Author: Paul Burton <paul.burton@mips.com>
 */

#define pr_fmt(fmt) "yamon-dt: " fmt

#include <linux/bug.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/libfdt.h>
#include <linux/printk.h>

#include <asm/fw/fw.h>
#include <asm/yamon-dt.h>

#define MAX_MEM_ARRAY_ENTRIES	2

__init int yamon_dt_append_cmdline(void *fdt)
{
	int err, chosen_off;

	/* find or add chosen node */
	chosen_off = fdt_path_offset(fdt, "/chosen");
	if (chosen_off == -FDT_ERR_NOTFOUND)
		chosen_off = fdt_add_subnode(fdt, 0, "chosen");
	if (chosen_off < 0) {
		pr_err("Unable to find or add DT chosen node: %d\n",
		       chosen_off);
		return chosen_off;
	}

	err = fdt_setprop_string(fdt, chosen_off, "bootargs", fw_getcmdline());
	if (err) {
		pr_err("Unable to set bootargs property: %d\n", err);
		return err;
	}

	return 0;
}

static unsigned int __init gen_fdt_mem_array(
					const struct yamon_mem_region *regions,
					__be32 *mem_array,
					unsigned int max_entries,
					unsigned long memsize)
{
	const struct yamon_mem_region *mr;
	unsigned long size;
	unsigned int entries = 0;

	for (mr = regions; mr->size && memsize; ++mr) {
		if (entries >= max_entries) {
			pr_warn("Number of regions exceeds max %u\n",
				max_entries);
			break;
		}

		/* How much of the remaining RAM fits in the next region? */
		size = min_t(unsigned long, memsize, mr->size);
		memsize -= size;

		/* Emit a memory region */
		*(mem_array++) = cpu_to_be32(mr->start);
		*(mem_array++) = cpu_to_be32(size);
		++entries;

		/* Discard the next mr->discard bytes */
		memsize -= min_t(unsigned long, memsize, mr->discard);
	}
	return entries;
}

__init int yamon_dt_append_memory(void *fdt,
				  const struct yamon_mem_region *regions)
{
	unsigned long phys_memsize = 0, memsize;
	__be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
	unsigned int mem_entries;
	int i, err, mem_off;
	char *var, param_name[10], *var_names[] = {
		"ememsize", "memsize",
	};

	/* find memory size from the bootloader environment */
	for (i = 0; i < ARRAY_SIZE(var_names); i++) {
		var = fw_getenv(var_names[i]);
		if (!var)
			continue;

		err = kstrtoul(var, 0, &phys_memsize);
		if (!err)
			break;

		pr_warn("Failed to read the '%s' env variable '%s'\n",
			var_names[i], var);
	}

	if (!phys_memsize) {
		pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
		phys_memsize = 32 << 20;
	}

	/* default to using all available RAM */
	memsize = phys_memsize;

	/* allow the user to override the usable memory */
	for (i = 0; i < ARRAY_SIZE(var_names); i++) {
		snprintf(param_name, sizeof(param_name), "%s=", var_names[i]);
		var = strstr(arcs_cmdline, param_name);
		if (!var)
			continue;

		memsize = memparse(var + strlen(param_name), NULL);
	}

	/* if the user says there's more RAM than we thought, believe them */
	phys_memsize = max_t(unsigned long, phys_memsize, memsize);

	/* find or add a memory node */
	mem_off = fdt_path_offset(fdt, "/memory");
	if (mem_off == -FDT_ERR_NOTFOUND)
		mem_off = fdt_add_subnode(fdt, 0, "memory");
	if (mem_off < 0) {
		pr_err("Unable to find or add memory DT node: %d\n", mem_off);
		return mem_off;
	}

	err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
	if (err) {
		pr_err("Unable to set memory node device_type: %d\n", err);
		return err;
	}

	mem_entries = gen_fdt_mem_array(regions, mem_array,
					MAX_MEM_ARRAY_ENTRIES, phys_memsize);
	err = fdt_setprop(fdt, mem_off, "reg",
			  mem_array, mem_entries * 2 * sizeof(mem_array[0]));
	if (err) {
		pr_err("Unable to set memory regs property: %d\n", err);
		return err;
	}

	mem_entries = gen_fdt_mem_array(regions, mem_array,
					MAX_MEM_ARRAY_ENTRIES, memsize);
	err = fdt_setprop(fdt, mem_off, "linux,usable-memory",
			  mem_array, mem_entries * 2 * sizeof(mem_array[0]));
	if (err) {
		pr_err("Unable to set linux,usable-memory property: %d\n", err);
		return err;
	}

	return 0;
}

__init int yamon_dt_serial_config(void *fdt)
{
	const char *yamontty, *mode_var;
	char mode_var_name[9], path[20], parity;
	unsigned int uart, baud, stop_bits;
	bool hw_flow;
	int chosen_off, err;

	yamontty = fw_getenv("yamontty");
	if (!yamontty || !strcmp(yamontty, "tty0")) {
		uart = 0;
	} else if (!strcmp(yamontty, "tty1")) {
		uart = 1;
	} else {
		pr_warn("yamontty environment variable '%s' invalid\n",
			yamontty);
		uart = 0;
	}

	baud = stop_bits = 0;
	parity = 0;
	hw_flow = false;

	snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart);
	mode_var = fw_getenv(mode_var_name);
	if (mode_var) {
		while (mode_var[0] >= '0' && mode_var[0] <= '9') {
			baud *= 10;
			baud += mode_var[0] - '0';
			mode_var++;
		}
		if (mode_var[0] == ',')
			mode_var++;
		if (mode_var[0])
			parity = mode_var[0];
		if (mode_var[0] == ',')
			mode_var++;
		if (mode_var[0])
			stop_bits = mode_var[0] - '0';
		if (mode_var[0] == ',')
			mode_var++;
		if (!strcmp(mode_var, "hw"))
			hw_flow = true;
	}

	if (!baud)
		baud = 38400;

	if (parity != 'e' && parity != 'n' && parity != 'o')
		parity = 'n';

	if (stop_bits != 7 && stop_bits != 8)
		stop_bits = 8;

	WARN_ON(snprintf(path, sizeof(path), "serial%u:%u%c%u%s",
			 uart, baud, parity, stop_bits,
			 hw_flow ? "r" : "") >= sizeof(path));

	/* find or add chosen node */
	chosen_off = fdt_path_offset(fdt, "/chosen");
	if (chosen_off == -FDT_ERR_NOTFOUND)
		chosen_off = fdt_add_subnode(fdt, 0, "chosen");
	if (chosen_off < 0) {
		pr_err("Unable to find or add DT chosen node: %d\n",
		       chosen_off);
		return chosen_off;
	}

	err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path);
	if (err) {
		pr_err("Unable to set stdout-path property: %d\n", err);
		return err;
	}

	return 0;
}
