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

#include <blk.h>
#include <cpu_func.h>
#include <dm.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 <dm/device-internal.h>
#include <linux/delay.h>

#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
 */
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];
	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
 */
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];
	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;
}

static int sil_init_sata(struct udevice *uc_dev, int dev)
{
	struct sil_sata_priv *priv = dev_get_plat(uc_dev);
	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 */
	priv->sil_sata_desc[dev] = sata;
	priv->port_num = dev;
	sata->devno = uc_dev->parent;
	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;
}

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];
	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));

	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

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

	return 0;
}

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, 0, 0, PCI_REGION_TYPE,
			PCI_REGION_MEM);
	sata_info.iobase[1] = (ulong)dm_pci_map_bar(dev,
			PCI_BASE_ADDRESS_2, 0, 0, PCI_REGION_TYPE,
			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,
					 UCLASS_AHCI, -1, DEFAULT_BLKSZ,
					 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;
		}

		ret = device_probe(dev);
		if (ret < 0) {
			debug("Probing %s failed (%d)\n", dev->name, ret);
			ret = sil_unbind_device(blk);
			device_unbind(dev);
			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);
