/*
 * arch/arm/mach-orion5x/addr-map.c
 *
 * Address map functions for Marvell Orion 5x SoCs
 *
 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <mach/hardware.h>
#include "common.h"

/*
 * The Orion has fully programmable address map. There's a separate address
 * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
 * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
 * address decode windows that allow it to access any of the Orion resources.
 *
 * CPU address decoding --
 * Linux assumes that it is the boot loader that already setup the access to
 * DDR and internal registers.
 * Setup access to PCI and PCIe IO/MEM space is issued by this file.
 * Setup access to various devices located on the device bus interface (e.g.
 * flashes, RTC, etc) should be issued by machine-setup.c according to
 * specific board population (by using orion5x_setup_*_win()).
 *
 * Non-CPU Masters address decoding --
 * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
 * banks only (the typical use case).
 * Setup access for each master to DDR is issued by platform device setup.
 */

/*
 * Generic Address Decode Windows bit settings
 */
#define TARGET_DDR		0
#define TARGET_DEV_BUS		1
#define TARGET_PCI		3
#define TARGET_PCIE		4
#define TARGET_SRAM		9
#define ATTR_PCIE_MEM		0x59
#define ATTR_PCIE_IO		0x51
#define ATTR_PCIE_WA		0x79
#define ATTR_PCI_MEM		0x59
#define ATTR_PCI_IO		0x51
#define ATTR_DEV_CS0		0x1e
#define ATTR_DEV_CS1		0x1d
#define ATTR_DEV_CS2		0x1b
#define ATTR_DEV_BOOT		0xf
#define ATTR_SRAM		0x0

/*
 * Helpers to get DDR bank info
 */
#define ORION5X_DDR_REG(x)	(ORION5X_DDR_VIRT_BASE | (x))
#define DDR_BASE_CS(n)		ORION5X_DDR_REG(0x1500 + ((n) << 3))
#define DDR_SIZE_CS(n)		ORION5X_DDR_REG(0x1504 + ((n) << 3))

/*
 * CPU Address Decode Windows registers
 */
#define ORION5X_BRIDGE_REG(x)	(ORION5X_BRIDGE_VIRT_BASE | (x))
#define CPU_WIN_CTRL(n)		ORION5X_BRIDGE_REG(0x000 | ((n) << 4))
#define CPU_WIN_BASE(n)		ORION5X_BRIDGE_REG(0x004 | ((n) << 4))
#define CPU_WIN_REMAP_LO(n)	ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
#define CPU_WIN_REMAP_HI(n)	ORION5X_BRIDGE_REG(0x00c | ((n) << 4))


struct mbus_dram_target_info orion5x_mbus_dram_info;
static int __initdata win_alloc_count;

static int __init orion5x_cpu_win_can_remap(int win)
{
	u32 dev, rev;

	orion5x_pcie_id(&dev, &rev);
	if ((dev == MV88F5281_DEV_ID && win < 4)
	    || (dev == MV88F5182_DEV_ID && win < 2)
	    || (dev == MV88F5181_DEV_ID && win < 2)
	    || (dev == MV88F6183_DEV_ID && win < 4))
		return 1;

	return 0;
}

static int __init setup_cpu_win(int win, u32 base, u32 size,
				 u8 target, u8 attr, int remap)
{
	if (win >= 8) {
		printk(KERN_ERR "setup_cpu_win: trying to allocate "
				"window %d\n", win);
		return -ENOSPC;
	}

	writel(base & 0xffff0000, CPU_WIN_BASE(win));
	writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1,
		CPU_WIN_CTRL(win));

	if (orion5x_cpu_win_can_remap(win)) {
		if (remap < 0)
			remap = base;

		writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
		writel(0, CPU_WIN_REMAP_HI(win));
	}
	return 0;
}

void __init orion5x_setup_cpu_mbus_bridge(void)
{
	int i;
	int cs;

	/*
	 * First, disable and clear windows.
	 */
	for (i = 0; i < 8; i++) {
		writel(0, CPU_WIN_BASE(i));
		writel(0, CPU_WIN_CTRL(i));
		if (orion5x_cpu_win_can_remap(i)) {
			writel(0, CPU_WIN_REMAP_LO(i));
			writel(0, CPU_WIN_REMAP_HI(i));
		}
	}

	/*
	 * Setup windows for PCI+PCIe IO+MEM space.
	 */
	setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
		TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE);
	setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
		TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE);
	setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
		TARGET_PCIE, ATTR_PCIE_MEM, -1);
	setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
		TARGET_PCI, ATTR_PCI_MEM, -1);
	win_alloc_count = 4;

	/*
	 * Setup MBUS dram target info.
	 */
	orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;

	for (i = 0, cs = 0; i < 4; i++) {
		u32 base = readl(DDR_BASE_CS(i));
		u32 size = readl(DDR_SIZE_CS(i));

		/*
		 * Chip select enabled?
		 */
		if (size & 1) {
			struct mbus_dram_window *w;

			w = &orion5x_mbus_dram_info.cs[cs++];
			w->cs_index = i;
			w->mbus_attr = 0xf & ~(1 << i);
			w->base = base & 0xffff0000;
			w->size = (size | 0x0000ffff) + 1;
		}
	}
	orion5x_mbus_dram_info.num_cs = cs;
}

void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
{
	setup_cpu_win(win_alloc_count++, base, size,
		      TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
}

void __init orion5x_setup_dev0_win(u32 base, u32 size)
{
	setup_cpu_win(win_alloc_count++, base, size,
		      TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
}

void __init orion5x_setup_dev1_win(u32 base, u32 size)
{
	setup_cpu_win(win_alloc_count++, base, size,
		      TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
}

void __init orion5x_setup_dev2_win(u32 base, u32 size)
{
	setup_cpu_win(win_alloc_count++, base, size,
		      TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
}

void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
{
	setup_cpu_win(win_alloc_count++, base, size,
		      TARGET_PCIE, ATTR_PCIE_WA, -1);
}

int __init orion5x_setup_sram_win(void)
{
	return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE,
			ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1);
}
