// 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)	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_platdata(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_platdata(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_platdata(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;
#else
	priv->sil_sata_desc[dev] = sata;
	priv->port_num = dev;
#endif
	sata->id = dev;
	sata->port = port;
	sata->devno = sata_info.devno;
	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_platdata(blk_dev);
	struct sil_sata_priv *priv = dev_get_platdata(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,
	.platdata_auto_alloc_size = 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_alloc_size = sizeof(struct sil_sata_priv),
};

U_BOOT_PCI_DEVICE(sil_ahci_pci, supported);
#endif
