/*
 *  (C) Copyright 2010-2012
 *  NVIDIA Corporation <www.nvidia.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <asm/io.h>
#include <asm/arch/pinmux.h>
#include "pinmux-config-cardhu.h"

#include <asm/arch/clock.h>
#include <asm/arch/gp_padctrl.h>
#include <asm/arch/pmu.h>
#include <asm/arch/sdmmc.h>
#include <asm/arch-tegra/mmc.h>
#include <asm/arch-tegra/tegra_mmc.h>
#include <mmc.h>
#include <i2c.h>

/*
 * Routine: pinmux_init
 * Description: Do individual peripheral pinmux configs
 */
void pinmux_init(void)
{
	pinmux_config_table(tegra3_pinmux_common,
		ARRAY_SIZE(tegra3_pinmux_common));

	pinmux_config_table(unused_pins_lowpower,
		ARRAY_SIZE(unused_pins_lowpower));
}

#if defined(CONFIG_MMC)
/*
 * Routine: pin_mux_mmc
 * Description: setup the pin muxes/tristate values for the SDMMC(s)
 */
static void pin_mux_mmc(void)
{
}

/* Do I2C/PMU writes to bring up SD card bus power */
static void board_sdmmc_voltage_init(void)
{
        uchar reg, data_buffer[1];
        int i;

        i2c_set_bus_num(0);             /* PMU is on bus 0 */

        data_buffer[0] = 0x65;
        reg = 0x32;

        for (i = 0; i < MAX_I2C_RETRY; ++i) {
                if (i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1))
                        udelay(100);
        }

        data_buffer[0] = 0x09;
        reg = 0x67;

        for (i = 0; i < MAX_I2C_RETRY; ++i) {
                if (i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1))
                        udelay(100);
        }
}

static void pad_init_mmc(struct tegra_mmc *reg)
{
        struct apb_misc_gp_ctlr *const gpc =
                (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
        struct sdmmc_ctlr *const sdmmc = (struct sdmmc_ctlr *)reg;
        u32 val, offset = (unsigned int)reg;
        u32 padcfg, padmask;

        debug("%s: sdmmc address = %08x\n", __func__, (unsigned int)sdmmc);

        /* Set the pad drive strength for SDMMC1 or 3 only */
        if (offset != TEGRA_SDMMC1_BASE && offset != TEGRA_SDMMC3_BASE) {
                debug("%s: settings are only valid for SDMMC1/SDMMC3!\n",
                        __func__);
                return;
        }

        /* Set pads as per T30 TRM, section 24.6.1.2 */
        padcfg = (GP_SDIOCFG_DRVUP_SLWF | GP_SDIOCFG_DRVDN_SLWR | \
                GP_SDIOCFG_DRVUP | GP_SDIOCFG_DRVDN);
        padmask = 0x00000FFF;
        if (offset == TEGRA_SDMMC1_BASE) {
                val = readl(&gpc->sdio1cfg);
                val &= padmask;
                val |= padcfg;
                writel(val, &gpc->sdio1cfg);
        } else {                                /* SDMMC3 */
                val = readl(&gpc->sdio3cfg);
                val &= padmask;
                val |= padcfg;
                writel(val, &gpc->sdio3cfg);
        }

        val = readl(&sdmmc->sdmmc_sdmemcomp_pad_ctrl);
        val &= 0xFFFFFFF0;
        val |= MEMCOMP_PADCTRL_VREF;
        writel(val, &sdmmc->sdmmc_sdmemcomp_pad_ctrl);

        val = readl(&sdmmc->sdmmc_auto_cal_config);
        val &= 0xFFFF0000;
        val |= AUTO_CAL_PU_OFFSET | AUTO_CAL_PD_OFFSET | AUTO_CAL_ENABLED;
        writel(val, &sdmmc->sdmmc_auto_cal_config);
}

/* this is a weak define that we are overriding */
int board_mmc_init(bd_t *bd)
{
	debug("board_mmc_init called\n");

	/* Turn on SD-card bus power */
	board_sdmmc_voltage_init();

	/* Set up the SDMMC pads as per the TRM */
	pad_init_mmc((struct tegra_mmc *)TEGRA_SDMMC1_BASE);

	/* Enable muxes, etc. for SDMMC controllers */
	pin_mux_mmc();

	/* init dev 0 (SDMMC4), ("HSMMC") with 8-bit bus */
	tegra_mmc_init(0, 8, -1, -1);

	/* init dev 1 (SDMMC0), ("SDIO") with 8-bit bus */
	tegra_mmc_init(1, 8, -1, -1);

	return 0;
}
#endif	/* MMC */
