// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2011 Freescale Semiconductor, Inc.
 * Copyright 2019 NXP
 * Author: Tang Yuantian <b29983@freescale.com>
 */

#include <common.h>
#include <cpu_func.h>
#include <log.h>
#include <pci.h>
#include <command.h>
#include <asm/byteorder.h>
#include <malloc.h>
#include <asm/io.h>
#include <fis.h>
#include <sata.h>
#include <libata.h>
#include <sata.h>
#include <linux/delay.h>

#if CONFIG_IS_ENABLED(BLK)
#include <dm.h>
#include <blk.h>
#include <dm/device-internal.h>
#endif

#include "sata_sil.h"

#define virt_to_bus(devno, v)	dm_pci_virt_to_mem(devno, (void *) (v))

/* just compatible ahci_ops */
struct sil_ops {
	int *rev0;
	int *rev1;
	int (*scan)(struct udevice *dev);
};

static struct sata_info sata_info;

static struct pci_device_id supported[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3131) },
	{ PCI_DEVICE(PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3132) },
	{ PCI_DEVICE(PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3124) },
	{}
};

static void sil_sata_dump_fis(struct sata_fis_d2h *s)
{
	printf("Status FIS dump:\n");
	printf("fis_type:		%02x\n", s->fis_type);
	printf("pm_port_i:		%02x\n", s->pm_port_i);
	printf("status:			%02x\n", s->status);
	printf("error:			%02x\n", s->error);
	printf("lba_low:		%02x\n", s->lba_low);
	printf("lba_mid:		%02x\n", s->lba_mid);
	printf("lba_high:		%02x\n", s->lba_high);
	printf("device:			%02x\n", s->device);
	printf("lba_low_exp:		%02x\n", s->lba_low_exp);
	printf("lba_mid_exp:		%02x\n", s->lba_mid_exp);
	printf("lba_high_exp:		%02x\n", s->lba_high_exp);
	printf("res1:			%02x\n", s->res1);
	printf("sector_count:		%02x\n", s->sector_count);
	printf("sector_count_exp:	%02x\n", s->sector_count_exp);
}

static const char *sata_spd_string(unsigned int speed)
{
	static const char * const spd_str[] = {
		"1.5 Gbps",
		"3.0 Gbps",
		"6.0 Gbps",
	};

	if ((speed - 1) > 2)
		return "<unknown>";

	return spd_str[speed - 1];
}

static u32 ata_wait_register(void *reg, u32 mask,
			 u32 val, int timeout_msec)
{
	u32 tmp;

	tmp = readl(reg);
	while ((tmp & mask) == val && timeout_msec > 0) {
		mdelay(1);
		timeout_msec--;
		tmp = readl(reg);
	}

	return tmp;
}

static void sil_config_port(void *port)
{
	/* configure IRQ WoC */
	writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);

	/* zero error counters. */
	writew(0x8000, port + PORT_DECODE_ERR_THRESH);
	writew(0x8000, port + PORT_CRC_ERR_THRESH);
	writew(0x8000, port + PORT_HSHK_ERR_THRESH);
	writew(0x0000, port + PORT_DECODE_ERR_CNT);
	writew(0x0000, port + PORT_CRC_ERR_CNT);
	writew(0x0000, port + PORT_HSHK_ERR_CNT);

	/* always use 64bit activation */
	writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);

	/* clear port multiplier enable and resume bits */
	writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
}

static int sil_init_port(void *port)
{
	u32 tmp;

	writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
	ata_wait_register(port + PORT_CTRL_STAT,
			  PORT_CS_INIT, PORT_CS_INIT, 100);
	tmp = ata_wait_register(port + PORT_CTRL_STAT,
				PORT_CS_RDY, 0, 100);

	if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
		return 1;

	return 0;
}

static void sil_read_fis(struct sil_sata *sata, int tag,
			 struct sata_fis_d2h *fis)
{
	void *port = sata->port;
	struct sil_prb *prb;
	int i;
	u32 *src, *dst;

	prb = port + PORT_LRAM + tag * PORT_LRAM_SLOT_SZ;
	src = (u32 *)&prb->fis;
	dst = (u32 *)fis;
	for (i = 0; i < sizeof(struct sata_fis_h2d); i += 4)
		*dst++ = readl(src++);
}

