// SPDX-License-Identifier: GPL-2.0
/*
 * bcm2835 sdhost driver.
 *
 * The 2835 has two SD controllers: The Arasan sdhci controller
 * (supported by the iproc driver) and a custom sdhost controller
 * (supported by this driver).
 *
 * The sdhci controller supports both sdcard and sdio.  The sdhost
 * controller supports the sdcard only, but has better performance.
 * Also note that the rpi3 has sdio wifi, so driving the sdcard with
 * the sdhost controller allows to use the sdhci controller for wifi
 * support.
 *
 * The configuration is done by devicetree via pin muxing.  Both
 * SD controller are available on the same pins (2 pin groups = pin 22
 * to 27 + pin 48 to 53).  So it's possible to use both SD controllers
 * at the same time with different pin groups.
 *
 * This code was ported to U-Boot by
 *  Alexander Graf <agraf@suse.de>
 * and is based on drivers/mmc/host/bcm2835.c in Linux which is written by
 *  Phil Elwell <phil@raspberrypi.org>
 *  Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd.
 * which is based on
 *  mmc-bcm2835.c by Gellert Weisz
 * which is, in turn, based on
 *  sdhci-bcm2708.c by Broadcom
 *  sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko
 *  sdhci.c and sdhci-pci.c by Pierre Ossman
 */
#include <clk.h>
#include <common.h>
#include <dm.h>
#include <mmc.h>
#include <asm/arch/msg.h>
#include <asm/arch/mbox.h>
#include <asm/unaligned.h>
#include <linux/compat.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
#include <mach/gpio.h>
#include <power/regulator.h>

#define msleep(a) udelay(a * 1000)

#define SDCMD  0x00 /* Command to SD card              - 16 R/W */
#define SDARG  0x04 /* Argument to SD card             - 32 R/W */
#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */
#define SDCDIV 0x0c /* Start value for clock divider   - 11 R/W */
#define SDRSP0 0x10 /* SD card response (31:0)         - 32 R   */
#define SDRSP1 0x14 /* SD card response (63:32)        - 32 R   */
#define SDRSP2 0x18 /* SD card response (95:64)        - 32 R   */
#define SDRSP3 0x1c /* SD card response (127:96)       - 32 R   */
#define SDHSTS 0x20 /* SD host status                  - 11 R/W */
#define SDVDD  0x30 /* SD card power control           -  1 R/W */
#define SDEDM  0x34 /* Emergency Debug Mode            - 13 R/W */
#define SDHCFG 0x38 /* Host configuration              -  2 R/W */
#define SDHBCT 0x3c /* Host byte count (debug)         - 32 R/W */
#define SDDATA 0x40 /* Data to/from SD card            - 32 R/W */
#define SDHBLC 0x50 /* Host block count (SDIO/SDHC)    -  9 R/W */

#define SDCMD_NEW_FLAG			0x8000
#define SDCMD_FAIL_FLAG			0x4000
#define SDCMD_BUSYWAIT			0x800
#define SDCMD_NO_RESPONSE		0x400
#define SDCMD_LONG_RESPONSE		0x200
#define SDCMD_WRITE_CMD			0x80
#define SDCMD_READ_CMD			0x40
#define SDCMD_CMD_MASK			0x3f

#define SDCDIV_MAX_CDIV			0x7ff

#define SDHSTS_BUSY_IRPT		0x400
#define SDHSTS_BLOCK_IRPT		0x200
#define SDHSTS_SDIO_IRPT		0x100
#define SDHSTS_REW_TIME_OUT		0x80
#define SDHSTS_CMD_TIME_OUT		0x40
#define SDHSTS_CRC16_ERROR		0x20
#define SDHSTS_CRC7_ERROR		0x10
#define SDHSTS_FIFO_ERROR		0x08
#define SDHSTS_DATA_FLAG		0x01

#define SDHSTS_CLEAR_MASK		(SDHSTS_BUSY_IRPT | \
					 SDHSTS_BLOCK_IRPT | \
					 SDHSTS_SDIO_IRPT | \
					 SDHSTS_REW_TIME_OUT | \
					 SDHSTS_CMD_TIME_OUT | \
					 SDHSTS_CRC16_ERROR | \
					 SDHSTS_CRC7_ERROR | \
					 SDHSTS_FIFO_ERROR)

