/*
 * Copyright (C) Procsys. All rights reserved.
 * Author: Mushtaq Khan <mushtaq_k@procsys.com>
 *			<mushtaqk_921@yahoo.co.in>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 * with the reference to ata_piix driver in kernel 2.4.32
 */

/*
 * This file contains SATA controller and SATA drive initialization functions
 */

#include <common.h>
#include <asm/io.h>
#include <pci.h>
#include <command.h>
#include <config.h>
#include <asm/byteorder.h>
#include <part.h>
#include <ide.h>
#include <ata.h>
#include <sata.h>

#define DEBUG_SATA 0		/* For debug prints set DEBUG_SATA to 1 */

#define SATA_DECL
#define DRV_DECL		/* For file specific declarations */
#include "ata_piix.h"

/* Macros realted to PCI */
#define PCI_SATA_BUS	0x00
#define PCI_SATA_DEV	0x1f
#define PCI_SATA_FUNC	0x02

#define PCI_SATA_BASE1 0x10
#define PCI_SATA_BASE2 0x14
#define PCI_SATA_BASE3 0x18
#define PCI_SATA_BASE4 0x1c
#define PCI_SATA_BASE5 0x20
#define PCI_PMR         0x90
#define PCI_PI          0x09
#define PCI_PCS         0x92
#define PCI_DMA_CTL     0x48

#define PORT_PRESENT (1<<0)
#define PORT_ENABLED (1<<4)

u32 bdf;
u32 iobase1;		/* Primary cmd block */
u32 iobase2;		/* Primary ctl block */
u32 iobase3;		/* Sec cmd block */
u32 iobase4;		/* sec ctl block */
u32 iobase5;		/* BMDMA*/

int pci_sata_init(void)
{
	u32 bus = PCI_SATA_BUS;
	u32 dev = PCI_SATA_DEV;
	u32 fun = PCI_SATA_FUNC;
	u16 cmd = 0;
	u8 lat = 0, pcibios_max_latency = 0xff;
	u8 pmr; /* Port mapping reg */
	u8 pi; /* Prgming Interface reg */

	bdf = PCI_BDF(bus, dev, fun);
	pci_read_config_dword(bdf, PCI_SATA_BASE1, &iobase1);
	pci_read_config_dword(bdf, PCI_SATA_BASE2, &iobase2);
	pci_read_config_dword(bdf, PCI_SATA_BASE3, &iobase3);
	pci_read_config_dword(bdf, PCI_SATA_BASE4, &iobase4);
	pci_read_config_dword(bdf, PCI_SATA_BASE5, &iobase5);

	if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) ||
	    (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) ||
	    (iobase5 == 0xFFFFFFFF)) {
		/* ERROR */
		printf("error no base addr for SATA controller\n");
		return 1;
	}

	iobase1 &= 0xFFFFFFFE;
	iobase2 &= 0xFFFFFFFE;
	iobase3 &= 0xFFFFFFFE;
	iobase4 &= 0xFFFFFFFE;
	iobase5 &= 0xFFFFFFFE;

	/* check for mode */
	pci_read_config_byte(bdf, PCI_PMR, &pmr);
	if (pmr > 1) {
		puts("combined mode not supported\n");
		return 1;
	}

	pci_read_config_byte(bdf, PCI_PI, &pi);
	if ((pi & 0x05) != 0x05) {
		puts("Sata is in Legacy mode\n");
		return 1;
	} else
		puts("sata is in Native mode\n");

	/* MASTER CFG AND IO CFG */
	pci_read_config_word(bdf, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
	pci_write_config_word(bdf, PCI_COMMAND, cmd);
	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);

	if (lat < 16)
		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
	else if (lat > pcibios_max_latency)
		lat = pcibios_max_latency;
	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);

	return 0;
}

