// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) Freescale Semiconductor, Inc. 2006.
 * Author: Jason Jin<Jason.jin@freescale.com>
 *         Zhang Wei<wei.zhang@freescale.com>
 *
 * with the reference on libata and ahci drvier in kernel
 *
 * This driver provides a SCSI interface to SATA.
 */
#include <blk.h>
#include <cpu_func.h>
#include <log.h>
#include <time.h>
#include <linux/bitops.h>
#include <linux/delay.h>

#include <command.h>
#include <dm.h>
#include <pci.h>
#include <asm/processor.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <memalign.h>
#include <pci.h>
#include <scsi.h>
#include <libata.h>
#include <linux/ctype.h>
#include <ahci.h>
#include <dm/device-internal.h>
#include <dm/lists.h>

static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port);

#define writel_with_flush(a,b)	do { writel(a,b); readl(b); } while (0)

/*
 * Some controllers limit number of blocks they can read/write at once.
 * Contemporary SSD devices work much faster if the read/write size is aligned
 * to a power of 2.  Let's set default to 128 and allowing to be overwritten if
 * needed.
 */
#ifndef MAX_SATA_BLOCKS_READ_WRITE
#define MAX_SATA_BLOCKS_READ_WRITE	0x80
#endif

/* Maximum timeouts for each event */
#define WAIT_MS_SPINUP	20000
#define WAIT_MS_DATAIO	10000
#define WAIT_MS_FLUSH	5000
#define WAIT_MS_LINKUP	200

#define AHCI_CAP_S64A BIT(31)

__weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
{
	return base + 0x100 + (port * 0x80);
}

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

static void ahci_dcache_flush_range(unsigned long begin, unsigned long len)
{
	const unsigned long start = begin;
	const unsigned long end = start + len;

	debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
	flush_dcache_range(start, end);
}

/*
 * SATA controller DMAs to physical RAM.  Ensure data from the
 * controller is invalidated from dcache; next access comes from
 * physical RAM.
 */
static void ahci_dcache_invalidate_range(unsigned long begin, unsigned long len)
{
	const unsigned long start = begin;
	const unsigned long end = start + len;

	debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
	invalidate_dcache_range(start, end);
}

/*
 * Ensure data for SATA controller is flushed out of dcache and
 * written to physical memory.
 */
static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
{
	ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
				AHCI_PORT_PRIV_DMA_SZ);
}

static int waiting_for_cmd_completed(void __iomem *offset,
				     int timeout_msec,
				     u32 sign)
{
	int i;
	u32 status;

	for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
		msleep(1);

	return (i < timeout_msec) ? 0 : -1;
}

int __weak ahci_link_up(struct ahci_uc_priv *uc_priv, int port)
{
	u32 tmp;
	int j = 0;
	void __iomem *port_mmio = uc_priv->port[port].port_mmio;

	/*
	 * Bring up SATA link.
	 * SATA link bringup time is usually less than 1 ms; only very
	 * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
	 */
	while (j < WAIT_MS_LINKUP) {
		tmp = readl(port_mmio + PORT_SCR_STAT);
		tmp &= PORT_SCR_STAT_DET_MASK;
		if (tmp == PORT_SCR_STAT_DET_PHYRDY)
			return 0;
		udelay(1000);
		j++;
	}
	return 1;
}

#ifdef CONFIG_SUNXI_AHCI
/* The sunxi AHCI controller requires this undocumented setup */
static void sunxi_dma_init(void __iomem *port_mmio)
{
	clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400);
}
#endif

int ahci_reset(void __iomem *base)
{
	int i = 1000;
	u32 __iomem *host_ctl_reg = base + HOST_CTL;
	u32 tmp = readl(host_ctl_reg); /* global controller reset */

	if ((tmp & HOST_RESET) == 0)
		writel_with_flush(tmp | HOST_RESET, host_ctl_reg);

	/*
	 * reset must complete within 1 second, or
	 * the hardware should be considered fried.
	 */
	do {
		udelay(1000);
		tmp = readl(host_ctl_reg);
		i--;
	} while ((i > 0) && (tmp & HOST_RESET));

	if (i == 0) {
		printf("controller reset failed (0x%x)\n", tmp);
		return -1;
	}

	return 0;
}

