/*
 * Copyright 2013 Broadcom Corporation.
 *
 * SPDX-License-Identifier:      GPL-2.0+
 */

#include <common.h>
#include <malloc.h>
#include <sdhci.h>
#include <asm/errno.h>
#include <asm/kona-common/clk.h>

#define SDHCI_CORECTRL_OFFSET		0x00008000
#define SDHCI_CORECTRL_EN		0x01
#define SDHCI_CORECTRL_RESET		0x02

#define SDHCI_CORESTAT_OFFSET		0x00008004
#define SDHCI_CORESTAT_CD_SW		0x01

#define SDHCI_COREIMR_OFFSET		0x00008008
#define SDHCI_COREIMR_IP		0x01

static int init_kona_mmc_core(struct sdhci_host *host)
{
	unsigned int mask;
	unsigned int timeout;

	if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
		printf("%s: sd host controller reset error\n", __func__);
		return 1;
	}

	/* For kona a hardware reset before anything else. */
	mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET;
	sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);

	/* Wait max 100 ms */
	timeout = 1000;
	do {
		if (timeout == 0) {
			printf("%s: reset timeout error\n", __func__);
			return 1;
		}
		timeout--;
		udelay(100);
	} while (0 ==
		 (sdhci_readl(host, SDHCI_CORECTRL_OFFSET) &
		  SDHCI_CORECTRL_RESET));

	/* Clear the reset bit. */
	mask = mask & ~SDHCI_CORECTRL_RESET;
	sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);

	/* Enable AHB clock */
	mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET);
	sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET);

	/* Enable interrupts */
	sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET);

	/* Make sure Card is detected in controller */
	mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET);
	sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET);

	/* Wait max 100 ms */
	timeout = 1000;
	while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
		if (timeout == 0) {
			printf("%s: CARD DETECT timeout error\n", __func__);
			return 1;
		}
		timeout--;
		udelay(100);
	}
	return 0;
}

int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
{
	int ret = 0;
	u32 max_clk;
	void *reg_base;
	struct sdhci_host *host = NULL;

	host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
	if (!host) {
		printf("%s: sdhci host malloc fail!\n", __func__);
		return -ENOMEM;
	}
	switch (dev_index) {
	case 0:
		reg_base = (void *)CONFIG_SYS_SDIO_BASE0;
		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK,
				      &max_clk);
		break;
	case 1:
		reg_base = (void *)CONFIG_SYS_SDIO_BASE1;
		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK,
				      &max_clk);
		break;
	case 2:
		reg_base = (void *)CONFIG_SYS_SDIO_BASE2;
		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK,
				      &max_clk);
		break;
	case 3:
		reg_base = (void *)CONFIG_SYS_SDIO_BASE3;
		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK,
				      &max_clk);
		break;
	default:
		printf("%s: sdio dev index %d not supported\n",
		       __func__, dev_index);
		ret = -EINVAL;
	}
	if (ret)
		return ret;

	host->name = "kona-sdhci";
	host->ioaddr = reg_base;
	host->quirks = quirks;
	host->host_caps = MMC_MODE_HC;

	if (init_kona_mmc_core(host))
		return -EINVAL;

	if (quirks & SDHCI_QUIRK_REG32_RW)
		host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
	else
		host->version = sdhci_readw(host, SDHCI_HOST_VERSION);

	add_sdhci(host, max_clk, min_clk);
	return ret;
}