int sata_bus_probe(int port_no)
{
	int orig_mask, mask;
	u16 pcs;

	mask = (PORT_PRESENT << port_no);
	pci_read_config_word(bdf, PCI_PCS, &pcs);
	orig_mask = (int) pcs & 0xff;
	if ((orig_mask & mask) != mask)
		return 0;
	else
		return 1;
}

int init_sata(int dev)
{
	static int done;
	u8 i, rv = 0;

	if (!done)
		done = 1;
	else
		return 0;

	rv = pci_sata_init();
	if (rv == 1) {
		puts("pci initialization failed\n");
		return 1;
	}

	port[0].port_no = 0;
	port[0].ioaddr.cmd_addr = iobase1;
	port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
	    iobase2 | ATA_PCI_CTL_OFS;
	port[0].ioaddr.bmdma_addr = iobase5;

	port[1].port_no = 1;
	port[1].ioaddr.cmd_addr = iobase3;
	port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
	    iobase4 | ATA_PCI_CTL_OFS;
	port[1].ioaddr.bmdma_addr = iobase5 + 0x8;

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++)
		sata_port(&port[i].ioaddr);

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) {
		if (!(sata_bus_probe(i))) {
			port[i].port_state = 0;
			printf("SATA#%d port is not present\n", i);
		} else {
			printf("SATA#%d port is present\n", i);
			if (sata_bus_softreset(i))
				port[i].port_state = 0;
			else
				port[i].port_state = 1;
		}
	}

	for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) {
		u8 j, devno;

		if (port[i].port_state == 0)
			continue;
		for (j = 0; j < CONFIG_SYS_SATA_DEVS_PER_BUS; j++) {
			sata_identify(i, j);
			set_Feature_cmd(i, j);
			devno = i * CONFIG_SYS_SATA_DEVS_PER_BUS + j;
			if ((sata_dev_desc[devno].lba > 0) &&
			    (sata_dev_desc[devno].blksz > 0)) {
				dev_print(&sata_dev_desc[devno]);
				/* initialize partition type */
				init_part(&sata_dev_desc[devno]);
			}
		}
	}
	return 0;
}

static inline u8 sata_inb(unsigned long ioaddr)
{
	return inb(ioaddr);
}

static inline void sata_outb(unsigned char val, unsigned long ioaddr)
{
	outb(val, ioaddr);
}

static void output_data(struct sata_ioports *ioaddr, ulong * sect_buf,
		int words)
{
	outsw(ioaddr->data_addr, sect_buf, words << 1);
}

static int input_data(struct sata_ioports *ioaddr, ulong * sect_buf, int words)
{
	insw(ioaddr->data_addr, sect_buf, words << 1);
	return 0;
}

static void sata_cpy(unsigned char *dst, unsigned char *src, unsigned int len)
{
	unsigned char *end, *last;

	last = dst;
	end = src + len - 1;

	/* reserve space for '\0' */
	if (len < 2)
		goto OUT;

	/* skip leading white space */
	while ((*src) && (src < end) && (*src == ' '))
		++src;

	/* copy string, omitting trailing white space */
	while ((*src) && (src < end)) {
		*dst++ = *src;
		if (*src++ != ' ')
			last = dst;
	}
OUT:
	*last = '\0';
}

