/*
 * 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/cpm1.h>
#include <asm/fs_pd.h>
#include <asm/udbg.h>

#include "mpc885ads.h"
#include "mpc8xx.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
	/* I2C */
	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
};

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 */
	of_platform_bus_probe(NULL, of_bus_ids, NULL);

	return 0;
}
machine_device_initcall(mpc885_ads, declare_of_platform_devices);

define_machine(mpc885_ads) {
	.name			= "Freescale MPC885 ADS",
	.probe			= mpc885ads_probe,
	.setup_arch		= mpc885ads_setup_arch,
	.init_IRQ		= mpc8xx_pics_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,
};