#define SDHSTS_TRANSFER_ERROR_MASK	(SDHSTS_CRC7_ERROR | \
					 SDHSTS_CRC16_ERROR | \
					 SDHSTS_REW_TIME_OUT | \
					 SDHSTS_FIFO_ERROR)

#define SDHSTS_ERROR_MASK		(SDHSTS_CMD_TIME_OUT | \
					 SDHSTS_TRANSFER_ERROR_MASK)

#define SDHCFG_BUSY_IRPT_EN	BIT(10)
#define SDHCFG_BLOCK_IRPT_EN	BIT(8)
#define SDHCFG_SDIO_IRPT_EN	BIT(5)
#define SDHCFG_DATA_IRPT_EN	BIT(4)
#define SDHCFG_SLOW_CARD	BIT(3)
#define SDHCFG_WIDE_EXT_BUS	BIT(2)
#define SDHCFG_WIDE_INT_BUS	BIT(1)
#define SDHCFG_REL_CMD_LINE	BIT(0)

#define SDVDD_POWER_OFF		0
#define SDVDD_POWER_ON		1

#define SDEDM_FORCE_DATA_MODE	BIT(19)
#define SDEDM_CLOCK_PULSE	BIT(20)
#define SDEDM_BYPASS		BIT(21)

#define SDEDM_FIFO_FILL_SHIFT	4
#define SDEDM_FIFO_FILL_MASK	0x1f
static u32 edm_fifo_fill(u32 edm)
{
	return (edm >> SDEDM_FIFO_FILL_SHIFT) & SDEDM_FIFO_FILL_MASK;
}

#define SDEDM_WRITE_THRESHOLD_SHIFT	9
#define SDEDM_READ_THRESHOLD_SHIFT	14
#define SDEDM_THRESHOLD_MASK		0x1f

#define SDEDM_FSM_MASK		0xf
#define SDEDM_FSM_IDENTMODE	0x0
#define SDEDM_FSM_DATAMODE	0x1
#define SDEDM_FSM_READDATA	0x2
#define SDEDM_FSM_WRITEDATA	0x3
#define SDEDM_FSM_READWAIT	0x4
#define SDEDM_FSM_READCRC	0x5
#define SDEDM_FSM_WRITECRC	0x6
#define SDEDM_FSM_WRITEWAIT1	0x7
#define SDEDM_FSM_POWERDOWN	0x8
#define SDEDM_FSM_POWERUP	0x9
#define SDEDM_FSM_WRITESTART1	0xa
#define SDEDM_FSM_WRITESTART2	0xb
#define SDEDM_FSM_GENPULSES	0xc
#define SDEDM_FSM_WRITEWAIT2	0xd
#define SDEDM_FSM_STARTPOWDOWN	0xf

#define SDDATA_FIFO_WORDS	16

#define FIFO_READ_THRESHOLD	4
#define FIFO_WRITE_THRESHOLD	4
#define SDDATA_FIFO_PIO_BURST	8

#define SDHST_TIMEOUT_MAX_USEC	100000

struct bcm2835_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

struct bcm2835_host {
	void __iomem		*ioaddr;
	u32			phys_addr;

	int			clock;		/* Current clock speed */
	unsigned int		max_clk;	/* Max possible freq */
	unsigned int		blocks;		/* remaining PIO blocks */

	u32			ns_per_fifo_word;

	/* cached registers */
	u32			hcfg;
	u32			cdiv;

	struct mmc_cmd	*cmd;		/* Current command */
	struct mmc_data		*data;		/* Current data request */
	bool			use_busy:1;	/* Wait for busy interrupt */

	struct udevice		*dev;
	struct mmc		*mmc;
	struct bcm2835_plat	*plat;
};