static int ahci_host_init(struct ahci_uc_priv *uc_priv)
{
	void __iomem *mmio = uc_priv->mmio_base;
	u32 tmp, cap_save, cmd;
	int i, j, ret;
	void __iomem *port_mmio;
	u32 port_map;

	debug("ahci_host_init: start\n");

	cap_save = readl(mmio + HOST_CAP);
	cap_save &= ((1 << 28) | (1 << 17));
	cap_save |= (1 << 27);  /* Staggered Spin-up. Not needed. */

	ret = ahci_reset(uc_priv->mmio_base);
	if (ret)
		return ret;

	writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
	writel(cap_save, mmio + HOST_CAP);
	writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);

	uc_priv->cap = readl(mmio + HOST_CAP);
	uc_priv->port_map = readl(mmio + HOST_PORTS_IMPL);
	port_map = uc_priv->port_map;
	uc_priv->n_ports = (uc_priv->cap & 0x1f) + 1;

	debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
	      uc_priv->cap, uc_priv->port_map, uc_priv->n_ports);

	for (i = 0; i < uc_priv->n_ports; i++) {
		if (!(port_map & (1 << i)))
			continue;
		uc_priv->port[i].port_mmio = ahci_port_base(mmio, i);
		port_mmio = (u8 *)uc_priv->port[i].port_mmio;

		/* make sure port is not active */
		tmp = readl(port_mmio + PORT_CMD);
		if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
			   PORT_CMD_FIS_RX | PORT_CMD_START)) {
			debug("Port %d is active. Deactivating.\n", i);
			tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
				 PORT_CMD_FIS_RX | PORT_CMD_START);
			writel_with_flush(tmp, port_mmio + PORT_CMD);

			/* spec says 500 msecs for each bit, so
			 * this is slightly incorrect.
			 */
			msleep(500);
		}

#ifdef CONFIG_SUNXI_AHCI
		sunxi_dma_init(port_mmio);
#endif

		/* Add the spinup command to whatever mode bits may
		 * already be on in the command register.
		 */
		cmd = readl(port_mmio + PORT_CMD);
		cmd |= PORT_CMD_SPIN_UP;
		writel_with_flush(cmd, port_mmio + PORT_CMD);

		/* Bring up SATA link. */
		ret = ahci_link_up(uc_priv, i);
		if (ret) {
			printf("SATA link %d timeout.\n", i);
			continue;
		} else {
			debug("SATA link ok.\n");
		}

		/* Clear error status */
		tmp = readl(port_mmio + PORT_SCR_ERR);
		if (tmp)
			writel(tmp, port_mmio + PORT_SCR_ERR);

		debug("Spinning up device on SATA port %d... ", i);

		j = 0;
		while (j < WAIT_MS_SPINUP) {
			tmp = readl(port_mmio + PORT_TFDATA);
			if (!(tmp & (ATA_BUSY | ATA_DRQ)))
				break;
			udelay(1000);
			tmp = readl(port_mmio + PORT_SCR_STAT);
			tmp &= PORT_SCR_STAT_DET_MASK;
			if (tmp == PORT_SCR_STAT_DET_PHYRDY)
				break;
			j++;
		}

		tmp = readl(port_mmio + PORT_SCR_STAT) & PORT_SCR_STAT_DET_MASK;
		if (tmp == PORT_SCR_STAT_DET_COMINIT) {
			debug("SATA link %d down (COMINIT received), retrying...\n", i);
			i--;
			continue;
		}

		printf("Target spinup took %d ms.\n", j);
		if (j == WAIT_MS_SPINUP)
			debug("timeout.\n");
		else
			debug("ok.\n");

		tmp = readl(port_mmio + PORT_SCR_ERR);
		debug("PORT_SCR_ERR 0x%x\n", tmp);
		writel(tmp, port_mmio + PORT_SCR_ERR);

		/* ack any pending irq events for this port */
		tmp = readl(port_mmio + PORT_IRQ_STAT);
		debug("PORT_IRQ_STAT 0x%x\n", tmp);
		if (tmp)
			writel(tmp, port_mmio + PORT_IRQ_STAT);

		writel(1 << i, mmio + HOST_IRQ_STAT);

		/* register linkup ports */
		tmp = readl(port_mmio + PORT_SCR_STAT);
		debug("SATA port %d status: 0x%x\n", i, tmp);
		if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
			uc_priv->link_port_map |= (0x01 << i);
	}

	tmp = readl(mmio + HOST_CTL);
	debug("HOST_CTL 0x%x\n", tmp);
	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
	tmp = readl(mmio + HOST_CTL);
	debug("HOST_CTL 0x%x\n", tmp);
	return 0;
}

