/*
 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
 *
 * Author: John Rigby <jrigby@freescale.com>
 *
 * Description:
 * MPC512x Shared code
 *
 * This 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; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/of_platform.h>
#include <linux/fsl-diu-fb.h>
#include <linux/memblock.h>
#include <sysdev/fsl_soc.h>

#include <asm/cacheflush.h>
#include <asm/machdep.h>
#include <asm/ipic.h>
#include <asm/prom.h>
#include <asm/time.h>
#include <asm/mpc5121.h>
#include <asm/mpc52xx_psc.h>

#include "mpc512x.h"

static struct mpc512x_reset_module __iomem *reset_module_base;

static void __init mpc512x_restart_init(void)
{
	struct device_node *np;
	const char *reset_compat;

	reset_compat = mpc512x_select_reset_compat();
	np = of_find_compatible_node(NULL, NULL, reset_compat);
	if (!np)
		return;

	reset_module_base = of_iomap(np, 0);
	of_node_put(np);
}

void mpc512x_restart(char *cmd)
{
	if (reset_module_base) {
		/* Enable software reset "RSTE" */
		out_be32(&reset_module_base->rpr, 0x52535445);
		/* Set software hard reset */
		out_be32(&reset_module_base->rcr, 0x2);
	} else {
		pr_err("Restart module not mapped.\n");
	}
	for (;;)
		;
}

struct fsl_diu_shared_fb {
	u8		gamma[0x300];	/* 32-bit aligned! */
	struct diu_ad	ad0;		/* 32-bit aligned! */
	phys_addr_t	fb_phys;
	size_t		fb_len;
	bool		in_use;
};

/* receives a pixel clock spec in pico seconds, adjusts the DIU clock rate */
static void mpc512x_set_pixel_clock(unsigned int pixclock)
{
	struct device_node *np;
	struct clk *clk_diu;
	unsigned long epsilon, minpixclock, maxpixclock;
	unsigned long offset, want, got, delta;

	/* lookup and enable the DIU clock */
	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu");
	if (!np) {
		pr_err("Could not find DIU device tree node.\n");
		return;
	}
	clk_diu = of_clk_get(np, 0);
	if (IS_ERR(clk_diu)) {
		/* backwards compat with device trees that lack clock specs */
		clk_diu = clk_get_sys(np->name, "ipg");
	}
	of_node_put(np);
	if (IS_ERR(clk_diu)) {
		pr_err("Could not lookup DIU clock.\n");
		return;
	}
	if (clk_prepare_enable(clk_diu)) {
		pr_err("Could not enable DIU clock.\n");
		return;
	}

	/*
	 * convert the picoseconds spec into the desired clock rate,
	 * determine the acceptable clock range for the monitor (+/- 5%),
	 * do the calculation in steps to avoid integer overflow
	 */
	pr_debug("DIU pixclock in ps - %u\n", pixclock);
	pixclock = (1000000000 / pixclock) * 1000;
	pr_debug("DIU pixclock freq  - %u\n", pixclock);
	epsilon = pixclock / 20; /* pixclock * 0.05 */
	pr_debug("DIU deviation      - %lu\n", epsilon);
	minpixclock = pixclock - epsilon;
	maxpixclock = pixclock + epsilon;
	pr_debug("DIU minpixclock    - %lu\n", minpixclock);
	pr_debug("DIU maxpixclock    - %lu\n", maxpixclock);

	/*
	 * check whether the DIU supports the desired pixel clock
	 *
	 * - simply request the desired clock and see what the
	 *   platform's clock driver will make of it, assuming that it
	 *   will setup the best approximation of the requested value
	 * - try other candidate frequencies in the order of decreasing
	 *   preference (i.e. with increasing distance from the desired
	 *   pixel clock, and checking the lower frequency before the
	 *   higher frequency to not overload the hardware) until the
	 *   first match is found -- any potential subsequent match
	 *   would only be as good as the former match or typically
	 *   would be less preferrable
	 *
	 * the offset increment of pixelclock divided by 64 is an
	 * arbitrary choice -- it's simple to calculate, in the typical
	 * case we expect the first check to succeed already, in the
	 * worst case seven frequencies get tested (the exact center and
	 * three more values each to the left and to the right) before
	 * the 5% tolerance window is exceeded, resulting in fast enough
	 * execution yet high enough probability of finding a suitable
	 * value, while the error rate will be in the order of single
	 * percents
	 */
	for (offset = 0; offset <= epsilon; offset += pixclock / 64) {
		want = pixclock - offset;
		pr_debug("DIU checking clock - %lu\n", want);
		clk_set_rate(clk_diu, want);
		got = clk_get_rate(clk_diu);
		delta = abs(pixclock - got);
		if (delta < epsilon)
			break;
		if (!offset)
			continue;
		want = pixclock + offset;
		pr_debug("DIU checking clock - %lu\n", want);
		clk_set_rate(clk_diu, want);
		got = clk_get_rate(clk_diu);
		delta = abs(pixclock - got);
		if (delta < epsilon)
			break;
	}
	if (offset <= epsilon) {
		pr_debug("DIU clock accepted - %lu\n", want);
		pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
			 pixclock, got, delta, epsilon);
		return;
	}
	pr_warn("DIU pixclock auto search unsuccessful\n");

	/*
	 * what is the most appropriate action to take when the search
	 * for an available pixel clock which is acceptable to the
	 * monitor has failed?  disable the DIU (clock) or just provide
	 * a "best effort"?  we go with the latter
	 */
	pr_warn("DIU pixclock best effort fallback (backend's choice)\n");
	clk_set_rate(clk_diu, pixclock);
	got = clk_get_rate(clk_diu);
	delta = abs(pixclock - got);
	pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
		 pixclock, got, delta, epsilon);
}