static void bcm2835_dumpregs(struct bcm2835_host *host)
{
	dev_dbg(dev, "=========== REGISTER DUMP ===========\n");
	dev_dbg(dev, "SDCMD  0x%08x\n", readl(host->ioaddr + SDCMD));
	dev_dbg(dev, "SDARG  0x%08x\n", readl(host->ioaddr + SDARG));
	dev_dbg(dev, "SDTOUT 0x%08x\n", readl(host->ioaddr + SDTOUT));
	dev_dbg(dev, "SDCDIV 0x%08x\n", readl(host->ioaddr + SDCDIV));
	dev_dbg(dev, "SDRSP0 0x%08x\n", readl(host->ioaddr + SDRSP0));
	dev_dbg(dev, "SDRSP1 0x%08x\n", readl(host->ioaddr + SDRSP1));
	dev_dbg(dev, "SDRSP2 0x%08x\n", readl(host->ioaddr + SDRSP2));
	dev_dbg(dev, "SDRSP3 0x%08x\n", readl(host->ioaddr + SDRSP3));
	dev_dbg(dev, "SDHSTS 0x%08x\n", readl(host->ioaddr + SDHSTS));
	dev_dbg(dev, "SDVDD  0x%08x\n", readl(host->ioaddr + SDVDD));
	dev_dbg(dev, "SDEDM  0x%08x\n", readl(host->ioaddr + SDEDM));
	dev_dbg(dev, "SDHCFG 0x%08x\n", readl(host->ioaddr + SDHCFG));
	dev_dbg(dev, "SDHBCT 0x%08x\n", readl(host->ioaddr + SDHBCT));
	dev_dbg(dev, "SDHBLC 0x%08x\n", readl(host->ioaddr + SDHBLC));
	dev_dbg(dev, "===========================================\n");
}