static void ahci_print_info(struct ahci_uc_priv *uc_priv)
{
	void __iomem *mmio = uc_priv->mmio_base;
	u32 vers, cap, cap2, impl, speed;
	const char *speed_s;
	const char *scc_s;

	vers = readl(mmio + HOST_VERSION);
	cap = uc_priv->cap;
	cap2 = readl(mmio + HOST_CAP2);
	impl = uc_priv->port_map;

	speed = (cap >> 20) & 0xf;
	if (speed == 1)
		speed_s = "1.5";
	else if (speed == 2)
		speed_s = "3";
	else if (speed == 3)
		speed_s = "6";
	else
		speed_s = "?";

	scc_s = "SATA";
	printf("AHCI %02x%02x.%02x%02x "
	       "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
	       (vers >> 24) & 0xff,
	       (vers >> 16) & 0xff,
	       (vers >> 8) & 0xff,
	       vers & 0xff,
	       ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);

	printf("flags: "
	       "%s%s%s%s%s%s%s"
	       "%s%s%s%s%s%s%s"
	       "%s%s%s%s%s%s\n",
	       cap & (1 << 31) ? "64bit " : "",
	       cap & (1 << 30) ? "ncq " : "",
	       cap & (1 << 28) ? "ilck " : "",
	       cap & (1 << 27) ? "stag " : "",
	       cap & (1 << 26) ? "pm " : "",
	       cap & (1 << 25) ? "led " : "",
	       cap & (1 << 24) ? "clo " : "",
	       cap & (1 << 19) ? "nz " : "",
	       cap & (1 << 18) ? "only " : "",
	       cap & (1 << 17) ? "pmp " : "",
	       cap & (1 << 16) ? "fbss " : "",
	       cap & (1 << 15) ? "pio " : "",
	       cap & (1 << 14) ? "slum " : "",
	       cap & (1 << 13) ? "part " : "",
	       cap & (1 << 7) ? "ccc " : "",
	       cap & (1 << 6) ? "ems " : "",
	       cap & (1 << 5) ? "sxs " : "",
	       cap2 & (1 << 2) ? "apst " : "",
	       cap2 & (1 << 1) ? "nvmp " : "",
	       cap2 & (1 << 0) ? "boh " : "");
}

static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
{
	int rc;

	uc_priv->dev = dev;

	uc_priv->host_flags = ATA_FLAG_SATA
				| ATA_FLAG_NO_LEGACY
				| ATA_FLAG_MMIO
				| ATA_FLAG_PIO_DMA
				| ATA_FLAG_NO_ATAPI;
	uc_priv->pio_mask = 0x1f;
	uc_priv->udma_mask = 0x7f;	/*Fixme,assume to support UDMA6 */

	struct scsi_plat *plat = dev_get_uclass_plat(dev);
	uc_priv->mmio_base = (void *)plat->base;

	debug("ahci mmio_base=0x%p\n", uc_priv->mmio_base);
	/* initialize adapter */
	rc = ahci_host_init(uc_priv);
	if (rc)
		goto err_out;

	ahci_print_info(uc_priv);

	return 0;

      err_out:
	return rc;
}