static enum fsl_diu_monitor_port
mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
{
	return FSL_DIU_PORT_DVI;
}

static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;

static inline void mpc512x_free_bootmem(struct page *page)
{
	BUG_ON(PageTail(page));
	BUG_ON(page_ref_count(page) > 1);
	free_reserved_page(page);
}

static void mpc512x_release_bootmem(void)
{
	unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK;
	unsigned long size = diu_shared_fb.fb_len;
	unsigned long start, end;

	if (diu_shared_fb.in_use) {
		start = PFN_UP(addr);
		end = PFN_DOWN(addr + size);

		for (; start < end; start++)
			mpc512x_free_bootmem(pfn_to_page(start));

		diu_shared_fb.in_use = false;
	}
	diu_ops.release_bootmem	= NULL;
}

/*
 * Check if DIU was pre-initialized. If so, perform steps
 * needed to continue displaying through the whole boot process.
 * Move area descriptor and gamma table elsewhere, they are
 * destroyed by bootmem allocator otherwise. The frame buffer
 * address range will be reserved in setup_arch() after bootmem
 * allocator is up.
 */
static void __init mpc512x_init_diu(void)
{
	struct device_node *np;
	struct diu __iomem *diu_reg;
	phys_addr_t desc;
	void __iomem *vaddr;
	unsigned long mode, pix_fmt, res, bpp;
	unsigned long dst;

	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu");
	if (!np) {
		pr_err("No DIU node\n");
		return;
	}

	diu_reg = of_iomap(np, 0);
	of_node_put(np);
	if (!diu_reg) {
		pr_err("Can't map DIU\n");
		return;
	}

	mode = in_be32(&diu_reg->diu_mode);
	if (mode == MFB_MODE0) {
		pr_info("%s: DIU OFF\n", __func__);
		goto out;
	}

	desc = in_be32(&diu_reg->desc[0]);
	vaddr = ioremap(desc, sizeof(struct diu_ad));
	if (!vaddr) {
		pr_err("Can't map DIU area desc.\n");
		goto out;
	}
	memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad));
	/* flush fb area descriptor */
	dst = (unsigned long)&diu_shared_fb.ad0;
	flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1);

	res = in_be32(&diu_reg->disp_size);
	pix_fmt = in_le32(vaddr);
	bpp = ((pix_fmt >> 16) & 0x3) + 1;
	diu_shared_fb.fb_phys = in_le32(vaddr + 4);
	diu_shared_fb.fb_len = ((res & 0xfff0000) >> 16) * (res & 0xfff) * bpp;
	diu_shared_fb.in_use = true;
	iounmap(vaddr);

	desc = in_be32(&diu_reg->gamma);
	vaddr = ioremap(desc, sizeof(diu_shared_fb.gamma));
	if (!vaddr) {
		pr_err("Can't map DIU area desc.\n");
		diu_shared_fb.in_use = false;
		goto out;
	}
	memcpy(&diu_shared_fb.gamma, vaddr, sizeof(diu_shared_fb.gamma));
	/* flush gamma table */
	dst = (unsigned long)&diu_shared_fb.gamma;
	flush_dcache_range(dst, dst + sizeof(diu_shared_fb.gamma) - 1);

	iounmap(vaddr);
	out_be32(&diu_reg->gamma, virt_to_phys(&diu_shared_fb.gamma));
	out_be32(&diu_reg->desc[1], 0);
	out_be32(&diu_reg->desc[2], 0);
	out_be32(&diu_reg->desc[0], virt_to_phys(&diu_shared_fb.ad0));