static void bcm2835_reset_internal(struct bcm2835_host *host)
{
	u32 temp;

	writel(SDVDD_POWER_OFF, host->ioaddr + SDVDD);
	writel(0, host->ioaddr + SDCMD);
	writel(0, host->ioaddr + SDARG);
	/* Set timeout to a big enough value so we don't hit it */
	writel(0xf00000, host->ioaddr + SDTOUT);
	writel(0, host->ioaddr + SDCDIV);
	/* Clear status register */
	writel(SDHSTS_CLEAR_MASK, host->ioaddr + SDHSTS);
	writel(0, host->ioaddr + SDHCFG);
	writel(0, host->ioaddr + SDHBCT);
	writel(0, host->ioaddr + SDHBLC);

	/* Limit fifo usage due to silicon bug */
	temp = readl(host->ioaddr + SDEDM);
	temp &= ~((SDEDM_THRESHOLD_MASK << SDEDM_READ_THRESHOLD_SHIFT) |
		  (SDEDM_THRESHOLD_MASK << SDEDM_WRITE_THRESHOLD_SHIFT));
	temp |= (FIFO_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
		(FIFO_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
	writel(temp, host->ioaddr + SDEDM);
	/* Wait for FIFO threshold to populate */
	msleep(20);
	writel(SDVDD_POWER_ON, host->ioaddr + SDVDD);
	/* Wait for all components to go through power on cycle */
	msleep(20);
	host->clock = 0;
	writel(host->hcfg, host->ioaddr + SDHCFG);
	writel(host->cdiv, host->ioaddr + SDCDIV);
}

static int bcm2835_wait_transfer_complete(struct bcm2835_host *host)
{
	int timediff = 0;

	while (1) {
		u32 edm, fsm;

		edm = readl(host->ioaddr + SDEDM);
		fsm = edm & SDEDM_FSM_MASK;

		if ((fsm == SDEDM_FSM_IDENTMODE) ||
		    (fsm == SDEDM_FSM_DATAMODE))
			break;

		if ((fsm == SDEDM_FSM_READWAIT) ||
		    (fsm == SDEDM_FSM_WRITESTART1) ||
		    (fsm == SDEDM_FSM_READDATA)) {
			writel(edm | SDEDM_FORCE_DATA_MODE,
			       host->ioaddr + SDEDM);
			break;
		}

		/* Error out after 100000 register reads (~1s) */
		if (timediff++ == 100000) {
			dev_err(host->dev,
				"wait_transfer_complete - still waiting after %d retries\n",
				timediff);
			bcm2835_dumpregs(host);
			return -ETIMEDOUT;
		}
	}

	return 0;
}

static int bcm2835_transfer_block_pio(struct bcm2835_host *host, bool is_read)
{
	struct mmc_data *data = host->data;
	size_t blksize = data->blocksize;
	int copy_words;
	u32 hsts = 0;
	u32 *buf;

	if (blksize % sizeof(u32))
		return -EINVAL;

	buf = is_read ? (u32 *)data->dest : (u32 *)data->src;

	if (is_read)
		data->dest += blksize;
	else
		data->src += blksize;

	copy_words = blksize / sizeof(u32);

	/*
	 * Copy all contents from/to the FIFO as far as it reaches,
	 * then wait for it to fill/empty again and rewind.
	 */
	while (copy_words) {
		int burst_words, words;
		u32 edm;

		burst_words = min(SDDATA_FIFO_PIO_BURST, copy_words);
		edm = readl(host->ioaddr + SDEDM);
		if (is_read)
			words = edm_fifo_fill(edm);
		else
			words = SDDATA_FIFO_WORDS - edm_fifo_fill(edm);

		if (words < burst_words) {
			int fsm_state = (edm & SDEDM_FSM_MASK);

			if ((is_read &&
			     (fsm_state != SDEDM_FSM_READDATA &&
			      fsm_state != SDEDM_FSM_READWAIT &&
			      fsm_state != SDEDM_FSM_READCRC)) ||
			    (!is_read &&
			     (fsm_state != SDEDM_FSM_WRITEDATA &&
			      fsm_state != SDEDM_FSM_WRITEWAIT1 &&
			      fsm_state != SDEDM_FSM_WRITEWAIT2 &&
			      fsm_state != SDEDM_FSM_WRITECRC &&
			      fsm_state != SDEDM_FSM_WRITESTART1 &&
			      fsm_state != SDEDM_FSM_WRITESTART2))) {
				hsts = readl(host->ioaddr + SDHSTS);
				printf("fsm %x, hsts %08x\n", fsm_state, hsts);
				if (hsts & SDHSTS_ERROR_MASK)
					break;
			}

			continue;
		} else if (words > copy_words) {
			words = copy_words;
		}

		copy_words -= words;

		/* Copy current chunk to/from the FIFO */
		while (words) {
			if (is_read)
				*(buf++) = readl(host->ioaddr + SDDATA);
			else
				writel(*(buf++), host->ioaddr + SDDATA);
			words--;
		}
	}

	return 0;
}

static int bcm2835_transfer_pio(struct bcm2835_host *host)
{
	u32 sdhsts;
	bool is_read;
	int ret = 0;

	is_read = (host->data->flags & MMC_DATA_READ) != 0;
	ret = bcm2835_transfer_block_pio(host, is_read);
	if (ret)
		return ret;

	sdhsts = readl(host->ioaddr + SDHSTS);
	if (sdhsts & (SDHSTS_CRC16_ERROR |
		      SDHSTS_CRC7_ERROR |
		      SDHSTS_FIFO_ERROR)) {
		printf("%s transfer error - HSTS %08x\n",
		       is_read ? "read" : "write", sdhsts);
		ret =  -EILSEQ;
	} else if ((sdhsts & (SDHSTS_CMD_TIME_OUT |
			      SDHSTS_REW_TIME_OUT))) {
		printf("%s timeout error - HSTS %08x\n",
		       is_read ? "read" : "write", sdhsts);
		ret = -ETIMEDOUT;
	}

	return ret;
}

static void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_cmd *cmd,
				 struct mmc_data *data)
{
	WARN_ON(host->data);

	host->data = data;
	if (!data)
		return;

	/* Use PIO */
	host->blocks = data->blocks;

	writel(data->blocksize, host->ioaddr + SDHBCT);
	writel(data->blocks, host->ioaddr + SDHBLC);
}

static u32 bcm2835_read_wait_sdcmd(struct bcm2835_host *host)
{
	u32 value;
	int ret;
	int timeout_us = SDHST_TIMEOUT_MAX_USEC;

	ret = readl_poll_timeout(host->ioaddr + SDCMD, value,
				 !(value & SDCMD_NEW_FLAG), timeout_us);
	if (ret == -ETIMEDOUT)
		printf("%s: timeout (%d us)\n", __func__, timeout_us);

	return value;
}

static int bcm2835_send_command(struct bcm2835_host *host, struct mmc_cmd *cmd,
				struct mmc_data *data)
{
	u32 sdcmd, sdhsts;

	WARN_ON(host->cmd);

	if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) {
		printf("unsupported response type!\n");
		return -EINVAL;
	}

	sdcmd = bcm2835_read_wait_sdcmd(host);
	if (sdcmd & SDCMD_NEW_FLAG) {
		printf("previous command never completed.\n");
		bcm2835_dumpregs(host);
		return -EBUSY;
	}

	host->cmd = cmd;

	/* Clear any error flags */
	sdhsts = readl(host->ioaddr + SDHSTS);
	if (sdhsts & SDHSTS_ERROR_MASK)
		writel(sdhsts, host->ioaddr + SDHSTS);

	bcm2835_prepare_data(host, cmd, data);

	writel(cmd->cmdarg, host->ioaddr + SDARG);

	sdcmd = cmd->cmdidx & SDCMD_CMD_MASK;

	host->use_busy = false;
	if (!(cmd->resp_type & MMC_RSP_PRESENT)) {
		sdcmd |= SDCMD_NO_RESPONSE;
	} else {
		if (cmd->resp_type & MMC_RSP_136)
			sdcmd |= SDCMD_LONG_RESPONSE;
		if (cmd->resp_type & MMC_RSP_BUSY) {
			sdcmd |= SDCMD_BUSYWAIT;
			host->use_busy = true;
		}
	}

	if (data) {
		if (data->flags & MMC_DATA_WRITE)
			sdcmd |= SDCMD_WRITE_CMD;
		if (data->flags & MMC_DATA_READ)
			sdcmd |= SDCMD_READ_CMD;
	}

	writel(sdcmd | SDCMD_NEW_FLAG, host->ioaddr + SDCMD);

	return 0;
}

