/*
 * Copyright (c) 2019, Linaro Limited
 * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <drivers/delay_timer.h>
#include <drivers/rpi3/sdhost/rpi3_sdhost.h>
#include <drivers/mmc.h>
#include <drivers/rpi3/gpio/rpi3_gpio.h>
#include <errno.h>
#include <string.h>

static void rpi3_sdhost_initialize(void);
static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd);
static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width);
static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size);
static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size);
static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size);

static const struct mmc_ops rpi3_sdhost_ops = {
	.init		= rpi3_sdhost_initialize,
	.send_cmd	= rpi3_sdhost_send_cmd,
	.set_ios	= rpi3_sdhost_set_ios,
	.prepare	= rpi3_sdhost_prepare,
	.read		= rpi3_sdhost_read,
	.write		= rpi3_sdhost_write,
};

static struct rpi3_sdhost_params rpi3_sdhost_params;

/**
 * Wait for command being processed.
 *
 * This function waits the command being processed. It compares
 * the ENABLE flag of the HC_COMMAND register. When ENABLE flag disappeared
 * it means the command is processed by the SDHOST.
 * The timeout is currently 1000*100 us = 100 ms.
 *
 * @return 0: command finished. 1: command timed out.
 */
static int rpi3_sdhost_waitcommand(void)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;

	volatile int timeout = 1000;

	while ((mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_ENABLE)
	       && (--timeout > 0)) {
		udelay(100);
	}

	return ((timeout > 0) ? 0 : (-(ETIMEDOUT)));
}

/**
 * Send the command and argument to the SDHOST
 *
 * This function will wait for the previous command finished. And then
 * clear any error status of previous command. And then
 * send out the command and args. The command will be turned on the ENABLE
 * flag before sending out.
 */
static void send_command_raw(unsigned int cmd, unsigned int arg)
{
	unsigned int status;
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;

	/* wait for previous command finish */
	rpi3_sdhost_waitcommand();

	/* clean error status */
	status = mmio_read_32(reg_base + HC_HOSTSTATUS);
	if (status & HC_HSTST_MASK_ERROR_ALL)
		mmio_write_32(reg_base + HC_HOSTSTATUS, status);

	/* recording the command */
	rpi3_sdhost_params.current_cmd = cmd & HC_CMD_COMMAND_MASK;

	/* send the argument and command */
	mmio_write_32(reg_base + HC_ARGUMENT, arg);
	mmio_write_32(reg_base + HC_COMMAND, cmd | HC_CMD_ENABLE);
}

/**
 * Send the command and argument to the SDHOST, decorated with control
 * flags.
 *
 * This function will use send_command_raw to send the commands to SDHOST.
 * But before sending it will decorate the command with control flags specific
 * to SDHOST.
 */
static void send_command_decorated(unsigned int cmd, unsigned int arg)
{
	unsigned int cmd_flags = 0;

	switch (cmd & HC_CMD_COMMAND_MASK) {
	case MMC_CMD(0):
		cmd_flags |= HC_CMD_RESPONSE_NONE;
		break;
	case MMC_ACMD(51):
		cmd_flags |= HC_CMD_READ;
		break;
	case MMC_CMD(8):
	case MMC_CMD(11):
	case MMC_CMD(17):
	case MMC_CMD(18):
		cmd_flags |= HC_CMD_READ;
		break;
	case MMC_CMD(20):
	case MMC_CMD(24):
	case MMC_CMD(25):
		cmd_flags |= HC_CMD_WRITE;
		break;
	case MMC_CMD(12):
		cmd_flags |= HC_CMD_BUSY;
		break;
	default:
		break;
	}
	send_command_raw(cmd | cmd_flags, arg);
}

/**
 * drains the FIFO on DATA port
 *
 * This function drains any data left in the DATA port.
 */