int sata_bus_softreset(int num)
{
	u8 dev = 0, status = 0, i;

	port[num].dev_mask = 0;

	for (i = 0; i < CONFIG_SYS_SATA_DEVS_PER_BUS; i++) {
		if (!(sata_devchk(&port[num].ioaddr, i))) {
			debug("dev_chk failed for dev#%d\n", i);
		} else {
			port[num].dev_mask |= (1 << i);
			debug("dev_chk passed for dev#%d\n", i);
		}
	}

	if (!(port[num].dev_mask)) {
		printf("no devices on port%d\n", num);
		return 1;
	}

	dev_select(&port[num].ioaddr, dev);

	port[num].ctl_reg = 0x08;	/* Default value of control reg */
	sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr);
	udelay(10);
	sata_outb(port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
	udelay(10);
	sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr);

	/*
	 * spec mandates ">= 2ms" before checking status.
	 * We wait 150ms, because that was the magic delay used for
	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
	 * between when the ATA command register is written, and then
	 * status is checked.  Because waiting for "a while" before
	 * checking status is fine, post SRST, we perform this magic
	 * delay here as well.
	 */
	mdelay(150);
	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 300);
	while ((status & ATA_BUSY)) {
		mdelay(100);
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 3);
	}

	if (status & ATA_BUSY)
		printf("ata%u is slow to respond,plz be patient\n", num);

	while ((status & ATA_BUSY)) {
		mdelay(100);
		status = sata_chk_status(&port[num].ioaddr);
	}

	if (status & ATA_BUSY) {
		printf("ata%u failed to respond : bus reset failed\n", num);
		return 1;
	}
	return 0;
}

void sata_identify(int num, int dev)
{
	u8 cmd = 0, status = 0;
	u8 devno = num * CONFIG_SYS_SATA_DEVS_PER_BUS + dev;
	u16 iobuf[ATA_SECT_SIZE];
	u64 n_sectors = 0;
	u8 mask = 0;

	memset(iobuf, 0, sizeof(iobuf));
	hd_driveid_t *iop = (hd_driveid_t *) iobuf;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		printf("dev%d is not present on port#%d\n", dev, num);
		return;
	}

	printf("port=%d dev=%d\n", num, dev);

	dev_select(&port[num].ioaddr, dev);

	status = 0;
	cmd = ATA_CMD_IDENT;	/* Device Identify Command */
	sata_outb(cmd, port[num].ioaddr.command_addr);
	sata_inb(port[num].ioaddr.altstatus_addr);
	udelay(10);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 1000);
	if (status & ATA_ERR) {
		puts("\ndevice not responding\n");
		port[num].dev_mask &= ~mask;
		return;
	}

	input_data(&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS);

	debug("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x"
		"86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49],
		iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86],
		iobuf[87], iobuf[88]);

	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
	if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf))
		debug("ata%u: no dma/lba\n", num);
	ata_dump_id(iobuf);

	if (ata_id_has_lba48(iobuf))
		n_sectors = ata_id_u64(iobuf, 100);
	else
		n_sectors = ata_id_u32(iobuf, 60);
	debug("no. of sectors %u\n", ata_id_u64(iobuf, 100));
	debug("no. of sectors %u\n", ata_id_u32(iobuf, 60));

	if (n_sectors == 0) {
		port[num].dev_mask &= ~mask;
		return;
	}

	sata_cpy((unsigned char *)sata_dev_desc[devno].revision, iop->fw_rev,
		  sizeof(sata_dev_desc[devno].revision));
	sata_cpy((unsigned char *)sata_dev_desc[devno].vendor, iop->model,
		  sizeof(sata_dev_desc[devno].vendor));
	sata_cpy((unsigned char *)sata_dev_desc[devno].product, iop->serial_no,
		  sizeof(sata_dev_desc[devno].product));
	strswab(sata_dev_desc[devno].revision);
	strswab(sata_dev_desc[devno].vendor);

	if ((iop->config & 0x0080) == 0x0080)
		sata_dev_desc[devno].removable = 1;
	else
		sata_dev_desc[devno].removable = 0;

	sata_dev_desc[devno].lba = iop->lba_capacity;
	debug("lba=0x%x", sata_dev_desc[devno].lba);

#ifdef CONFIG_LBA48
	if (iop->command_set_2 & 0x0400) {
		sata_dev_desc[devno].lba48 = 1;
		lba = (unsigned long long) iop->lba48_capacity[0] |
		    ((unsigned long long) iop->lba48_capacity[1] << 16) |
		    ((unsigned long long) iop->lba48_capacity[2] << 32) |
		    ((unsigned long long) iop->lba48_capacity[3] << 48);
	} else {
		sata_dev_desc[devno].lba48 = 0;
	}