static int bcm2835_finish_command(struct bcm2835_host *host)
{
	struct mmc_cmd *cmd = host->cmd;
	u32 sdcmd;
	int ret = 0;

	sdcmd = bcm2835_read_wait_sdcmd(host);

	/* Check for errors */
	if (sdcmd & SDCMD_NEW_FLAG) {
		printf("command never completed.\n");
		bcm2835_dumpregs(host);
		return -EIO;
	} else if (sdcmd & SDCMD_FAIL_FLAG) {
		u32 sdhsts = readl(host->ioaddr + SDHSTS);

		/* Clear the errors */
		writel(SDHSTS_ERROR_MASK, host->ioaddr + SDHSTS);

		if (!(sdhsts & SDHSTS_CRC7_ERROR) ||
		    (host->cmd->cmdidx != MMC_CMD_SEND_OP_COND)) {
			if (sdhsts & SDHSTS_CMD_TIME_OUT) {
				ret = -ETIMEDOUT;
			} else {
				printf("unexpected command %d error\n",
				       host->cmd->cmdidx);
				bcm2835_dumpregs(host);
				ret = -EILSEQ;
			}

			return ret;
		}
	}

	if (cmd->resp_type & MMC_RSP_PRESENT) {
		if (cmd->resp_type & MMC_RSP_136) {
			int i;

			for (i = 0; i < 4; i++) {
				cmd->response[3 - i] =
					readl(host->ioaddr + SDRSP0 + i * 4);
			}
		} else {
			cmd->response[0] = readl(host->ioaddr + SDRSP0);
		}
	}

	/* Processed actual command. */
	host->cmd = NULL;

	return ret;
}

static int bcm2835_check_cmd_error(struct bcm2835_host *host, u32 intmask)
{
	int ret = -EINVAL;

	if (!(intmask & SDHSTS_ERROR_MASK))
		return 0;

	if (!host->cmd)
		return -EINVAL;

	printf("sdhost_busy_irq: intmask %08x\n", intmask);
	if (intmask & SDHSTS_CRC7_ERROR) {
		ret = -EILSEQ;
	} else if (intmask & (SDHSTS_CRC16_ERROR |
			      SDHSTS_FIFO_ERROR)) {
		ret = -EILSEQ;
	} else if (intmask & (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT)) {
		ret = -ETIMEDOUT;
	}
	bcm2835_dumpregs(host);
	return ret;
}

