/*
 * Copyright 2012 Calxeda, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <ahci.h>
#include <asm/io.h>

#define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f))
#define CPHY_ADDR(base, dev, addr) ((base) | (((addr) & 0x1ff) << 2))
#define CPHY_BASE			0xfff58000
#define CPHY_WIDTH			0x1000
#define CPHY_DTE_XS			5
#define CPHY_MII			31
#define SERDES_CR_CTL			0x80a0
#define SERDES_CR_ADDR			0x80a1
#define SERDES_CR_DATA			0x80a2
#define CR_BUSY				0x0001
#define CR_START			0x0001
#define CR_WR_RDN			0x0002
#define CPHY_TX_INPUT_STS		0x2001
#define CPHY_RX_INPUT_STS		0x2002
#define CPHY_SATA_TX_OVERRIDE_BIT	0x8000
#define CPHY_SATA_RX_OVERRIDE_BIT	0x4000
#define CPHY_TX_INPUT_OVERRIDE		0x2004
#define CPHY_RX_INPUT_OVERRIDE		0x2005
#define SPHY_LANE			0x100
#define SPHY_HALF_RATE			0x0001
#define CPHY_SATA_DPLL_MODE		0x0700
#define CPHY_SATA_DPLL_SHIFT		8
#define CPHY_SATA_TX_ATTEN		0x1c00
#define CPHY_SATA_TX_ATTEN_SHIFT	10

#define HB_SREG_SATA_ATTEN		0xfff3cf24

#define SATA_PORT_BASE			0xffe08000
#define SATA_VERSIONR			0xf8
#define SATA_HB_VERSION			0x3332302a

static u32 __combo_phy_reg_read(u8 phy, u8 dev, u32 addr)
{
	u32 data;
	writel(CPHY_MAP(dev, addr), CPHY_BASE + 0x800 + CPHY_WIDTH * phy);
	data = readl(CPHY_ADDR(CPHY_BASE + CPHY_WIDTH * phy, dev, addr));
	return data;
}

static void __combo_phy_reg_write(u8 phy, u8 dev, u32 addr, u32 data)
{
	writel(CPHY_MAP(dev, addr), CPHY_BASE + 0x800 + CPHY_WIDTH * phy);
	writel(data, CPHY_ADDR(CPHY_BASE + CPHY_WIDTH * phy, dev, addr));
}

static u32 combo_phy_read(u8 phy, u32 addr)
{
	u8 dev = CPHY_DTE_XS;
	if (phy == 5)
		dev = CPHY_MII;
	while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY)
		udelay(5);
	__combo_phy_reg_write(phy, dev, SERDES_CR_ADDR, addr);
	__combo_phy_reg_write(phy, dev, SERDES_CR_CTL, CR_START);
	while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY)
		udelay(5);
	return __combo_phy_reg_read(phy, dev, SERDES_CR_DATA);
}

static void combo_phy_write(u8 phy, u32 addr, u32 data)
{
	u8 dev = CPHY_DTE_XS;
	if (phy == 5)
		dev = CPHY_MII;
	while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY)
		udelay(5);
	__combo_phy_reg_write(phy, dev, SERDES_CR_ADDR, addr);
	__combo_phy_reg_write(phy, dev, SERDES_CR_DATA, data);
	__combo_phy_reg_write(phy, dev, SERDES_CR_CTL, CR_WR_RDN | CR_START);
}

static void cphy_spread_spectrum_override(u8 phy, u8 lane, u32 val)
{
	u32 tmp;
	tmp = combo_phy_read(phy, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
	tmp &= ~CPHY_SATA_RX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);

	tmp |= CPHY_SATA_RX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);

	tmp &= ~CPHY_SATA_DPLL_MODE;
	tmp |= (val << CPHY_SATA_DPLL_SHIFT) & CPHY_SATA_DPLL_MODE;
	combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);
}

static void cphy_tx_attenuation_override(u8 phy, u8 lane)
{
	u32 val;
	u32 tmp;
	u8  shift;

	shift = ((phy == 5) ? 4 : lane) * 4;

	val = (readl(HB_SREG_SATA_ATTEN) >> shift) & 0xf;

	if (val & 0x8)
		return;

	tmp = combo_phy_read(phy, CPHY_TX_INPUT_STS + lane * SPHY_LANE);
	tmp &= ~CPHY_SATA_TX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);

	tmp |= CPHY_SATA_TX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);

	tmp |= (val << CPHY_SATA_TX_ATTEN_SHIFT) & CPHY_SATA_TX_ATTEN;
	combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);
}

static void cphy_disable_port_overrides(u8 port)
{
	u32 tmp;
	u8 lane = 0, phy = 0;

	if (port == 0)
		phy = 5;
	else if (port < 5)
		lane = port - 1;
	else
		return;
	tmp = combo_phy_read(phy, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
	tmp &= ~CPHY_SATA_RX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);

	tmp = combo_phy_read(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE);
	tmp &= ~CPHY_SATA_TX_OVERRIDE_BIT;
	combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp);
}

void cphy_disable_overrides(void)
{
	int i;
	u32 port_map;

	port_map = readl(0xffe08000 + HOST_PORTS_IMPL);
	for (i = 0; i < 5; i++) {
		if (port_map & (1 << i))
			cphy_disable_port_overrides(i);
	}
}

static void cphy_override_lane(u8 port)
{
	u32 tmp, k = 0;
	u8 lane = 0, phy = 0;

	if (port == 0)
		phy = 5;
	else if (port < 5)
		lane = port - 1;
	else
		return;

	do {
		tmp = combo_phy_read(0, CPHY_RX_INPUT_STS +
					lane * SPHY_LANE);
	} while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
	cphy_spread_spectrum_override(phy, lane, 3);
	cphy_tx_attenuation_override(phy, lane);
}

#define WAIT_MS_LINKUP	4

int ahci_link_up(struct ahci_probe_ent *probe_ent, int port)
{
	u32 tmp;
	int j = 0;
	u8 *port_mmio = (u8 *)probe_ent->port[port].port_mmio;
	u32 is_highbank = readl(SATA_PORT_BASE + SATA_VERSIONR) ==
				SATA_HB_VERSION ? 1 : 0;

	/* 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) {
		if (is_highbank && (j == 0)) {
			cphy_disable_port_overrides(port);
			writel(0x301, port_mmio + PORT_SCR_CTL);
			udelay(1000);
			writel(0x300, port_mmio + PORT_SCR_CTL);
			udelay(1000);
			cphy_override_lane(port);
		}

		tmp = readl(port_mmio + PORT_SCR_STAT);
		if ((tmp & 0xf) == 0x3)
			return 0;
		udelay(1000);
		j++;

		if ((j == WAIT_MS_LINKUP) && (tmp & 0xf))
			j = 0;	/* retry phy reset */
	}
	return 1;
}