#endif

	/* assuming HD */
	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
	sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);
	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */
}

void set_Feature_cmd(int num, int dev)
{
	u8 mask = 0x00, status = 0;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		debug("dev%d is not present on port#%d\n", dev, num);
		return;
	}

	dev_select(&port[num].ioaddr, dev);

	sata_outb(SETFEATURES_XFER, port[num].ioaddr.feature_addr);
	sata_outb(XFER_PIO_4, port[num].ioaddr.nsect_addr);
	sata_outb(0, port[num].ioaddr.lbal_addr);
	sata_outb(0, port[num].ioaddr.lbam_addr);
	sata_outb(0, port[num].ioaddr.lbah_addr);

	sata_outb(ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
	sata_outb(ATA_CMD_SETF, port[num].ioaddr.command_addr);

	udelay(50);
	mdelay(150);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 5000);
	if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) {
		printf("Error  : status 0x%02x\n", status);
		port[num].dev_mask &= ~mask;
	}
}

void sata_port(struct sata_ioports *ioport)
{
	ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
	ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
	ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
	ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
	ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
	ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
	ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
	ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
	ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
	ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
}

int sata_devchk(struct sata_ioports *ioaddr, int dev)
{
	u8 nsect, lbal;

	dev_select(ioaddr, dev);

	sata_outb(0x55, ioaddr->nsect_addr);
	sata_outb(0xaa, ioaddr->lbal_addr);

	sata_outb(0xaa, ioaddr->nsect_addr);
	sata_outb(0x55, ioaddr->lbal_addr);

	sata_outb(0x55, ioaddr->nsect_addr);
	sata_outb(0xaa, ioaddr->lbal_addr);

	nsect = sata_inb(ioaddr->nsect_addr);
	lbal = sata_inb(ioaddr->lbal_addr);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return 1;	/* we found a device */
	else
		return 0;	/* nothing found */
}

void dev_select(struct sata_ioports *ioaddr, int dev)
{
	u8 tmp = 0;

	if (dev == 0)
		tmp = ATA_DEVICE_OBS;
	else
		tmp = ATA_DEVICE_OBS | ATA_DEV1;

	sata_outb(tmp, ioaddr->device_addr);
	sata_inb(ioaddr->altstatus_addr);
	udelay(5);
}

u8 sata_busy_wait(struct sata_ioports *ioaddr, int bits, unsigned int max)
{
	u8 status;

	do {
		udelay(1000);
		status = sata_chk_status(ioaddr);
		max--;
	} while ((status & bits) && (max > 0));

	return status;
}