static int bcm2835_check_data_error(struct bcm2835_host *host, u32 intmask)
{
	int ret = 0;

	if (!host->data)
		return 0;
	if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_FIFO_ERROR))
		ret = -EILSEQ;
	if (intmask & SDHSTS_REW_TIME_OUT)
		ret = -ETIMEDOUT;

	if (ret)
		printf("%s:%d %d\n", __func__, __LINE__, ret);

	return ret;
}

static int bcm2835_transmit(struct bcm2835_host *host)
{
	u32 intmask = readl(host->ioaddr + SDHSTS);
	int ret;

	/* Check for errors */
	ret = bcm2835_check_data_error(host, intmask);
	if (ret)
		return ret;

	ret = bcm2835_check_cmd_error(host, intmask);
	if (ret)
		return ret;

	/* Handle wait for busy end */
	if (host->use_busy && (intmask & SDHSTS_BUSY_IRPT)) {
		writel(SDHSTS_BUSY_IRPT, host->ioaddr + SDHSTS);
		host->use_busy = false;
		bcm2835_finish_command(host);
	}

	/* Handle PIO data transfer */
	if (host->data) {
		ret = bcm2835_transfer_pio(host);
		if (ret)
			return ret;
		host->blocks--;
		if (host->blocks == 0) {
			/* Wait for command to complete for real */
			ret = bcm2835_wait_transfer_complete(host);
			if (ret)
				return ret;
			/* Transfer complete */
			host->data = NULL;
		}
	}

	return 0;
}

static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock)
{
	int div;

	/* The SDCDIV register has 11 bits, and holds (div - 2).  But
	 * in data mode the max is 50MHz wihout a minimum, and only
	 * the bottom 3 bits are used. Since the switch over is
	 * automatic (unless we have marked the card as slow...),
	 * chosen values have to make sense in both modes.  Ident mode
	 * must be 100-400KHz, so can range check the requested
	 * clock. CMD15 must be used to return to data mode, so this
	 * can be monitored.
	 *
	 * clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz
	 *                 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz
	 *
	 *		 623->400KHz/27.8MHz
	 *		 reset value (507)->491159/50MHz
	 *
	 * BUT, the 3-bit clock divisor in data mode is too small if
	 * the core clock is higher than 250MHz, so instead use the
	 * SLOW_CARD configuration bit to force the use of the ident
	 * clock divisor at all times.
	 */

	if (clock < 100000) {
		/* Can't stop the clock, but make it as slow as possible
		 * to show willing
		 */
		host->cdiv = SDCDIV_MAX_CDIV;
		writel(host->cdiv, host->ioaddr + SDCDIV);
		return;
	}

	div = host->max_clk / clock;
	if (div < 2)
		div = 2;
	if ((host->max_clk / div) > clock)
		div++;
	div -= 2;

	if (div > SDCDIV_MAX_CDIV)
		div = SDCDIV_MAX_CDIV;

	clock = host->max_clk / (div + 2);
	host->mmc->clock = clock;

	/* Calibrate some delays */

	host->ns_per_fifo_word = (1000000000 / clock) *
		((host->mmc->card_caps & MMC_MODE_4BIT) ? 8 : 32);

	host->cdiv = div;
	writel(host->cdiv, host->ioaddr + SDCDIV);

	/* Set the timeout to 500ms */
	writel(host->mmc->clock / 2, host->ioaddr + SDTOUT);
}

static inline int is_power_of_2(u64 x)
{
	return !(x & (x - 1));
}

static int bcm2835_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
			    struct mmc_data *data)
{
	struct bcm2835_host *host = dev_get_priv(dev);
	u32 edm, fsm;
	int ret = 0;

	if (data && !is_power_of_2(data->blocksize)) {
		printf("unsupported block size (%d bytes)\n", data->blocksize);

		if (cmd)
			return -EINVAL;
	}