static int sil_exec_cmd(struct sil_sata *sata, struct sil_cmd_block *pcmd,
			int tag)
{
	void *port = sata->port;
	u64 paddr = virt_to_bus(sata->devno, pcmd);
	u32 irq_mask, irq_stat;
	int rc;

	writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR);

	/* better to add momery barrior here */
	writel((u32)paddr, port + PORT_CMD_ACTIVATE + tag * 8);
	writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + tag * 8 + 4);

	irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
	irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask,
			0, 10000);

	/* clear IRQs */
	writel(irq_mask, port + PORT_IRQ_STAT);
	irq_stat >>= PORT_IRQ_RAW_SHIFT;

	if (irq_stat & PORT_IRQ_COMPLETE)
		rc = 0;
	else {
		/* force port into known state */
		sil_init_port(port);
		if (irq_stat & PORT_IRQ_ERROR)
			rc = 1; /* error */
		else
			rc = 2; /* busy */
	}

	return rc;
}

static int sil_cmd_set_feature(struct sil_sata *sata)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;
	struct sata_fis_d2h fis;
	u8 udma_cap;
	int ret;

	memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	pcmd->prb.fis.command = ATA_CMD_SET_FEATURES;
	pcmd->prb.fis.features = SETFEATURES_XFER;

	/* First check the device capablity */
	udma_cap = (u8)(sata->udma & 0xff);
	debug("udma_cap %02x\n", udma_cap);

	if (udma_cap == ATA_UDMA6)
		pcmd->prb.fis.sector_count = XFER_UDMA_6;
	if (udma_cap == ATA_UDMA5)
		pcmd->prb.fis.sector_count = XFER_UDMA_5;
	if (udma_cap == ATA_UDMA4)
		pcmd->prb.fis.sector_count = XFER_UDMA_4;
	if (udma_cap == ATA_UDMA3)
		pcmd->prb.fis.sector_count = XFER_UDMA_3;

	ret = sil_exec_cmd(sata, pcmd, 0);
	if (ret) {
		sil_read_fis(sata, 0, &fis);
		printf("Err: exe cmd(0x%x).\n",
				readl(sata->port + PORT_SERROR));
		sil_sata_dump_fis(&fis);
		return 1;
	}

	return 0;
}

static void sil_sata_init_wcache(struct sil_sata *sata, u16 *id)
{
	if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
		sata->wcache = 1;
	if (ata_id_has_flush(id))
		sata->flush = 1;
	if (ata_id_has_flush_ext(id))
		sata->flush_ext = 1;
}

static void sil_sata_set_feature_by_id(struct sil_sata *sata, u16 *id)
{
#ifdef CONFIG_LBA48
	/* Check if support LBA48 */
	if (ata_id_has_lba48(id)) {
		sata->lba48 = 1;
		debug("Device supports LBA48\n");
	} else {
		debug("Device supports LBA28\n");
	}
#endif

	sil_sata_init_wcache(sata, id);
	sil_cmd_set_feature(sata);
}

static int sil_cmd_identify_device(struct sil_sata *sata, u16 *id)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;
	struct sata_fis_d2h fis;
	int ret;

	memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
	pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	pcmd->prb.fis.command = ATA_CMD_ID_ATA;
	pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, id));
	pcmd->sge.cnt = cpu_to_le32(sizeof(id[0]) * ATA_ID_WORDS);
	pcmd->sge.flags = cpu_to_le32(SGE_TRM);

	ret = sil_exec_cmd(sata, pcmd, 0);
	if (ret) {
		sil_read_fis(sata, 0, &fis);
		printf("Err: id cmd(0x%x).\n", readl(sata->port + PORT_SERROR));
		sil_sata_dump_fis(&fis);
		return 1;
	}
	ata_swap_buf_le16(id, ATA_ID_WORDS);

	return 0;
}

static int sil_cmd_soft_reset(struct sil_sata *sata)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;
	struct sata_fis_d2h fis;
	void *port = sata->port;
	int ret;

	/* put the port into known state */
	if (sil_init_port(port)) {
		printf("SRST: port %d not ready\n", sata->id);
		return 1;
	}

	memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));

	pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_SRST);
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = 0xf;

	ret = sil_exec_cmd(sata, &cmdb, 0);
	if (ret) {
		sil_read_fis(sata, 0, &fis);
		printf("SRST cmd error.\n");
		sil_sata_dump_fis(&fis);
		return 1;
	}

	return 0;
}

