/*
 * Joshua Henderson, joshua.henderson@microchip.com
 * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/platform_data/sdhci-pic32.h>

#include <asm/fw/fw.h>
#include <asm/mips-boards/generic.h>
#include <asm/prom.h>

#include "pic32mzda.h"

const char *get_system_type(void)
{
	return "PIC32MZDA";
}

static ulong get_fdtaddr(void)
{
	ulong ftaddr = 0;

	if (fw_passed_dtb && !fw_arg2 && !fw_arg3)
		return (ulong)fw_passed_dtb;

	if (&__dtb_start < &__dtb_end)
		ftaddr = (ulong)__dtb_start;

	return ftaddr;
}

void __init plat_mem_setup(void)
{
	void *dtb;

	dtb = (void *)get_fdtaddr();
	if (!dtb) {
		pr_err("pic32: no DTB found.\n");
		return;
	}

	/*
	 * Load the builtin device tree. This causes the chosen node to be
	 * parsed resulting in our memory appearing.
	 */
	__dt_setup_arch(dtb);

	pr_info("Found following command lines\n");
	pr_info(" boot_command_line: %s\n", boot_command_line);
	pr_info(" arcs_cmdline     : %s\n", arcs_cmdline);
#ifdef CONFIG_CMDLINE_BOOL
	pr_info(" builtin_cmdline  : %s\n", CONFIG_CMDLINE);
#endif
	if (dtb != __dtb_start)
		strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);

#ifdef CONFIG_EARLY_PRINTK
	fw_init_early_console(-1);
#endif
	pic32_config_init();
}

static __init void pic32_init_cmdline(int argc, char *argv[])
{
	unsigned int count = COMMAND_LINE_SIZE - 1;
	int i;
	char *dst = &(arcs_cmdline[0]);
	char *src;

	for (i = 1; i < argc && count; ++i) {
		src = argv[i];
		while (*src && count) {
			*dst++ = *src++;
			--count;
		}
		*dst++ = ' ';
	}
	if (i > 1)
		--dst;

	*dst = 0;
}

void __init prom_init(void)
{
	pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1);
}

void __init prom_free_prom_memory(void)
{
}

void __init device_tree_init(void)
{
	if (!initial_boot_params)
		return;

	unflatten_and_copy_device_tree();
}

static struct pic32_sdhci_platform_data sdhci_data = {
	.setup_dma = pic32_set_sdhci_adma_fifo_threshold,
};

static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = {
	OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data),
	{ /* sentinel */}
};

static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup)
{
	struct device_node *root, *np;
	struct resource res;

	root = of_find_node_by_path("/");

	for (; lookup->compatible; lookup++) {
		np = of_find_compatible_node(NULL, NULL, lookup->compatible);
		if (np) {
			lookup->name = (char *)np->name;
			if (lookup->phys_addr)
				continue;
			if (!of_address_to_resource(np, 0, &res))
				lookup->phys_addr = res.start;
		}
	}

	return 0;
}

static int __init plat_of_setup(void)
{
	if (!of_have_populated_dt())
		panic("Device tree not present");

	pic32_of_prepare_platform_data(pic32_auxdata_lookup);
	if (of_platform_default_populate(NULL, pic32_auxdata_lookup, NULL))
		panic("Failed to populate DT");

	return 0;
}
arch_initcall(plat_of_setup);