static void rpi3_drain_fifo(void)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	volatile int timeout = 100000;

	rpi3_sdhost_waitcommand();

	while (mmio_read_32(reg_base + HC_HOSTSTATUS) & HC_HSTST_HAVEDATA) {
		mmio_read_32(reg_base + HC_DATAPORT);
		udelay(100);
	}

	while (1) {
		uint32_t edm, fsm;

		edm = mmio_read_32(reg_base + HC_DEBUG);
		fsm = edm & HC_DBG_FSM_MASK;

		if ((fsm == HC_DBG_FSM_IDENTMODE) ||
		    (fsm == HC_DBG_FSM_DATAMODE))
			break;

		if ((fsm == HC_DBG_FSM_READWAIT) ||
		    (fsm == HC_DBG_FSM_WRITESTART1) ||
		    (fsm == HC_DBG_FSM_READDATA)) {
			mmio_write_32(reg_base + HC_DEBUG,
				      edm | HC_DBG_FORCE_DATA_MODE);
			break;
		}

		if (--timeout <= 0) {
			ERROR("rpi3_sdhost: %s cannot recover stat\n",
			      __func__);
			return;
		}
	}
}

/**
 * Dump SDHOST registers
 */
static void rpi3_sdhost_print_regs(void)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;

	INFO("rpi3_sdhost: HC_COMMAND:        0x%08x\n",
	     mmio_read_32(reg_base + HC_COMMAND));
	INFO("rpi3_sdhost: HC_ARGUMENT:       0x%08x\n",
	     mmio_read_32(reg_base + HC_ARGUMENT));
	INFO("rpi3_sdhost: HC_TIMEOUTCOUNTER: 0x%08x\n",
	     mmio_read_32(reg_base + HC_TIMEOUTCOUNTER));
	INFO("rpi3_sdhost: HC_CLOCKDIVISOR:   0x%08x\n",
	     mmio_read_32(reg_base + HC_CLOCKDIVISOR));
	INFO("rpi3_sdhost: HC_RESPONSE_0:     0x%08x\n",
	     mmio_read_32(reg_base + HC_RESPONSE_0));
	INFO("rpi3_sdhost: HC_RESPONSE_1:     0x%08x\n",
	     mmio_read_32(reg_base + HC_RESPONSE_1));
	INFO("rpi3_sdhost: HC_RESPONSE_2:     0x%08x\n",
	     mmio_read_32(reg_base + HC_RESPONSE_2));
	INFO("rpi3_sdhost: HC_RESPONSE_3:     0x%08x\n",
	     mmio_read_32(reg_base + HC_RESPONSE_3));
	INFO("rpi3_sdhost: HC_HOSTSTATUS:     0x%08x\n",
	     mmio_read_32(reg_base + HC_HOSTSTATUS));
	INFO("rpi3_sdhost: HC_POWER:          0x%08x\n",
	     mmio_read_32(reg_base + HC_POWER));
	INFO("rpi3_sdhost: HC_DEBUG:          0x%08x\n",
	     mmio_read_32(reg_base + HC_DEBUG));
	INFO("rpi3_sdhost: HC_HOSTCONFIG:     0x%08x\n",
	     mmio_read_32(reg_base + HC_HOSTCONFIG));
	INFO("rpi3_sdhost: HC_BLOCKSIZE:      0x%08x\n",
	     mmio_read_32(reg_base + HC_BLOCKSIZE));
	INFO("rpi3_sdhost: HC_BLOCKCOUNT:     0x%08x\n",
	     mmio_read_32(reg_base + HC_BLOCKCOUNT));
}

/**
 * Reset SDHOST
 */