#define MAX_DATA_BYTE_COUNT  (4*1024*1024)

static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port,
			unsigned char *buf, int buf_len)
{
	struct ahci_ioports *pp = &(uc_priv->port[port]);
	struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
	phys_addr_t pa = virt_to_phys(buf);
	u32 sg_count;
	int i;

	sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
	if (sg_count > AHCI_MAX_SG) {
		printf("Error:Too much sg!\n");
		return -1;
	}

	for (i = 0; i < sg_count; i++) {
		ahci_sg->addr = cpu_to_le32(lower_32_bits(pa));
		ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa));
		if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) {
			printf("Error: DMA address too high\n");
			return -1;
		}
		ahci_sg->flags_size = cpu_to_le32(0x3fffff &
					  (buf_len < MAX_DATA_BYTE_COUNT ?
					   (buf_len - 1) :
					   (MAX_DATA_BYTE_COUNT - 1)));
		ahci_sg++;
		buf_len -= MAX_DATA_BYTE_COUNT;
		pa += MAX_DATA_BYTE_COUNT;
	}

	return sg_count;
}

static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
{
	phys_addr_t pa = virt_to_phys((void *)pp->cmd_tbl);

	pp->cmd_slot->opts = cpu_to_le32(opts);
	pp->cmd_slot->status = 0;
	pp->cmd_slot->tbl_addr = cpu_to_le32(lower_32_bits(pa));
#ifdef CONFIG_PHYS_64BIT
	pp->cmd_slot->tbl_addr_hi = cpu_to_le32(upper_32_bits(pa));
#endif
}

static int wait_spinup(void __iomem *port_mmio)
{
	ulong start;
	u32 tf_data;

	start = get_timer(0);
	do {
		tf_data = readl(port_mmio + PORT_TFDATA);
		if (!(tf_data & ATA_BUSY))
			return 0;
	} while (get_timer(start) < WAIT_MS_SPINUP);

	return -ETIMEDOUT;
}

static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port)
{
	struct ahci_ioports *pp = &(uc_priv->port[port]);
	void __iomem *port_mmio = pp->port_mmio;
	u64 dma_addr;
	u32 port_status;
	void __iomem *mem;

	debug("Enter start port: %d\n", port);
	port_status = readl(port_mmio + PORT_SCR_STAT);
	debug("Port %d status: %x\n", port, port_status);
	if ((port_status & 0xf) != 0x03) {
		printf("No Link on this port!\n");
		return -1;
	}

	mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ);
	if (!mem) {
		free(pp);
		printf("%s: No mem for table!\n", __func__);
		return -ENOMEM;
	}
	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);

	/*
	 * First item in chunk of DMA memory: 32-slot command table,
	 * 32 bytes each in size
	 */
	pp->cmd_slot =
		(struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
	debug("cmd_slot = %p\n", pp->cmd_slot);
	mem += (AHCI_CMD_SLOT_SZ + 224);

	/*
	 * Second item: Received-FIS area
	 */
	pp->rx_fis = virt_to_phys((void *)mem);
	mem += AHCI_RX_FIS_SZ;

	/*
	 * Third item: data area for storing a single command
	 * and its scatter-gather table
	 */
	pp->cmd_tbl = virt_to_phys((void *)mem);
	debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl);

	mem += AHCI_CMD_TBL_HDR;
	pp->cmd_tbl_sg =
			(struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);

	dma_addr = (ulong)pp->cmd_slot;
	writel_with_flush(dma_addr, port_mmio + PORT_LST_ADDR);
	writel_with_flush(dma_addr >> 32, port_mmio + PORT_LST_ADDR_HI);
	dma_addr = (ulong)pp->rx_fis;
	writel_with_flush(dma_addr, port_mmio + PORT_FIS_ADDR);
	writel_with_flush(dma_addr >> 32, port_mmio + PORT_FIS_ADDR_HI);

#ifdef CONFIG_SUNXI_AHCI
	sunxi_dma_init(port_mmio);