static ulong sil_sata_rw_cmd(struct sil_sata *sata, ulong start, ulong blkcnt,
			     u8 *buffer, int is_write)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;
	struct sata_fis_d2h fis;
	u64 block;
	int ret;

	block = (u64)start;
	memset(pcmd, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	if (is_write) {
		pcmd->prb.fis.command = ATA_CMD_WRITE;
		pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
	} else {
		pcmd->prb.fis.command = ATA_CMD_READ;
		pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
	}

	pcmd->prb.fis.device = ATA_LBA;
	pcmd->prb.fis.device |= (block >> 24) & 0xf;
	pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
	pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
	pcmd->prb.fis.lba_low = block & 0xff;
	pcmd->prb.fis.sector_count = (u8)blkcnt & 0xff;

	pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
	pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
	pcmd->sge.flags = cpu_to_le32(SGE_TRM);

	ret = sil_exec_cmd(sata, pcmd, 0);
	if (ret) {
		sil_read_fis(sata, 0, &fis);
		printf("Err: rw cmd(0x%08x).\n",
				readl(sata->port + PORT_SERROR));
		sil_sata_dump_fis(&fis);
		return 1;
	}

	return blkcnt;
}

static ulong sil_sata_rw_cmd_ext(struct sil_sata *sata, ulong start,
				 ulong blkcnt, u8 *buffer, int is_write)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;
	struct sata_fis_d2h fis;
	u64 block;
	int ret;

	block = (u64)start;
	memset(pcmd, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	if (is_write) {
		pcmd->prb.fis.command = ATA_CMD_WRITE_EXT;
		pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
	} else {
		pcmd->prb.fis.command = ATA_CMD_READ_EXT;
		pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
	}

	pcmd->prb.fis.lba_high_exp = (block >> 40) & 0xff;
	pcmd->prb.fis.lba_mid_exp = (block >> 32) & 0xff;
	pcmd->prb.fis.lba_low_exp = (block >> 24) & 0xff;
	pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
	pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
	pcmd->prb.fis.lba_low = block & 0xff;
	pcmd->prb.fis.device = ATA_LBA;
	pcmd->prb.fis.sector_count_exp = (blkcnt >> 8) & 0xff;
	pcmd->prb.fis.sector_count = blkcnt & 0xff;

	pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
	pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
	pcmd->sge.flags = cpu_to_le32(SGE_TRM);

	ret = sil_exec_cmd(sata, pcmd, 0);
	if (ret) {
		sil_read_fis(sata, 0, &fis);
		printf("Err: rw ext cmd(0x%08x).\n",
				readl(sata->port + PORT_SERROR));
		sil_sata_dump_fis(&fis);
		return 1;
	}

	return blkcnt;
}

static ulong sil_sata_rw_lba28(struct sil_sata *sata, ulong blknr,
			       lbaint_t blkcnt, const void *buffer,
			       int is_write)
{
	ulong start, blks, max_blks;
	u8 *addr;

	start = blknr;
	blks = blkcnt;
	addr = (u8 *)buffer;

	max_blks = ATA_MAX_SECTORS;
	do {
		if (blks > max_blks) {
			sil_sata_rw_cmd(sata, start, max_blks, addr, is_write);
			start += max_blks;
			blks -= max_blks;
			addr += ATA_SECT_SIZE * max_blks;
		} else {
			sil_sata_rw_cmd(sata, start, blks, addr, is_write);
			start += blks;
			blks = 0;
			addr += ATA_SECT_SIZE * blks;
		}
	} while (blks != 0);

	return blkcnt;
}

static ulong sil_sata_rw_lba48(struct sil_sata *sata, ulong blknr,
			       lbaint_t blkcnt, const void *buffer,
			       int is_write)
{
	ulong start, blks, max_blks;
	u8 *addr;

	start = blknr;
	blks = blkcnt;
	addr = (u8 *)buffer;

	max_blks = ATA_MAX_SECTORS_LBA48;
	do {
		if (blks > max_blks) {
			sil_sata_rw_cmd_ext(sata, start, max_blks,
					    addr, is_write);
			start += max_blks;
			blks -= max_blks;
			addr += ATA_SECT_SIZE * max_blks;
		} else {
			sil_sata_rw_cmd_ext(sata, start, blks,
					    addr, is_write);
			start += blks;
			blks = 0;
			addr += ATA_SECT_SIZE * blks;
		}
	} while (blks != 0);

	return blkcnt;
}

static void sil_sata_cmd_flush_cache(struct sil_sata *sata)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;

	memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	pcmd->prb.fis.command = ATA_CMD_FLUSH;

	sil_exec_cmd(sata, pcmd, 0);
}

