/*
 * Platform setup for the Freescale mpc885ads board
 *
 * Vitaly Bordug <vbordug@ru.mvista.com>
 *
 * Copyright 2005 MontaVista Software Inc.
 *
 * Heavily modified by Scott Wood <scottwood@freescale.com>
 * Copyright 2007 Freescale Semiconductor, Inc.
 *
 * 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/init.h>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/delay.h>

#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
#include <linux/fsl_devices.h>
#include <linux/mii.h>
#include <linux/of_platform.h>

#include <asm/delay.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/mpc8xx.h>
#include <asm/8xx_immap.h>
#include <asm/commproc.h>
#include <asm/fs_pd.h>
#include <asm/udbg.h>

#include <sysdev/commproc.h>

static u32 __iomem *bcsr, *bcsr5;

#ifdef CONFIG_PCMCIA_M8XX
static void pcmcia_hw_setup(int slot, int enable)
{
	if (enable)
		clrbits32(&bcsr[1], BCSR1_PCCEN);
	else
		setbits32(&bcsr[1], BCSR1_PCCEN);
}

static int pcmcia_set_voltage(int slot, int vcc, int vpp)
{
	u32 reg = 0;

	switch (vcc) {
	case 0:
		break;
	case 33:
		reg |= BCSR1_PCCVCC0;
		break;
	case 50:
		reg |= BCSR1_PCCVCC1;
		break;
	default:
		return 1;
	}

	switch (vpp) {
	case 0:
		break;
	case 33:
	case 50:
		if (vcc == vpp)
			reg |= BCSR1_PCCVPP1;
		else
			return 1;
		break;
	case 120:
		if ((vcc == 33) || (vcc == 50))
			reg |= BCSR1_PCCVPP0;
		else
			return 1;
	default:
		return 1;
	}

	/* first, turn off all power */
	clrbits32(&bcsr[1], 0x00610000);

	/* enable new powersettings */
	setbits32(&bcsr[1], reg);

	return 0;
}
#endif

struct cpm_pin {
	int port, pin, flags;
};