out:
	iounmap(diu_reg);
}

static void __init mpc512x_setup_diu(void)
{
	int ret;

	/*
	 * We do not allocate and configure new area for bitmap buffer
	 * because it would requere copying bitmap data (splash image)
	 * and so negatively affect boot time. Instead we reserve the
	 * already configured frame buffer area so that it won't be
	 * destroyed. The starting address of the area to reserve and
	 * also it's length is passed to memblock_reserve(). It will be
	 * freed later on first open of fbdev, when splash image is not
	 * needed any more.
	 */
	if (diu_shared_fb.in_use) {
		ret = memblock_reserve(diu_shared_fb.fb_phys,
				       diu_shared_fb.fb_len);
		if (ret) {
			pr_err("%s: reserve bootmem failed\n", __func__);
			diu_shared_fb.in_use = false;
		}
	}

	diu_ops.set_pixel_clock		= mpc512x_set_pixel_clock;
	diu_ops.valid_monitor_port	= mpc512x_valid_monitor_port;
	diu_ops.release_bootmem		= mpc512x_release_bootmem;
}

void __init mpc512x_init_IRQ(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic");
	if (!np)
		return;

	ipic_init(np, 0);
	of_node_put(np);

	/*
	 * Initialize the default interrupt mapping priorities,
	 * in case the boot rom changed something on us.
	 */
	ipic_set_default_priority();
}

/*
 * Nodes to do bus probe on, soc and localbus
 */
static const struct of_device_id of_bus_ids[] __initconst = {
	{ .compatible = "fsl,mpc5121-immr", },
	{ .compatible = "fsl,mpc5121-localbus", },
	{ .compatible = "fsl,mpc5121-mbx", },
	{ .compatible = "fsl,mpc5121-nfc", },
	{ .compatible = "fsl,mpc5121-sram", },
	{ .compatible = "fsl,mpc5121-pci", },
	{ .compatible = "gpio-leds", },
	{},
};

static void __init mpc512x_declare_of_platform_devices(void)
{
	if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
		printk(KERN_ERR __FILE__ ": "
			"Error while probing of_platform bus\n");
}

#define DEFAULT_FIFO_SIZE 16

const char *mpc512x_select_psc_compat(void)
{
	if (of_machine_is_compatible("fsl,mpc5121"))
		return "fsl,mpc5121-psc";

	if (of_machine_is_compatible("fsl,mpc5125"))
		return "fsl,mpc5125-psc";

	return NULL;
}

