/*
 * R-Car Generation 2 support
 *
 * Copyright (C) 2013  Renesas Solutions Corp.
 * Copyright (C) 2013  Magnus Damm
 * Copyright (C) 2014  Ulrich Hecht
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that 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/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include "common.h"
#include "rcar-gen2.h"

static const struct of_device_id cpg_matches[] __initconst = {
	{ .compatible = "renesas,rcar-gen2-cpg-clocks", },
	{ .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
	{ .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
	{ .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" },
	{ .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" },
	{ /* sentinel */ }
};

static unsigned int __init get_extal_freq(void)
{
	const struct of_device_id *match;
	struct device_node *cpg, *extal;
	u32 freq = 20000000;
	int idx = 0;

	cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match);
	if (!cpg)
		return freq;

	if (match->data)
		idx = of_property_match_string(cpg, "clock-names", match->data);
	extal = of_parse_phandle(cpg, "clocks", idx);
	of_node_put(cpg);
	if (!extal)
		return freq;

	of_property_read_u32(extal, "clock-frequency", &freq);
	of_node_put(extal);
	return freq;
}

#define CNTCR 0
#define CNTFID0 0x20

void __init rcar_gen2_timer_init(void)
{
#ifdef CONFIG_ARM_ARCH_TIMER
	void __iomem *base;
	u32 freq;

	shmobile_init_cntvoff();

	if (of_machine_is_compatible("renesas,r8a7745") ||
	    of_machine_is_compatible("renesas,r8a7792") ||
	    of_machine_is_compatible("renesas,r8a7794")) {
		freq = 260000000 / 8;	/* ZS / 8 */
	} else {
		/* At Linux boot time the r8a7790 arch timer comes up
		 * with the counter disabled. Moreover, it may also report
		 * a potentially incorrect fixed 13 MHz frequency. To be
		 * correct these registers need to be updated to use the
		 * frequency EXTAL / 2.
		 */
		freq = get_extal_freq() / 2;
	}

	/* Remap "armgcnt address map" space */
	base = ioremap(0xe6080000, PAGE_SIZE);

	/*
	 * Update the timer if it is either not running, or is not at the
	 * right frequency. The timer is only configurable in secure mode
	 * so this avoids an abort if the loader started the timer and
	 * entered the kernel in non-secure mode.
	 */

	if ((ioread32(base + CNTCR) & 1) == 0 ||
	    ioread32(base + CNTFID0) != freq) {
		/* Update registers with correct frequency */
		iowrite32(freq, base + CNTFID0);
		asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));

		/* make sure arch timer is started by setting bit 0 of CNTCR */
		iowrite32(1, base + CNTCR);
	}

	iounmap(base);
#endif /* CONFIG_ARM_ARCH_TIMER */

	of_clk_init(NULL);
	timer_probe();
}

struct memory_reserve_config {
	u64 reserved;
	u64 base, size;
};

static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
				     int depth, void *data)
{
	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
	const __be32 *reg, *endp;
	int l;
	struct memory_reserve_config *mrc = data;
	u64 lpae_start = 1ULL << 32;

	/* We are scanning "memory" nodes only */
	if (type == NULL || strcmp(type, "memory"))
		return 0;

	reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
	if (reg == NULL)
		reg = of_get_flat_dt_prop(node, "reg", &l);
	if (reg == NULL)
		return 0;

	endp = reg + (l / sizeof(__be32));
	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
		u64 base, size;

		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
		size = dt_mem_next_cell(dt_root_size_cells, &reg);

		if (base >= lpae_start)
			continue;

		if ((base + size) >= lpae_start)
			size = lpae_start - base;

		if (size < mrc->reserved)
			continue;

		if (base < mrc->base)
			continue;

		/* keep the area at top near the 32-bit legacy limit */
		mrc->base = base + size - mrc->reserved;
		mrc->size = mrc->reserved;
	}

	return 0;
}

void __init rcar_gen2_reserve(void)
{
	struct memory_reserve_config mrc;

	/* reserve 256 MiB at the top of the physical legacy 32-bit space */
	memset(&mrc, 0, sizeof(mrc));
	mrc.reserved = SZ_256M;

	of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
#ifdef CONFIG_DMA_CMA
	if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
		static struct cma *rcar_gen2_dma_contiguous;

		dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
					    &rcar_gen2_dma_contiguous, true);
	}
#endif
}

static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
	/*
	 * R8A7790 and R8A7791 can't be handled here as long as they need SMP
	 * initialization fallback.
	 */
	"renesas,r8a7792",
	"renesas,r8a7793",
	"renesas,r8a7794",
	NULL,
};

DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
	.init_early	= shmobile_init_delay,
	.init_late	= shmobile_init_late,
	.init_time	= rcar_gen2_timer_init,
	.reserve	= rcar_gen2_reserve,
	.dt_compat	= rcar_gen2_boards_compat_dt,
MACHINE_END

static const char * const rz_g1_boards_compat_dt[] __initconst = {
	"renesas,r8a7743",
	"renesas,r8a7745",
	NULL,
};

DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
	.init_early	= shmobile_init_delay,
	.init_late	= shmobile_init_late,
	.init_time	= rcar_gen2_timer_init,
	.reserve	= rcar_gen2_reserve,
	.dt_compat	= rz_g1_boards_compat_dt,
MACHINE_END