static void rpi3_sdhost_reset(void)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	unsigned int dbg;
	uint32_t tmp1;

	mmio_write_32(reg_base + HC_POWER, 0);
	mmio_write_32(reg_base + HC_COMMAND, 0);
	mmio_write_32(reg_base + HC_ARGUMENT, 0);

	mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT);
	mmio_write_32(reg_base + HC_CLOCKDIVISOR, 0);
	mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_RESET);
	mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
	mmio_write_32(reg_base + HC_BLOCKSIZE, 0);
	mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);

	dbg = mmio_read_32(reg_base + HC_DEBUG);
	dbg &= ~((HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) |
		 (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT));
	dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) |
		(HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT);
	mmio_write_32(reg_base + HC_DEBUG, dbg);
	mdelay(250);
	mmio_write_32(reg_base + HC_POWER, 1);
	mdelay(250);
	rpi3_sdhost_params.clk_rate = 0;

	mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL);
	tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
	mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 | HC_HSTCF_INT_BUSY);
}

static void rpi3_sdhost_initialize(void)
{
	assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);

	rpi3_sdhost_reset();

	rpi3_sdhost_set_ios(rpi3_sdhost_params.clk_rate_initial,
		rpi3_sdhost_params.bus_width);
	udelay(300);
}

static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	int err = 0;
	uint32_t cmd_idx;
	uint32_t cmd_arg;
	uint32_t cmd_flags = 0;
	uint32_t intmask;

	/* Wait for the command done */
	err = rpi3_sdhost_waitcommand();
	if (err != 0) {
		WARN("previous command not done yet\n");
		return err;
	}

	cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK;

	cmd_arg = cmd->cmd_arg;
	if (cmd_idx == MMC_ACMD(51)) {
		/* if previous cmd send to SDHOST is not MMC_CMD(55).
		 * It means this MMC_ACMD(51) is a resend.
		 * And we must also resend MMC_CMD(55) in this case
		 */
		if (rpi3_sdhost_params.current_cmd != MMC_CMD(55)) {
			send_command_decorated(
				MMC_CMD(55),
				rpi3_sdhost_params.sdcard_rca <<
				RCA_SHIFT_OFFSET);
			rpi3_sdhost_params.mmc_app_cmd = 1;
			rpi3_sdhost_waitcommand();

			/* Also we need to call prepare to clean the buffer */
			rpi3_sdhost_prepare(0, (uintptr_t)NULL, 8);
		}
	}

	/* We ignore MMC_CMD(12) sending from the TF-A's MMC driver
	 * because we send MMC_CMD(12) by ourselves.
	 */
	if (cmd_idx == MMC_CMD(12))
		return 0;

	if ((cmd->resp_type & MMC_RSP_136) &&
	    (cmd->resp_type & MMC_RSP_BUSY)) {
		ERROR("rpi3_sdhost: unsupported response type!\n");
		return -(EOPNOTSUPP);
	}

	if (cmd->resp_type & MMC_RSP_48 && cmd->resp_type != MMC_RESPONSE_R2) {
		/* 48-bit command
		 * We don't need to set any flags here because it is default.
		 */
	} else if (cmd->resp_type & MMC_RSP_136) {
		/* 136-bit command */
		cmd_flags |= HC_CMD_RESPONSE_LONG;
	} else {
		/* no respond command */
		cmd_flags |= HC_CMD_RESPONSE_NONE;
	}

	rpi3_sdhost_params.cmdbusy = 0;
	if (cmd->resp_type & MMC_RSP_BUSY) {
		cmd_flags |= HC_CMD_BUSY;
		rpi3_sdhost_params.cmdbusy = 1;
	}

	if (rpi3_sdhost_params.mmc_app_cmd) {
		switch (cmd_idx) {
		case MMC_ACMD(41):
			if (cmd_arg == OCR_HCS)
				cmd_arg |= OCR_3_3_3_4;
			break;
		default:
			break;
		}
		rpi3_sdhost_params.mmc_app_cmd = 0;
	}

	if (cmd_idx == MMC_CMD(55))
		rpi3_sdhost_params.mmc_app_cmd = 1;

	send_command_decorated(cmd_idx | cmd_flags, cmd_arg);

	intmask = mmio_read_32(reg_base + HC_HOSTSTATUS);
	if (rpi3_sdhost_params.cmdbusy && (intmask & HC_HSTST_INT_BUSY)) {
		mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_INT_BUSY);
		rpi3_sdhost_params.cmdbusy = 0;
	}

	if (!(cmd_flags & HC_CMD_RESPONSE_NONE)) {
		err = rpi3_sdhost_waitcommand();
		if (err != 0)
			ERROR("rpi3_sdhost: cmd cannot be finished\n");
	}

	cmd->resp_data[0] = mmio_read_32(reg_base + HC_RESPONSE_0);
	cmd->resp_data[1] = mmio_read_32(reg_base + HC_RESPONSE_1);
	cmd->resp_data[2] = mmio_read_32(reg_base + HC_RESPONSE_2);
	cmd->resp_data[3] = mmio_read_32(reg_base + HC_RESPONSE_3);

	if (mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_FAILED) {
		uint32_t sdhsts = mmio_read_32(reg_base + HC_HOSTSTATUS);

		mmio_write_32(reg_base + HC_HOSTSTATUS,
			      HC_HSTST_MASK_ERROR_ALL);

		/*
		 * If the command SEND_OP_COND returns with CRC7 error,
		 * it can be considered as having completed successfully.
		 */
		if (!(sdhsts & HC_HSTST_ERROR_CRC7)
		    || (cmd_idx != MMC_CMD(1))) {
			if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
				ERROR("rpi3_sdhost: timeout status 0x%x\n",
				      sdhsts);
				err = -(ETIMEDOUT);
			} else {
				ERROR("rpi3_sdhost: unknown err, cmd = 0x%x\n",
				      mmio_read_32(reg_base + HC_COMMAND));
				ERROR("rpi3_sdhost status: 0x%x\n", sdhsts);
				err = -(EILSEQ);
			}
		}
	}

	if ((!err) && (cmd_idx == MMC_CMD(3))) {
		/* we keep the RCA in case to send MMC_CMD(55) ourselves */
		rpi3_sdhost_params.sdcard_rca = (cmd->resp_data[0]
						 & 0xFFFF0000U) >> 16;
	}

	return err;
}