static struct cpm_pin mpc885ads_pins[] = {
	/* SMC1 */
	{CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
	{CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */

	/* SMC2 */
#ifndef CONFIG_MPC8xx_SECOND_ETH_FEC2
	{CPM_PORTE, 21, CPM_PIN_INPUT}, /* RX */
	{CPM_PORTE, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
#endif

	/* SCC3 */
	{CPM_PORTA, 9, CPM_PIN_INPUT}, /* RX */
	{CPM_PORTA, 8, CPM_PIN_INPUT}, /* TX */
	{CPM_PORTC, 4, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */
	{CPM_PORTC, 5, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */
	{CPM_PORTE, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */
	{CPM_PORTE, 17, CPM_PIN_INPUT}, /* CLK5 */
	{CPM_PORTE, 16, CPM_PIN_INPUT}, /* CLK6 */

	/* MII1 */
	{CPM_PORTA, 0, CPM_PIN_INPUT},
	{CPM_PORTA, 1, CPM_PIN_INPUT},
	{CPM_PORTA, 2, CPM_PIN_INPUT},
	{CPM_PORTA, 3, CPM_PIN_INPUT},
	{CPM_PORTA, 4, CPM_PIN_OUTPUT},
	{CPM_PORTA, 10, CPM_PIN_OUTPUT},
	{CPM_PORTA, 11, CPM_PIN_OUTPUT},
	{CPM_PORTB, 19, CPM_PIN_INPUT},
	{CPM_PORTB, 31, CPM_PIN_INPUT},
	{CPM_PORTC, 12, CPM_PIN_INPUT},
	{CPM_PORTC, 13, CPM_PIN_INPUT},
	{CPM_PORTE, 30, CPM_PIN_OUTPUT},
	{CPM_PORTE, 31, CPM_PIN_OUTPUT},

	/* MII2 */
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
	{CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 16, CPM_PIN_OUTPUT},
	{CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
	{CPM_PORTE, 21, CPM_PIN_OUTPUT},
	{CPM_PORTE, 22, CPM_PIN_OUTPUT},
	{CPM_PORTE, 23, CPM_PIN_OUTPUT},
	{CPM_PORTE, 24, CPM_PIN_OUTPUT},
	{CPM_PORTE, 25, CPM_PIN_OUTPUT},
	{CPM_PORTE, 26, CPM_PIN_OUTPUT},
	{CPM_PORTE, 27, CPM_PIN_OUTPUT},
	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
#endif
};

static void __init init_ioports(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mpc885ads_pins); i++) {
		struct cpm_pin *pin = &mpc885ads_pins[i];
		cpm1_set_pin(pin->port, pin->pin, pin->flags);
	}

	cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
	cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX);
	cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_TX);
	cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX);

	/* Set FEC1 and FEC2 to MII mode */
	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
}

static void __init mpc885ads_setup_arch(void)
{
	struct device_node *np;

	cpm_reset();
	init_ioports();

	np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr");
	if (!np) {
		printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n");
		return;
	}

	bcsr = of_iomap(np, 0);
	bcsr5 = of_iomap(np, 1);
	of_node_put(np);

	if (!bcsr || !bcsr5) {
		printk(KERN_CRIT "Could not remap BCSR\n");
		return;
	}

	clrbits32(&bcsr[1], BCSR1_RS232EN_1);
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
	setbits32(&bcsr[1], BCSR1_RS232EN_2);
#else
	clrbits32(&bcsr[1], BCSR1_RS232EN_2);
#endif

	clrbits32(bcsr5, BCSR5_MII1_EN);
	setbits32(bcsr5, BCSR5_MII1_RST);
	udelay(1000);
	clrbits32(bcsr5, BCSR5_MII1_RST);

#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
	clrbits32(bcsr5, BCSR5_MII2_EN);
	setbits32(bcsr5, BCSR5_MII2_RST);
	udelay(1000);
	clrbits32(bcsr5, BCSR5_MII2_RST);
#else
	setbits32(bcsr5, BCSR5_MII2_EN);
#endif

#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
	clrbits32(&bcsr[4], BCSR4_ETH10_RST);
	udelay(1000);
	setbits32(&bcsr[4], BCSR4_ETH10_RST);

	setbits32(&bcsr[1], BCSR1_ETHEN);

	np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
#else
	np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40");
#endif

	/* The SCC3 enet registers overlap the SMC1 registers, so
	 * one of the two must be removed from the device tree.
	 */

	if (np) {
		of_detach_node(np);
		of_node_put(np);
	}

#ifdef CONFIG_PCMCIA_M8XX
	/* Set up board specific hook-ups.*/
	m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
	m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
#endif
}

static int __init mpc885ads_probe(void)
{
	unsigned long root = of_get_flat_dt_root();
	return of_flat_dt_is_compatible(root, "fsl,mpc885ads");
}

static struct of_device_id __initdata of_bus_ids[] = {
	{ .name = "soc", },
	{ .name = "cpm", },
	{ .name = "localbus", },
	{},
};

static int __init declare_of_platform_devices(void)
{
	/* Publish the QE devices */
	if (machine_is(mpc885_ads))
		of_platform_bus_probe(NULL, of_bus_ids, NULL);

	return 0;
}
device_initcall(declare_of_platform_devices);

define_machine(mpc885_ads) {
	.name			= "Freescale MPC885 ADS",
	.probe			= mpc885ads_probe,
	.setup_arch		= mpc885ads_setup_arch,
	.init_IRQ		= m8xx_pic_init,
	.get_irq		= mpc8xx_get_irq,
	.restart		= mpc8xx_restart,
	.calibrate_decr		= mpc8xx_calibrate_decr,
	.set_rtc_time		= mpc8xx_set_rtc_time,
	.get_rtc_time		= mpc8xx_get_rtc_time,
	.progress		= udbg_progress,
};