#endif

	writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
			  PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
			  PORT_CMD_START, port_mmio + PORT_CMD);

	debug("Exit start port %d\n", port);

	/*
	 * Make sure interface is not busy based on error and status
	 * information from task file data register before proceeding
	 */
	return wait_spinup(port_mmio);
}

static int ahci_device_data_io(struct ahci_uc_priv *uc_priv, u8 port, u8 *fis,
			       int fis_len, u8 *buf, int buf_len, u8 is_write)
{

	struct ahci_ioports *pp = &(uc_priv->port[port]);
	void __iomem *port_mmio = pp->port_mmio;
	u32 opts;
	u32 port_status;
	int sg_count;

	debug("Enter %s: for port %d\n", __func__, port);

	if (port > uc_priv->n_ports) {
		printf("Invalid port number %d\n", port);
		return -1;
	}

	port_status = readl(port_mmio + PORT_SCR_STAT);
	if ((port_status & 0xf) != 0x03) {
		debug("No Link on port %d!\n", port);
		return -1;
	}

	memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);

	sg_count = ahci_fill_sg(uc_priv, port, buf, buf_len);
	opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
	ahci_fill_cmd_slot(pp, opts);

	ahci_dcache_flush_sata_cmd(pp);
	ahci_dcache_flush_range((unsigned long)buf, (unsigned long)buf_len);

	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);

	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
				WAIT_MS_DATAIO, 0x1)) {
		printf("timeout exit!\n");
		return -1;
	}

	ahci_dcache_invalidate_range((unsigned long)buf,
				     (unsigned long)buf_len);
	debug("%s: %d byte transferred.\n", __func__,
	      le32_to_cpu(pp->cmd_slot->status));

	return 0;
}

static char *ata_id_strcpy(u16 *target, u16 *src, int len)
{
	int i;
	for (i = 0; i < len / 2; i++)
		target[i] = swab16(src[i]);
	return (char *)target;
}

/*
 * SCSI INQUIRY command operation.
 */
static int ata_scsiop_inquiry(struct ahci_uc_priv *uc_priv,
			      struct scsi_cmd *pccb)
{
	static const u8 hdr[] = {
		0,
		0,
		0x5,		/* claim SPC-3 version compatibility */
		2,
		95 - 4,
	};
	u8 fis[20];
	u16 *idbuf;
	ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
	u8 port;

	/* Clean ccb data buffer */
	memset(pccb->pdata, 0, pccb->datalen);

	memcpy(pccb->pdata, hdr, sizeof(hdr));

	if (pccb->datalen <= 35)
		return 0;

	memset(fis, 0, sizeof(fis));
	/* Construct the FIS */
	fis[0] = 0x27;		/* Host to device FIS. */
	fis[1] = 1 << 7;	/* Command FIS. */
	fis[2] = ATA_CMD_ID_ATA; /* Command byte. */

	/* Read id from sata */
	port = pccb->target;

	/* If this port number is not valid, give up */
	if (!(uc_priv->port_map & (1 << port))) {
		debug("Port %x not valid in map %x\n", port, uc_priv->port_map);
		return -ENODEV;
	}

	if (ahci_device_data_io(uc_priv, port, (u8 *)&fis, sizeof(fis),
				(u8 *)tmpid, ATA_ID_WORDS * 2, 0)) {
		debug("scsi_ahci: SCSI inquiry command failure.\n");
		return -EIO;
	}

	if (!uc_priv->ataid[port]) {
		uc_priv->ataid[port] = malloc(ATA_ID_WORDS * 2);
		if (!uc_priv->ataid[port]) {
			printf("%s: No memory for ataid[port]\n", __func__);
			return -ENOMEM;
		}
	}

	idbuf = uc_priv->ataid[port];

	memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
	ata_swap_buf_le16(idbuf, ATA_ID_WORDS);

	memcpy(&pccb->pdata[8], "ATA     ", 8);
	ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16);
	ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4);

#ifdef DEBUG
	ata_dump_id(idbuf);
#endif
	return 0;
}