static int rpi3_sdhost_set_clock(unsigned int clk)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	uint32_t max_clk = 250000000;
	uint32_t div;

	if (clk < 100000) {
		mmio_write_32(reg_base + HC_CLOCKDIVISOR,
			      HC_CLOCKDIVISOR_MAXVAL);
		return 0;
	}

	div = max_clk / clk;
	if (div < 2)
		div = 2;

	if ((max_clk / div) > clk)
		div++;

	div -= 2;
	if (div > HC_CLOCKDIVISOR_MAXVAL)
		div = HC_CLOCKDIVISOR_MAXVAL;

	rpi3_sdhost_params.clk_rate = max_clk / (div + 2);
	rpi3_sdhost_params.ns_per_fifo_word = (1000000000 /
					       rpi3_sdhost_params.clk_rate)
		* 8;

	mmio_write_32(reg_base + HC_CLOCKDIVISOR, div);
	return 0;
}

static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	uint32_t tmp1;

	rpi3_sdhost_set_clock(clk);
	VERBOSE("rpi3_sdhost: Changing clock to %dHz for data mode\n", clk);

	if (width != MMC_BUS_WIDTH_4 && width != MMC_BUS_WIDTH_1) {
		ERROR("rpi3_sdhost: width %d not supported\n", width);
		return -(EOPNOTSUPP);
	}
	rpi3_sdhost_params.bus_width = width;

	tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
	tmp1 &= ~(HC_HSTCF_EXTBUS_4BIT);
	if (rpi3_sdhost_params.bus_width == MMC_BUS_WIDTH_4)
		tmp1 |= HC_HSTCF_EXTBUS_4BIT;

	mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1);
	tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
	mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 |
		      HC_HSTCF_SLOW_CARD | HC_HSTCF_INTBUS_WIDE);

	return 0;
}