u8 sata_chk_status(struct sata_ioports *ioaddr)
{
	return sata_inb(ioaddr->status_addr);
}


ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buff)
{
	ulong n = 0, *buffer = (ulong *)buff;
	u8 dev = 0, num = 0, mask = 0, status = 0;

#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr & 0x0000fffff0000000) {
		if (!sata_dev_desc[devno].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	/* Port Number */
	num = device / CONFIG_SYS_SATA_DEVS_PER_BUS;
	/* dev on the port */
	if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS)
		dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS;
	else
		dev = device;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	if (!(port[num].dev_mask & mask)) {
		printf("dev%d is not present on port#%d\n", dev, num);
		return 0;
	}

	/* Select device */
	dev_select(&port[num].ioaddr, dev);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
	if (status & ATA_BUSY) {
		printf("ata%u failed to respond\n", port[num].port_no);
		return n;
	}
	while (blkcnt-- > 0) {
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
		if (status & ATA_BUSY) {
			printf("ata%u failed to respond\n", 0);
			return n;
		}
#ifdef CONFIG_LBA48
		if (lba48) {
			/* write high bits */
			sata_outb(0, port[num].ioaddr.nsect_addr);
			sata_outb((blknr >> 24) & 0xFF,
				   port[num].ioaddr.lbal_addr);
			sata_outb((blknr >> 32) & 0xFF,
				   port[num].ioaddr.lbam_addr);
			sata_outb((blknr >> 40) & 0xFF,
				   port[num].ioaddr.lbah_addr);
		}
#endif
		sata_outb(1, port[num].ioaddr.nsect_addr);
		sata_outb(((blknr) >> 0) & 0xFF,
			   port[num].ioaddr.lbal_addr);
		sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
		sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);

#ifdef CONFIG_LBA48
		if (lba48) {
			sata_outb(ATA_LBA, port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_READ_EXT,
				   port[num].ioaddr.command_addr);
		} else
#endif
		{
			sata_outb(ATA_LBA | ((blknr >> 24) & 0xF),
				   port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_READ,
				   port[num].ioaddr.command_addr);
		}

		mdelay(50);
		/* may take up to 4 sec */
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000);

		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
		    != ATA_STAT_DRQ) {
			u8 err = 0;

			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
				device, (ulong) blknr, status);
			err = sata_inb(port[num].ioaddr.error_addr);
			printf("Error reg = 0x%x\n", err);
			return n;
		}
		input_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS);
		sata_inb(port[num].ioaddr.altstatus_addr);
		udelay(50);

		++n;
		++blknr;
		buffer += ATA_SECTORWORDS;
	}
	return n;
}

ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buff)
{
	ulong n = 0, *buffer = (ulong *)buff;
	unsigned char status = 0, num = 0, dev = 0, mask = 0;

#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr & 0x0000fffff0000000) {
		if (!sata_dev_desc[devno].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	/* Port Number */
	num = device / CONFIG_SYS_SATA_DEVS_PER_BUS;
	/* dev on the Port */
	if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS)
		dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS;
	else
		dev = device;

	if (dev == 0)
		mask = 0x01;
	else
		mask = 0x02;

	/* Select device */
	dev_select(&port[num].ioaddr, dev);

	status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
	if (status & ATA_BUSY) {
		printf("ata%u failed to respond\n", port[num].port_no);
		return n;
	}

	while (blkcnt-- > 0) {
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500);
		if (status & ATA_BUSY) {
			printf("ata%u failed to respond\n",
				port[num].port_no);
			return n;
		}
#ifdef CONFIG_LBA48
		if (lba48) {
			/* write high bits */
			sata_outb(0, port[num].ioaddr.nsect_addr);
			sata_outb((blknr >> 24) & 0xFF,
				   port[num].ioaddr.lbal_addr);
			sata_outb((blknr >> 32) & 0xFF,
				   port[num].ioaddr.lbam_addr);
			sata_outb((blknr >> 40) & 0xFF,
				   port[num].ioaddr.lbah_addr);
		}
#endif
		sata_outb(1, port[num].ioaddr.nsect_addr);
		sata_outb((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
		sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
		sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
#ifdef CONFIG_LBA48
		if (lba48) {
			sata_outb(ATA_LBA, port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_WRITE_EXT,
				   port[num].ioaddr.command_addr);
		} else
#endif
		{
			sata_outb(ATA_LBA | ((blknr >> 24) & 0xF),
				   port[num].ioaddr.device_addr);
			sata_outb(ATA_CMD_WRITE,
				   port[num].ioaddr.command_addr);
		}

		mdelay(50);
		/* may take up to 4 sec */
		status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000);
		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
		    != ATA_STAT_DRQ) {
			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
				device, (ulong) blknr, status);
			return n;
		}

		output_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS);
		sata_inb(port[num].ioaddr.altstatus_addr);
		udelay(50);

		++n;
		++blknr;
		buffer += ATA_SECTORWORDS;
	}
	return n;
}

int scan_sata(int dev)
{
	return 0;
}