/*
 * SCSI READ10/WRITE10 command operation.
 */
static int ata_scsiop_read_write(struct ahci_uc_priv *uc_priv,
				 struct scsi_cmd *pccb, u8 is_write)
{
	lbaint_t lba = 0;
	u16 blocks = 0;
	u8 fis[20];
	u8 *user_buffer = pccb->pdata;
	u32 user_buffer_size = pccb->datalen;

	/* Retrieve the base LBA number from the ccb structure. */
	if (pccb->cmd[0] == SCSI_READ16) {
		memcpy(&lba, pccb->cmd + 2, 8);
		lba = be64_to_cpu(lba);
	} else {
		u32 temp;
		memcpy(&temp, pccb->cmd + 2, 4);
		lba = be32_to_cpu(temp);
	}

	/*
	 * Retrieve the base LBA number and the block count from
	 * the ccb structure.
	 *
	 * For 10-byte and 16-byte SCSI R/W commands, transfer
	 * length 0 means transfer 0 block of data.
	 * However, for ATA R/W commands, sector count 0 means
	 * 256 or 65536 sectors, not 0 sectors as in SCSI.
	 *
	 * WARNING: one or two older ATA drives treat 0 as 0...
	 */
	if (pccb->cmd[0] == SCSI_READ16)
		blocks = (((u16)pccb->cmd[13]) << 8) | ((u16) pccb->cmd[14]);
	else
		blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);

	debug("scsi_ahci: %s %u blocks starting from lba 0x" LBAFU "\n",
	      is_write ?  "write" : "read", blocks, lba);

	/* Preset the FIS */
	memset(fis, 0, sizeof(fis));
	fis[0] = 0x27;		 /* Host to device FIS. */
	fis[1] = 1 << 7;	 /* Command FIS. */
	/* Command byte (read/write). */
	fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;

	while (blocks) {
		u16 now_blocks; /* number of blocks per iteration */
		u32 transfer_size; /* number of bytes per iteration */

		now_blocks = min((u16)MAX_SATA_BLOCKS_READ_WRITE, blocks);

		transfer_size = ATA_SECT_SIZE * now_blocks;
		if (transfer_size > user_buffer_size) {
			printf("scsi_ahci: Error: buffer too small.\n");
			return -EIO;
		}

		/*
		 * LBA48 SATA command but only use 32bit address range within
		 * that (unless we've enabled 64bit LBA support). The next
		 * smaller command range (28bit) is too small.
		 */
		fis[4] = (lba >> 0) & 0xff;
		fis[5] = (lba >> 8) & 0xff;
		fis[6] = (lba >> 16) & 0xff;
		fis[7] = 1 << 6; /* device reg: set LBA mode */
		fis[8] = ((lba >> 24) & 0xff);
#ifdef CONFIG_SYS_64BIT_LBA
		if (pccb->cmd[0] == SCSI_READ16) {
			fis[9] = ((lba >> 32) & 0xff);
			fis[10] = ((lba >> 40) & 0xff);
		}
#endif

		fis[3] = 0xe0; /* features */

		/* Block (sector) count */
		fis[12] = (now_blocks >> 0) & 0xff;
		fis[13] = (now_blocks >> 8) & 0xff;

		/* Read/Write from ahci */
		if (ahci_device_data_io(uc_priv, pccb->target, (u8 *)&fis,
					sizeof(fis), user_buffer, transfer_size,
					is_write)) {
			debug("scsi_ahci: SCSI %s10 command failure.\n",
			      is_write ? "WRITE" : "READ");
			return -EIO;
		}

		/* If this transaction is a write, do a following flush.
		 * Writes in u-boot are so rare, and the logic to know when is
		 * the last write and do a flush only there is sufficiently
		 * difficult. Just do a flush after every write. This incurs,
		 * usually, one extra flush when the rare writes do happen.
		 */
		if (is_write) {
			if (-EIO == ata_io_flush(uc_priv, pccb->target))
				return -EIO;
		}
		user_buffer += transfer_size;
		user_buffer_size -= transfer_size;
		blocks -= now_blocks;
		lba += now_blocks;
	}

	return 0;
}