static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	size_t blocks;
	size_t blocksize;

	if (size < 512) {
		blocksize = size;
		blocks = 1;
	} else {
		blocksize = 512;
		blocks = size / blocksize;
		if (size % blocksize != 0)
			blocks++;
	}

	rpi3_drain_fifo();

	mmio_write_32(reg_base + HC_BLOCKSIZE, blocksize);
	mmio_write_32(reg_base + HC_BLOCKCOUNT, blocks);
	udelay(100);
	return 0;
}

static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size)
{
	int err = 0;
	uint32_t *buf1 = ((uint32_t *) buf);
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	int timeout = 100000;
	int remaining_words = 0;

	for (int i = 0; i < size / 4; i++) {
		volatile int t = timeout;
		uint32_t hsts_err;

		while ((mmio_read_32(reg_base + HC_HOSTSTATUS)
			& HC_HSTST_HAVEDATA) == 0) {
			if (t == 0) {
				ERROR("rpi3_sdhost: fifo timeout after %dus\n",
				      timeout);
				err = -(ETIMEDOUT);
				break;
			}
			t--;
			udelay(10);
		}
		if (t == 0)
			break;

		uint32_t data = mmio_read_32(reg_base + HC_DATAPORT);

		hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
			& HC_HSTST_MASK_ERROR_ALL;
		if (hsts_err) {
			ERROR("rpi3_sdhost: transfer FIFO word %d: 0x%x\n",
			      i,
			      mmio_read_32(reg_base + HC_HOSTSTATUS));
			rpi3_sdhost_print_regs();

			err = -(EILSEQ);

			/* clean the error status */
			mmio_write_32(reg_base + HC_HOSTSTATUS, hsts_err);
		}

		if (buf1)
			buf1[i] = data;

		/* speeding up if the remaining words are still a lot */
		remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
			& HC_DBG_FIFO_THRESH_MASK;
		if (remaining_words >= 7)
			continue;

		/* delay. slowing down the read process */
		udelay(100);
	}

	/* We decide to stop by ourselves.
	 * It is because MMC_CMD(18) -> MMC_CMD(13) -> MMC_CMD(12)
	 * doesn't work for RPi3 SDHost.
	 */
	if (rpi3_sdhost_params.current_cmd == MMC_CMD(18))
		send_command_decorated(MMC_CMD(12), 0);

	return err;
}

static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size)
{
	uint32_t *buf1 = ((uint32_t *) buf);
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;
	int err = 0;
	int remaining_words = 0;

	for (int i = 0; i < size / 4; i++) {
		uint32_t hsts_err;
		uint32_t data = buf1[i];
		uint32_t dbg;
		uint32_t fsm_state;

		mmio_write_32(reg_base + HC_DATAPORT, data);

		dbg = mmio_read_32(reg_base + HC_DEBUG);
		fsm_state = dbg & HC_DBG_FSM_MASK;
		if (fsm_state != HC_DBG_FSM_WRITEDATA
		    && fsm_state != HC_DBG_FSM_WRITESTART1
		    && fsm_state != HC_DBG_FSM_WRITESTART2
		    && fsm_state != HC_DBG_FSM_WRITECRC
		    && fsm_state != HC_DBG_FSM_WRITEWAIT1
		    && fsm_state != HC_DBG_FSM_WRITEWAIT2) {
			hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
				& HC_HSTST_MASK_ERROR_ALL;
			if (hsts_err)
				err = -(EILSEQ);
		}

		/* speeding up if the remaining words are not many */
		remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
			& HC_DBG_FIFO_THRESH_MASK;
		if (remaining_words <= 4)
			continue;

		udelay(100);
	}

	/* We decide to stop by ourselves.
	 * It is because MMC_CMD(25) -> MMC_CMD(13) -> MMC_CMD(12)
	 * doesn't work for RPi3 SDHost.
	 */
	if (rpi3_sdhost_params.current_cmd == MMC_CMD(25))
		send_command_decorated(MMC_CMD(12), 0);

	return err;
}