static void sil_sata_cmd_flush_cache_ext(struct sil_sata *sata)
{
	struct sil_cmd_block cmdb, *pcmd = &cmdb;

	memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
	pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	pcmd->prb.fis.pm_port_c = (1 << 7);
	pcmd->prb.fis.command = ATA_CMD_FLUSH_EXT;

	sil_exec_cmd(sata, pcmd, 0);
}

/*
 * SATA interface between low level driver and command layer
 */
#if !CONFIG_IS_ENABLED(BLK)
ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
{
	struct sil_sata *sata = (struct sil_sata *)sata_dev_desc[dev].priv;
#else
static ulong sata_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
		       void *buffer)
{
	struct sil_sata_priv *priv = dev_get_plat(dev);
	int port_number = priv->port_num;
	struct sil_sata *sata = priv->sil_sata_desc[port_number];
#endif
	ulong rc;

	if (sata->lba48)
		rc = sil_sata_rw_lba48(sata, blknr, blkcnt, buffer, READ_CMD);
	else
		rc = sil_sata_rw_lba28(sata, blknr, blkcnt, buffer, READ_CMD);

	return rc;
}

/*
 * SATA interface between low level driver and command layer
 */
#if !CONFIG_IS_ENABLED(BLK)
ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
{
	struct sil_sata *sata = (struct sil_sata *)sata_dev_desc[dev].priv;
#else
ulong sata_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
		 const void *buffer)
{
	struct sil_sata_priv *priv = dev_get_plat(dev);
	int port_number = priv->port_num;
	struct sil_sata *sata = priv->sil_sata_desc[port_number];
#endif
	ulong rc;

	if (sata->lba48) {
		rc = sil_sata_rw_lba48(sata, blknr, blkcnt, buffer, WRITE_CMD);
		if (sata->wcache && sata->flush_ext)
			sil_sata_cmd_flush_cache_ext(sata);
	} else {
		rc = sil_sata_rw_lba28(sata, blknr, blkcnt, buffer, WRITE_CMD);
		if (sata->wcache && sata->flush)
			sil_sata_cmd_flush_cache(sata);
	}

	return rc;
}