/*
 * SCSI READ CAPACITY10 command operation.
 */
static int ata_scsiop_read_capacity10(struct ahci_uc_priv *uc_priv,
				      struct scsi_cmd *pccb)
{
	u32 cap;
	u64 cap64;
	u32 block_size;

	if (!uc_priv->ataid[pccb->target]) {
		printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
		       "\tNo ATA info!\n"
		       "\tPlease run SCSI command INQUIRY first!\n");
		return -EPERM;
	}

	cap64 = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
	if (cap64 > 0x100000000ULL)
		cap64 = 0xffffffff;

	cap = cpu_to_be32(cap64);
	memcpy(pccb->pdata, &cap, sizeof(cap));

	block_size = cpu_to_be32((u32)512);
	memcpy(&pccb->pdata[4], &block_size, 4);

	return 0;
}

/*
 * SCSI READ CAPACITY16 command operation.
 */
static int ata_scsiop_read_capacity16(struct ahci_uc_priv *uc_priv,
				      struct scsi_cmd *pccb)
{
	u64 cap;
	u64 block_size;

	if (!uc_priv->ataid[pccb->target]) {
		printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
		       "\tNo ATA info!\n"
		       "\tPlease run SCSI command INQUIRY first!\n");
		return -EPERM;
	}

	cap = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
	cap = cpu_to_be64(cap);
	memcpy(pccb->pdata, &cap, sizeof(cap));

	block_size = cpu_to_be64((u64)512);
	memcpy(&pccb->pdata[8], &block_size, 8);

	return 0;
}

/*
 * SCSI TEST UNIT READY command operation.
 */
static int ata_scsiop_test_unit_ready(struct ahci_uc_priv *uc_priv,
				      struct scsi_cmd *pccb)
{
	return (uc_priv->ataid[pccb->target]) ? 0 : -EPERM;
}

static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
{
	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev->parent);
	int ret;

	switch (pccb->cmd[0]) {
	case SCSI_READ16:
	case SCSI_READ10:
		ret = ata_scsiop_read_write(uc_priv, pccb, 0);
		break;
	case SCSI_WRITE10:
		ret = ata_scsiop_read_write(uc_priv, pccb, 1);
		break;
	case SCSI_RD_CAPAC10:
		ret = ata_scsiop_read_capacity10(uc_priv, pccb);
		break;
	case SCSI_RD_CAPAC16:
		ret = ata_scsiop_read_capacity16(uc_priv, pccb);
		break;
	case SCSI_TST_U_RDY:
		ret = ata_scsiop_test_unit_ready(uc_priv, pccb);
		break;
	case SCSI_INQUIRY:
		ret = ata_scsiop_inquiry(uc_priv, pccb);
		break;
	default:
		printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
		return -ENOTSUPP;
	}

	if (ret) {
		debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
		return ret;
	}
	return 0;

}

static int ahci_start_ports(struct ahci_uc_priv *uc_priv)
{
	u32 linkmap;
	int i;

	linkmap = uc_priv->link_port_map;

	for (i = 0; i < uc_priv->n_ports; i++) {
		if (((linkmap >> i) & 0x01)) {
			if (ahci_port_start(uc_priv, (u8) i)) {
				printf("Can not start port %d\n", i);
				continue;
			}
		}
	}

	return 0;
}

int ahci_init_one_dm(struct udevice *dev)
{
	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);

	return ahci_init_one(uc_priv, dev);
}

int ahci_start_ports_dm(struct udevice *dev)
{
	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);

	return ahci_start_ports(uc_priv);
}

/*
 * In the general case of generic rotating media it makes sense to have a
 * flush capability. It probably even makes sense in the case of SSDs because
 * one cannot always know for sure what kind of internal cache/flush mechanism
 * is embodied therein. At first it was planned to invoke this after the last
 * write to disk and before rebooting. In practice, knowing, a priori, which
 * is the last write is difficult. Because writing to the disk in u-boot is
 * very rare, this flush command will be invoked after every block write.
 */