	edm = readl(host->ioaddr + SDEDM);
	fsm = edm & SDEDM_FSM_MASK;

	if ((fsm != SDEDM_FSM_IDENTMODE) &&
	    (fsm != SDEDM_FSM_DATAMODE) &&
	    (cmd && cmd->cmdidx != MMC_CMD_STOP_TRANSMISSION)) {
		printf("previous command (%d) not complete (EDM %08x)\n",
		       readl(host->ioaddr + SDCMD) & SDCMD_CMD_MASK, edm);
		bcm2835_dumpregs(host);

		if (cmd)
			return -EILSEQ;

		return 0;
	}

	if (cmd) {
		ret = bcm2835_send_command(host, cmd, data);
		if (!ret && !host->use_busy)
			ret = bcm2835_finish_command(host);
	}

	/* Wait for completion of busy signal or data transfer */
	while (host->use_busy || host->data) {
		ret = bcm2835_transmit(host);
		if (ret)
			break;
	}

	return ret;
}

static int bcm2835_set_ios(struct udevice *dev)
{
	struct bcm2835_host *host = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);

	if (!mmc->clock || mmc->clock != host->clock) {
		bcm2835_set_clock(host, mmc->clock);
		host->clock = mmc->clock;
	}

	/* set bus width */
	host->hcfg &= ~SDHCFG_WIDE_EXT_BUS;
	if (mmc->bus_width == 4)
		host->hcfg |= SDHCFG_WIDE_EXT_BUS;

	host->hcfg |= SDHCFG_WIDE_INT_BUS;

	/* Disable clever clock switching, to cope with fast core clocks */
	host->hcfg |= SDHCFG_SLOW_CARD;

	writel(host->hcfg, host->ioaddr + SDHCFG);

	return 0;
}

static void bcm2835_add_host(struct bcm2835_host *host)
{
	struct mmc_config *cfg = &host->plat->cfg;

	cfg->f_max = host->max_clk;
	cfg->f_min = host->max_clk / SDCDIV_MAX_CDIV;
	cfg->b_max = 65535;

	dev_dbg(dev, "f_max %d, f_min %d\n",
		cfg->f_max, cfg->f_min);

	/* host controller capabilities */
	cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz;

	/* report supported voltage ranges */
	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;

	/* Set interrupt enables */
	host->hcfg = SDHCFG_BUSY_IRPT_EN;

	bcm2835_reset_internal(host);
}

static int bcm2835_probe(struct udevice *dev)
{
	struct bcm2835_plat *plat = dev_get_platdata(dev);
	struct bcm2835_host *host = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);

	host->dev = dev;
	host->mmc = mmc;
	host->plat = plat;
	upriv->mmc = &plat->mmc;
	plat->cfg.name = dev->name;

	host->phys_addr = devfdt_get_addr(dev);
	if (host->phys_addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	host->ioaddr = devm_ioremap(dev, host->phys_addr, SZ_256);
	if (!host->ioaddr)
		return -ENOMEM;

	host->max_clk = bcm2835_get_mmc_clock(BCM2835_MBOX_CLOCK_ID_CORE);

	bcm2835_add_host(host);

	dev_dbg(dev, "%s -> OK\n", __func__);

	return 0;
}

static const struct udevice_id bcm2835_match[] = {
	{ .compatible = "brcm,bcm2835-sdhost" },
	{ }
};

static const struct dm_mmc_ops bcm2835_ops = {
	.send_cmd = bcm2835_send_cmd,
	.set_ios = bcm2835_set_ios,
};

static int bcm2835_bind(struct udevice *dev)
{
	struct bcm2835_plat *plat = dev_get_platdata(dev);

	return mmc_bind(dev, &plat->mmc, &plat->cfg);
}

U_BOOT_DRIVER(bcm2835_sdhost) = {
	.name = "bcm2835-sdhost",
	.id = UCLASS_MMC,
	.of_match = bcm2835_match,
	.bind = bcm2835_bind,
	.probe = bcm2835_probe,
	.priv_auto_alloc_size = sizeof(struct bcm2835_host),
	.platdata_auto_alloc_size = sizeof(struct bcm2835_plat),
	.ops = &bcm2835_ops,
};