#if !CONFIG_IS_ENABLED(BLK)
static int sil_init_sata(int dev)
{
#else
static int sil_init_sata(struct udevice *uc_dev, int dev)
{
	struct sil_sata_priv *priv = dev_get_plat(uc_dev);
#endif
	struct sil_sata *sata;
	void *port;
	u32 tmp;
	int cnt;

	printf("SATA#%d:\n", dev);

	port = (void *)sata_info.iobase[1] +
		PORT_REGS_SIZE * (dev - sata_info.portbase);

	/* Initial PHY setting */
	writel(0x20c, port + PORT_PHY_CFG);

	/* clear port RST */
	tmp = readl(port + PORT_CTRL_STAT);
	if (tmp & PORT_CS_PORT_RST) {
		writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
		tmp = ata_wait_register(port + PORT_CTRL_STAT,
				PORT_CS_PORT_RST, PORT_CS_PORT_RST, 100);
		if (tmp & PORT_CS_PORT_RST)
			printf("Err: Failed to clear port RST\n");
	}

	/* Check if device is present */
	for (cnt = 0; cnt < 100; cnt++) {
		tmp = readl(port + PORT_SSTATUS);
		if ((tmp & 0xF) == 0x3)
			break;
		mdelay(1);
	}

	tmp = readl(port + PORT_SSTATUS);
	if ((tmp & 0xf) != 0x3) {
		printf("	(No RDY)\n");
		return 1;
	}

	/* Wait for port ready */
	tmp = ata_wait_register(port + PORT_CTRL_STAT,
				PORT_CS_RDY, PORT_CS_RDY, 100);
	if ((tmp & PORT_CS_RDY) != PORT_CS_RDY) {
		printf("%d port not ready.\n", dev);
		return 1;
	}

	/* configure port */
	sil_config_port(port);

	/* Reset port */
	writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
	readl(port + PORT_CTRL_STAT);
	tmp = ata_wait_register(port + PORT_CTRL_STAT, PORT_CS_DEV_RST,
				PORT_CS_DEV_RST, 100);
	if (tmp & PORT_CS_DEV_RST) {
		printf("%d port reset failed.\n", dev);
		return 1;
	}

	sata = (struct sil_sata *)malloc(sizeof(struct sil_sata));
	if (!sata) {
		printf("%d no memory.\n", dev);
		return 1;
	}
	memset((void *)sata, 0, sizeof(struct sil_sata));

	/* Save the private struct to block device struct */
#if !CONFIG_IS_ENABLED(BLK)
	sata_dev_desc[dev].priv = (void *)sata;
	sata->devno = sata_info.devno;
#else
	priv->sil_sata_desc[dev] = sata;
	priv->port_num = dev;
	sata->devno = uc_dev->parent;
#endif
	sata->id = dev;
	sata->port = port;
	sprintf(sata->name, "SATA#%d", dev);
	sil_cmd_soft_reset(sata);
	tmp = readl(port + PORT_SSTATUS);
	tmp = (tmp >> 4) & 0xf;
	printf("	(%s)\n", sata_spd_string(tmp));

	return 0;
}

#if !CONFIG_IS_ENABLED(BLK)
/*
 * SATA interface between low level driver and command layer
 */
int init_sata(int dev)
{
	static int init_done, idx;
	pci_dev_t devno;
	u16 word;

	if (init_done == 1 && dev < sata_info.maxport)
		goto init_start;

	init_done = 1;

	/* Find PCI device(s) */
	devno = pci_find_devices(supported, idx++);
	if (devno == -1)
		return 1;

	pci_read_config_word(devno, PCI_DEVICE_ID, &word);

	/* get the port count */
	word &= 0xf;

	sata_info.portbase = 0;
	sata_info.maxport = sata_info.portbase + word;
	sata_info.devno = devno;

	/* Read out all BARs */
	sata_info.iobase[0] = (ulong)pci_map_bar(devno,
			PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
	sata_info.iobase[1] = (ulong)pci_map_bar(devno,
			PCI_BASE_ADDRESS_2, PCI_REGION_MEM);

	/* mask out the unused bits */
	sata_info.iobase[0] &= 0xffffff80;
	sata_info.iobase[1] &= 0xfffffc00;

	/* Enable Bus Mastering and memory region */
	pci_write_config_word(devno, PCI_COMMAND,
			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

	/* Check if mem accesses and Bus Mastering are enabled. */
	pci_read_config_word(devno, PCI_COMMAND, &word);
	if (!(word & PCI_COMMAND_MEMORY) ||
	    (!(word & PCI_COMMAND_MASTER))) {
		printf("Error: Can not enable MEM access or Bus Mastering.\n");
		debug("PCI command: %04x\n", word);
		return 1;
	}

	/* GPIO off */
	writel(0, (void *)(sata_info.iobase[0] + HOST_FLASH_CMD));
	/* clear global reset & mask interrupts during initialization */
	writel(0, (void *)(sata_info.iobase[0] + HOST_CTRL));

init_start:
	return sil_init_sata(dev);
}

int reset_sata(int dev)
{
	return 0;
}

/*
 * SATA interface between low level driver and command layer
 */
int scan_sata(int dev)
{
	struct sil_sata *sata = (struct sil_sata *)sata_dev_desc[dev].priv;
#else
static int scan_sata(struct udevice *blk_dev, int dev)
{
	struct blk_desc *desc = dev_get_uclass_plat(blk_dev);
	struct sil_sata_priv *priv = dev_get_plat(blk_dev);
	struct sil_sata *sata = priv->sil_sata_desc[dev];
#endif
	unsigned char serial[ATA_ID_SERNO_LEN + 1];
	unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
	unsigned char product[ATA_ID_PROD_LEN + 1];
	u16 *id;

	id = (u16 *)malloc(ATA_ID_WORDS * 2);
	if (!id) {
		printf("Id malloc failed\n");
		return 1;
	}
	sil_cmd_identify_device(sata, id);

	sil_sata_set_feature_by_id(sata, id);

	/* Serial number */
	ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));

	/* Firmware version */
	ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));

	/* Product model */
	ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));

#if !CONFIG_IS_ENABLED(BLK)
	memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
	memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
	memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
	/* Totoal sectors */
	sata_dev_desc[dev].lba = ata_id_n_sectors(id);
#ifdef CONFIG_LBA48
	sata_dev_desc[dev].lba48 = sata->lba48;
#endif
#else
	memcpy(desc->product, serial, sizeof(serial));
	memcpy(desc->revision, firmware, sizeof(firmware));
	memcpy(desc->vendor, product, sizeof(product));
	desc->lba = ata_id_n_sectors(id);
#ifdef CONFIG_LBA48
	desc->lba48 = sata->lba48;
#endif
#endif

#ifdef DEBUG
	ata_dump_id(id);
#endif
	free((void *)id);

	return 0;
}