static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port)
{
	u8 fis[20];
	struct ahci_ioports *pp = &(uc_priv->port[port]);
	void __iomem *port_mmio = pp->port_mmio;
	u32 cmd_fis_len = 5;	/* five dwords */

	/* Preset the FIS */
	memset(fis, 0, 20);
	fis[0] = 0x27;		 /* Host to device FIS. */
	fis[1] = 1 << 7;	 /* Command FIS. */
	fis[2] = ATA_CMD_FLUSH_EXT;

	memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
	ahci_fill_cmd_slot(pp, cmd_fis_len);
	ahci_dcache_flush_sata_cmd(pp);
	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);

	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
			WAIT_MS_FLUSH, 0x1)) {
		debug("scsi_ahci: flush command timeout on port %d.\n", port);
		return -EIO;
	}

	return 0;
}

static int ahci_scsi_bus_reset(struct udevice *dev)
{
	/* Not implemented */

	return 0;
}

int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp)
{
	struct udevice *dev;
	int ret;

	ret = device_bind_driver(ahci_dev, "ahci_scsi", "ahci_scsi", &dev);
	if (ret)
		return ret;
	*devp = dev;

	return 0;
}

int ahci_probe_scsi(struct udevice *ahci_dev, ulong base)
{
	struct ahci_uc_priv *uc_priv;
	struct scsi_plat *uc_plat;
	struct udevice *dev;
	int ret;

	device_find_first_child(ahci_dev, &dev);
	if (!dev)
		return -ENODEV;
	uc_plat = dev_get_uclass_plat(dev);
	uc_plat->base = base;
	uc_plat->max_lun = 1;
	uc_plat->max_id = 2;

	uc_priv = dev_get_uclass_priv(ahci_dev);
	ret = ahci_init_one(uc_priv, dev);
	if (ret)
		return ret;
	ret = ahci_start_ports(uc_priv);
	if (ret)
		return ret;

	/*
	 * scsi_scan_dev() scans devices up-to the number of max_id.
	 * Update max_id if the number of detected ports exceeds max_id.
	 * This allows SCSI to scan all detected ports.
	 */
	uc_plat->max_id = max_t(unsigned long, uc_priv->n_ports,
				uc_plat->max_id);
	/* If port count is less than max_id, update max_id */
	if (uc_priv->n_ports < uc_plat->max_id)
		uc_plat->max_id = uc_priv->n_ports;

	return 0;
}

int ahci_probe_scsi_pci(struct udevice *ahci_dev)
{
	ulong base;
	u16 vendor, device, cmd;

	/* Enable bus mastering */
	dm_pci_read_config16(ahci_dev, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_MASTER;
	dm_pci_write_config16(ahci_dev, PCI_COMMAND, cmd);

	base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5, 0, 0,
				     PCI_REGION_TYPE, PCI_REGION_MEM);

	/*
	 * Note:
	 * Right now, we have only one quirk here, which is not enough to
	 * introduce a new Kconfig option to select this. Once we have more
	 * quirks in this AHCI code, we should add a Kconfig option for
	 * this though.
	 */
	dm_pci_read_config16(ahci_dev, PCI_VENDOR_ID, &vendor);
	dm_pci_read_config16(ahci_dev, PCI_DEVICE_ID, &device);

	if (vendor == PCI_VENDOR_ID_CAVIUM &&
	    device == PCI_DEVICE_ID_CAVIUM_SATA)
		base = (uintptr_t)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_0,
						 0, 0, PCI_REGION_TYPE,
						 PCI_REGION_MEM);
	return ahci_probe_scsi(ahci_dev, base);
}

struct scsi_ops scsi_ops = {
	.exec		= ahci_scsi_exec,
	.bus_reset	= ahci_scsi_bus_reset,
};

U_BOOT_DRIVER(ahci_scsi) = {
	.name		= "ahci_scsi",
	.id		= UCLASS_SCSI,
	.ops		= &scsi_ops,
};