void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
		    struct mmc_device_info *mmc_dev_info)
{
	assert((params != 0) &&
	       ((params->reg_base & MMC_BLOCK_MASK) == 0));

	memcpy(&rpi3_sdhost_params, params, sizeof(struct rpi3_sdhost_params));

	/* backup GPIO 48 to 53 configurations */
	for (int i = 48; i <= 53; i++) {
		rpi3_sdhost_params.gpio48_pinselect[i - 48]
			= rpi3_gpio_get_select(i);
		VERBOSE("rpi3_sdhost: Original GPIO state %d: %d\n",
			i,
			rpi3_sdhost_params.gpio48_pinselect[i - 48]);
	}

	/* setting pull resistors for 48 to 53.
	 * It is debatable to set SD_CLK to UP or NONE. We massively
	 * tested different brands of SD Cards and found NONE works
	 * most stable.
	 *
	 * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
	 * GPIO 49 (SD_CMD) to GPIO_PULL_UP
	 * GPIO 50 (SD_D0)  to GPIO_PULL_UP
	 * GPIO 51 (SD_D1)  to GPIO_PULL_UP
	 * GPIO 52 (SD_D2)  to GPIO_PULL_UP
	 * GPIO 53 (SD_D3)  to GPIO_PULL_UP
	 */
	gpio_set_pull(48, GPIO_PULL_NONE);
	for (int i = 49; i <= 53; i++)
		gpio_set_pull(i, GPIO_PULL_UP);

	/* Set pin 48-53 to alt-0. It means route SDHOST to card slot */
	for (int i = 48; i <= 53; i++)
		rpi3_gpio_set_select(i, RPI3_GPIO_FUNC_ALT0);

	mmc_init(&rpi3_sdhost_ops, params->clk_rate, params->bus_width,
		 params->flags, mmc_dev_info);
}

void rpi3_sdhost_stop(void)
{
	uintptr_t reg_base = rpi3_sdhost_params.reg_base;

	VERBOSE("rpi3_sdhost: Shutting down: drain FIFO out\n");
	rpi3_drain_fifo();

	VERBOSE("rpi3_sdhost: Shutting down: slowing down the clock\n");
	mmio_write_32(reg_base+HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_SLOWVAL);
	udelay(500);

	VERBOSE("rpi3_sdhost: Shutting down: put SDHost into idle state\n");
	send_command_decorated(MMC_CMD(0), 0);
	udelay(500);

	mmio_write_32(reg_base + HC_COMMAND, 0);
	mmio_write_32(reg_base + HC_ARGUMENT, 0);
	mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_IDLE);
	mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_STOPVAL);

	udelay(100);

	mmio_write_32(reg_base + HC_POWER, 0);
	mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
	mmio_write_32(reg_base + HC_BLOCKSIZE, 0x400);
	mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
	mmio_write_32(reg_base + HC_HOSTSTATUS, 0x7f8);

	mmio_write_32(reg_base + HC_COMMAND, 0);
	mmio_write_32(reg_base + HC_ARGUMENT, 0);

	udelay(100);

	/* Restore the pinmux to original state */
	for (int i = 48; i <= 53; i++) {
		rpi3_gpio_set_select(i,
				     rpi3_sdhost_params.gpio48_pinselect[i-48]);
	}

	/* Reset the pull resistors before entering BL33.
	 * GPIO 48 (SD_CLK) to GPIO_PULL_UP
	 * GPIO 49 (SD_CMD) to GPIO_PULL_UP
	 * GPIO 50 (SD_D0)  to GPIO_PULL_UP
	 * GPIO 51 (SD_D1)  to GPIO_PULL_UP
	 * GPIO 52 (SD_D2)  to GPIO_PULL_UP
	 * GPIO 53 (SD_D3)  to GPIO_PULL_UP
	 */
	for (int i = 48; i <= 53; i++)
		gpio_set_pull(i, GPIO_PULL_UP);
}