#if CONFIG_IS_ENABLED(BLK)
static const struct blk_ops sata_sil_blk_ops = {
	.read	= sata_read,
	.write	= sata_write,
};

U_BOOT_DRIVER(sata_sil_driver) = {
	.name = "sata_sil_blk",
	.id = UCLASS_BLK,
	.ops = &sata_sil_blk_ops,
	.plat_auto	= sizeof(struct sil_sata_priv),
};

static int sil_unbind_device(struct udevice *dev)
{
	int ret;

	ret = device_remove(dev, DM_REMOVE_NORMAL);
	if (ret)
		return ret;

	ret = device_unbind(dev);
	if (ret)
		return ret;

	return 0;
}

static int sil_pci_probe(struct udevice *dev)
{
	struct udevice *blk;
	int failed_number;
	char sata_name[10];
	pci_dev_t devno;
	u16 word;
	int ret;
	int i;

	failed_number = 0;

	/* Get PCI device number */
	devno = dm_pci_get_bdf(dev);
	if (devno == -1)
		return 1;

	dm_pci_read_config16(dev, PCI_DEVICE_ID, &word);

	/* get the port count */
	word &= 0xf;

	sata_info.portbase = 0;
	sata_info.maxport = sata_info.portbase + word;
	sata_info.devno = devno;

	/* Read out all BARs */
	sata_info.iobase[0] = (ulong)dm_pci_map_bar(dev,
			PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
	sata_info.iobase[1] = (ulong)dm_pci_map_bar(dev,
			PCI_BASE_ADDRESS_2, PCI_REGION_MEM);

	/* mask out the unused bits */
	sata_info.iobase[0] &= 0xffffff80;
	sata_info.iobase[1] &= 0xfffffc00;

	/* Enable Bus Mastering and memory region */
	dm_pci_write_config16(dev, PCI_COMMAND,
			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

	/* Check if mem accesses and Bus Mastering are enabled. */
	dm_pci_read_config16(dev, PCI_COMMAND, &word);
	if (!(word & PCI_COMMAND_MEMORY) ||
	    (!(word & PCI_COMMAND_MASTER))) {
		printf("Error: Can not enable MEM access or Bus Mastering.\n");
		debug("PCI command: %04x\n", word);
		return 1;
	}

	/* GPIO off */
	writel(0, (void *)(sata_info.iobase[0] + HOST_FLASH_CMD));
	/* clear global reset & mask interrupts during initialization */
	writel(0, (void *)(sata_info.iobase[0] + HOST_CTRL));

	for (i = sata_info.portbase; i < sata_info.maxport; i++) {
		snprintf(sata_name, sizeof(sata_name), "sil_sata%d", i);
		ret = blk_create_devicef(dev, "sata_sil_blk", sata_name,
					 IF_TYPE_SATA, -1, 512, 0, &blk);
		if (ret) {
			debug("Can't create device\n");
			return ret;
		}

		ret = sil_init_sata(blk, i);
		if (ret) {
			ret = sil_unbind_device(blk);
			if (ret)
				return ret;

			failed_number++;
			continue;
		}

		ret = scan_sata(blk, i);
		if (ret) {
			ret = sil_unbind_device(blk);
			if (ret)
				return ret;

			failed_number++;
			continue;
		}
	}

	if (failed_number == sata_info.maxport)
		return -ENODEV;
	else
		return 0;
}

static int sil_pci_remove(struct udevice *dev)
{
	int i;
	struct sil_sata *sata;
	struct sil_sata_priv *priv;

	priv = dev_get_priv(dev);

	for (i = sata_info.portbase; i < sata_info.maxport; i++) {
		sata = priv->sil_sata_desc[i];
		if (sata)
			free(sata);
	}

	return 0;
}

static int sata_sil_scan(struct udevice *dev)
{
	/* Nothing to do here */

	return 0;
}

struct sil_ops sata_sil_ops = {
	.scan = sata_sil_scan,
};

static const struct udevice_id sil_pci_ids[] = {
	{ .compatible = "sil-pci-sample" },
	{ }
};

U_BOOT_DRIVER(sil_ahci_pci) = {
	.name	= "sil_ahci_pci",
	.id	= UCLASS_AHCI,
	.of_match = sil_pci_ids,
	.ops = &sata_sil_ops,
	.probe = sil_pci_probe,
	.remove = sil_pci_remove,
	.priv_auto	= sizeof(struct sil_sata_priv),
};

U_BOOT_PCI_DEVICE(sil_ahci_pci, supported);
#endif
