/*
 * OpenFirmware bindings for Secure Digital Host Controller Interface.
 *
 * Copyright (c) 2007 Freescale Semiconductor, Inc.
 * Copyright (c) 2009 MontaVista Software, Inc.
 *
 * Authors: Xiaobo Xie <X.Xie@freescale.com>
 *	    Anton Vorontsov <avorontsov@ru.mvista.com>
 *
 * 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; either version 2 of the License, or (at
 * your option) any later version.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/mmc/host.h>
#include "sdhci.h"

struct sdhci_of_data {
	unsigned int quirks;
	struct sdhci_ops ops;
};

struct sdhci_of_host {
	unsigned int clock;
	u16 xfer_mode_shadow;
};

/*
 * Ops and quirks for the Freescale eSDHC controller.
 */

#define ESDHC_DMA_SYSCTL	0x40c
#define ESDHC_DMA_SNOOP		0x00000040

#define ESDHC_SYSTEM_CONTROL	0x2c
#define ESDHC_CLOCK_MASK	0x0000fff0
#define ESDHC_PREDIV_SHIFT	8
#define ESDHC_DIVIDER_SHIFT	4
#define ESDHC_CLOCK_PEREN	0x00000004
#define ESDHC_CLOCK_HCKEN	0x00000002
#define ESDHC_CLOCK_IPGEN	0x00000001

static u32 esdhc_readl(struct sdhci_host *host, int reg)
{
	return in_be32(host->ioaddr + reg);
}

static u16 esdhc_readw(struct sdhci_host *host, int reg)
{
	u16 ret;

	if (unlikely(reg == SDHCI_HOST_VERSION))
		ret = in_be16(host->ioaddr + reg);
	else
		ret = in_be16(host->ioaddr + (reg ^ 0x2));
	return ret;
}

static u8 esdhc_readb(struct sdhci_host *host, int reg)
{
	return in_8(host->ioaddr + (reg ^ 0x3));
}

static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
{
	out_be32(host->ioaddr + reg, val);
}

static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
{
	struct sdhci_of_host *of_host = sdhci_priv(host);
	int base = reg & ~0x3;
	int shift = (reg & 0x2) * 8;

	switch (reg) {
	case SDHCI_TRANSFER_MODE:
		/*
		 * Postpone this write, we must do it together with a
		 * command write that is down below.
		 */
		of_host->xfer_mode_shadow = val;
		return;
	case SDHCI_COMMAND:
		esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
			     SDHCI_TRANSFER_MODE);
		return;
	case SDHCI_BLOCK_SIZE:
		/*
		 * Two last DMA bits are reserved, and first one is used for
		 * non-standard blksz of 4096 bytes that we don't support
		 * yet. So clear the DMA boundary bits.
		 */
		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
		/* fall through */
	}
	clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
}

static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
{
	int base = reg & ~0x3;
	int shift = (reg & 0x3) * 8;

	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
}

static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
{
	int div;
	int pre_div = 2;

	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);

	if (clock == 0)
		goto out;

	if (host->max_clk / 16 > clock) {
		for (; pre_div < 256; pre_div *= 2) {
			if (host->max_clk / pre_div < clock * 16)
				break;
		}
	}

	for (div = 1; div <= 16; div++) {
		if (host->max_clk / (div * pre_div) <= clock)
			break;
	}

	pre_div >>= 1;

	setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
		  div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
	mdelay(100);
out:
	host->clock = clock;
}

static int esdhc_enable_dma(struct sdhci_host *host)
{
	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
	return 0;
}

static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_of_host *of_host = sdhci_priv(host);

	return of_host->clock;
}

static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
{
	struct sdhci_of_host *of_host = sdhci_priv(host);

	return of_host->clock / 1000;
}

static struct sdhci_of_data sdhci_esdhc = {
	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
		  SDHCI_QUIRK_NO_BUSY_IRQ |
		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
		  SDHCI_QUIRK_PIO_NEEDS_DELAY |
		  SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
		  SDHCI_QUIRK_NO_CARD_NO_RESET,
	.ops = {
		.readl = esdhc_readl,
		.readw = esdhc_readw,
		.readb = esdhc_readb,
		.writel = esdhc_writel,
		.writew = esdhc_writew,
		.writeb = esdhc_writeb,
		.set_clock = esdhc_set_clock,
		.enable_dma = esdhc_enable_dma,
		.get_max_clock = esdhc_get_max_clock,
		.get_timeout_clock = esdhc_get_timeout_clock,
	},
};

#ifdef CONFIG_PM

static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
{
	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);

	return mmc_suspend_host(host->mmc, state);
}

static int sdhci_of_resume(struct of_device *ofdev)
{
	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);

	return mmc_resume_host(host->mmc);
}

#else

#define sdhci_of_suspend NULL
#define sdhci_of_resume NULL

#endif

static int __devinit sdhci_of_probe(struct of_device *ofdev,
				 const struct of_device_id *match)
{
	struct device_node *np = ofdev->node;
	struct sdhci_of_data *sdhci_of_data = match->data;
	struct sdhci_host *host;
	struct sdhci_of_host *of_host;
	const u32 *clk;
	int size;
	int ret;

	if (!of_device_is_available(np))
		return -ENODEV;

	host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
	if (!host)
		return -ENOMEM;

	of_host = sdhci_priv(host);
	dev_set_drvdata(&ofdev->dev, host);

	host->ioaddr = of_iomap(np, 0);
	if (!host->ioaddr) {
		ret = -ENOMEM;
		goto err_addr_map;
	}

	host->irq = irq_of_parse_and_map(np, 0);
	if (!host->irq) {
		ret = -EINVAL;
		goto err_no_irq;
	}

	host->hw_name = dev_name(&ofdev->dev);
	if (sdhci_of_data) {
		host->quirks = sdhci_of_data->quirks;
		host->ops = &sdhci_of_data->ops;
	}

	clk = of_get_property(np, "clock-frequency", &size);
	if (clk && size == sizeof(*clk) && *clk)
		of_host->clock = *clk;

	ret = sdhci_add_host(host);
	if (ret)
		goto err_add_host;

	return 0;

err_add_host:
	irq_dispose_mapping(host->irq);
err_no_irq:
	iounmap(host->ioaddr);
err_addr_map:
	sdhci_free_host(host);
	return ret;
}

static int __devexit sdhci_of_remove(struct of_device *ofdev)
{
	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);

	sdhci_remove_host(host, 0);
	sdhci_free_host(host);
	irq_dispose_mapping(host->irq);
	iounmap(host->ioaddr);
	return 0;
}

static const struct of_device_id sdhci_of_match[] = {
	{ .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
	{ .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
	{ .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
	{ .compatible = "generic-sdhci", },
	{},
};
MODULE_DEVICE_TABLE(of, sdhci_of_match);

static struct of_platform_driver sdhci_of_driver = {
	.driver.name = "sdhci-of",
	.match_table = sdhci_of_match,
	.probe = sdhci_of_probe,
	.remove = __devexit_p(sdhci_of_remove),
	.suspend = sdhci_of_suspend,
	.resume	= sdhci_of_resume,
};

static int __init sdhci_of_init(void)
{
	return of_register_platform_driver(&sdhci_of_driver);
}
module_init(sdhci_of_init);

static void __exit sdhci_of_exit(void)
{
	of_unregister_platform_driver(&sdhci_of_driver);
}
module_exit(sdhci_of_exit);

MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
	      "Anton Vorontsov <avorontsov@ru.mvista.com>");
MODULE_LICENSE("GPL");