const char *mpc512x_select_reset_compat(void)
{
	if (of_machine_is_compatible("fsl,mpc5121"))
		return "fsl,mpc5121-reset";

	if (of_machine_is_compatible("fsl,mpc5125"))
		return "fsl,mpc5125-reset";

	return NULL;
}

static unsigned int __init get_fifo_size(struct device_node *np,
					 char *prop_name)
{
	const unsigned int *fp;

	fp = of_get_property(np, prop_name, NULL);
	if (fp)
		return *fp;

	pr_warning("no %s property in %s node, defaulting to %d\n",
		   prop_name, np->full_name, DEFAULT_FIFO_SIZE);

	return DEFAULT_FIFO_SIZE;
}

#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \
		    ((u32)(_base) + sizeof(struct mpc52xx_psc)))

/* Init PSC FIFO space for TX and RX slices */
static void __init mpc512x_psc_fifo_init(void)
{
	struct device_node *np;
	void __iomem *psc;
	unsigned int tx_fifo_size;
	unsigned int rx_fifo_size;
	const char *psc_compat;
	int fifobase = 0; /* current fifo address in 32 bit words */

	psc_compat = mpc512x_select_psc_compat();
	if (!psc_compat) {
		pr_err("%s: no compatible devices found\n", __func__);
		return;
	}

	for_each_compatible_node(np, NULL, psc_compat) {
		tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
		rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");

		/* size in register is in 4 byte units */
		tx_fifo_size /= 4;
		rx_fifo_size /= 4;
		if (!tx_fifo_size)
			tx_fifo_size = 1;
		if (!rx_fifo_size)
			rx_fifo_size = 1;

		psc = of_iomap(np, 0);
		if (!psc) {
			pr_err("%s: Can't map %s device\n",
				__func__, np->full_name);
			continue;
		}

		/* FIFO space is 4KiB, check if requested size is available */
		if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) {
			pr_err("%s: no fifo space available for %s\n",
				__func__, np->full_name);
			iounmap(psc);
			/*
			 * chances are that another device requests less
			 * fifo space, so we continue.
			 */
			continue;
		}

		/* set tx and rx fifo size registers */
		out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size);
		fifobase += tx_fifo_size;
		out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size);
		fifobase += rx_fifo_size;

		/* reset and enable the slices */
		out_be32(&FIFOC(psc)->txcmd, 0x80);
		out_be32(&FIFOC(psc)->txcmd, 0x01);
		out_be32(&FIFOC(psc)->rxcmd, 0x80);
		out_be32(&FIFOC(psc)->rxcmd, 0x01);

		iounmap(psc);
	}
}

void __init mpc512x_init_early(void)
{
	mpc512x_restart_init();
	if (IS_ENABLED(CONFIG_FB_FSL_DIU))
		mpc512x_init_diu();
}

void __init mpc512x_init(void)
{
	mpc5121_clk_init();
	mpc512x_declare_of_platform_devices();
	mpc512x_psc_fifo_init();
}

void __init mpc512x_setup_arch(void)
{
	if (IS_ENABLED(CONFIG_FB_FSL_DIU))
		mpc512x_setup_diu();
}

/**
 * mpc512x_cs_config - Setup chip select configuration
 * @cs: chip select number
 * @val: chip select configuration value
 *
 * Perform chip select configuration for devices on LocalPlus Bus.
 * Intended to dynamically reconfigure the chip select parameters
 * for configurable devices on the bus.
 */
int mpc512x_cs_config(unsigned int cs, u32 val)
{
	static struct mpc512x_lpc __iomem *lpc;
	struct device_node *np;

	if (cs > 7)
		return -EINVAL;

	if (!lpc) {
		np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-lpc");
		lpc = of_iomap(np, 0);
		of_node_put(np);
		if (!lpc)
			return -ENOMEM;
	}

	out_be32(&lpc->cs_cfg[cs], val);
	return 0;
}
EXPORT_SYMBOL(mpc512x_cs_config);
