/*
 * Altera SoCFPGA Specific Extensions for Synopsys DW Multimedia Card Interface
 * driver
 *
 *  Copyright (C) 2012, Samsung Electronics Co., Ltd.
 *  Copyright (C) 2013 Altera Corporation
 *
 * 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.
 *
 * Taken from dw_mmc-exynos.c
 */
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/mmc/host.h>
#include <linux/mmc/dw_mmc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"

#define SYSMGR_SDMMCGRP_CTRL_OFFSET		0x108
#define DRV_CLK_PHASE_SHIFT_SEL_MASK	0x7
#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)          \
	((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))

/* SOCFPGA implementation specific driver private data */
struct dw_mci_socfpga_priv_data {
	u8	ciu_div; /* card interface unit divisor */
	u32	hs_timing; /* bitmask for CIU clock phase shift */
	struct regmap   *sysreg; /* regmap for system manager register */
};

static int dw_mci_socfpga_priv_init(struct dw_mci *host)
{
	return 0;
}

static int dw_mci_socfpga_setup_clock(struct dw_mci *host)
{
	struct dw_mci_socfpga_priv_data *priv = host->priv;

	clk_disable_unprepare(host->ciu_clk);
	regmap_write(priv->sysreg, SYSMGR_SDMMCGRP_CTRL_OFFSET,
		priv->hs_timing);
	clk_prepare_enable(host->ciu_clk);

	host->bus_hz /= (priv->ciu_div + 1);
	return 0;
}

static void dw_mci_socfpga_prepare_command(struct dw_mci *host, u32 *cmdr)
{
	struct dw_mci_socfpga_priv_data *priv = host->priv;

	if (priv->hs_timing & DRV_CLK_PHASE_SHIFT_SEL_MASK)
		*cmdr |= SDMMC_CMD_USE_HOLD_REG;
}

static int dw_mci_socfpga_parse_dt(struct dw_mci *host)
{
	struct dw_mci_socfpga_priv_data *priv;
	struct device_node *np = host->dev->of_node;
	u32 timing[2];
	u32 div = 0;
	int ret;

	priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(host->dev, "mem alloc failed for private data\n");
		return -ENOMEM;
	}

	priv->sysreg = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
	if (IS_ERR(priv->sysreg)) {
		dev_err(host->dev, "regmap for altr,sys-mgr lookup failed.\n");
		return PTR_ERR(priv->sysreg);
	}

	ret = of_property_read_u32(np, "altr,dw-mshc-ciu-div", &div);
	if (ret)
		dev_info(host->dev, "No dw-mshc-ciu-div specified, assuming 1");
	priv->ciu_div = div;

	ret = of_property_read_u32_array(np,
			"altr,dw-mshc-sdr-timing", timing, 2);
	if (ret)
		return ret;

	priv->hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[0], timing[1]);
	host->priv = priv;
	return 0;
}

static const struct dw_mci_drv_data socfpga_drv_data = {
	.init			= dw_mci_socfpga_priv_init,
	.setup_clock		= dw_mci_socfpga_setup_clock,
	.prepare_command	= dw_mci_socfpga_prepare_command,
	.parse_dt		= dw_mci_socfpga_parse_dt,
};

static const struct of_device_id dw_mci_socfpga_match[] = {
	{ .compatible = "altr,socfpga-dw-mshc",
			.data = &socfpga_drv_data, },
	{},
};
MODULE_DEVICE_TABLE(of, dw_mci_socfpga_match);

static int dw_mci_socfpga_probe(struct platform_device *pdev)
{
	const struct dw_mci_drv_data *drv_data;
	const struct of_device_id *match;

	match = of_match_node(dw_mci_socfpga_match, pdev->dev.of_node);
	drv_data = match->data;
	return dw_mci_pltfm_register(pdev, drv_data);
}

static struct platform_driver dw_mci_socfpga_pltfm_driver = {
	.probe		= dw_mci_socfpga_probe,
	.remove		= __exit_p(dw_mci_pltfm_remove),
	.driver		= {
		.name		= "dwmmc_socfpga",
		.of_match_table	= dw_mci_socfpga_match,
		.pm		= &dw_mci_pltfm_pmops,
	},
};

module_platform_driver(dw_mci_socfpga_pltfm_driver);

MODULE_DESCRIPTION("Altera SOCFPGA Specific DW-MSHC Driver Extension");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:dwmmc-socfpga");
