/*
 * Marvell 88SE94xx hardware specific
 *
 * Copyright 2007 Red Hat, Inc.
 * Copyright 2008 Marvell. <kewei@marvell.com>
 * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
 *
 * This file is licensed under GPLv2.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
*/

#include "mv_sas.h"
#include "mv_94xx.h"
#include "mv_chips.h"

static void mvs_94xx_detect_porttype(struct mvs_info *mvi, int i)
{
	u32 reg;
	struct mvs_phy *phy = &mvi->phy[i];
	u32 phy_status;

	mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE3);
	reg = mvs_read_port_vsr_data(mvi, i);
	phy_status = ((reg & 0x3f0000) >> 16) & 0xff;
	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
	switch (phy_status) {
	case 0x10:
		phy->phy_type |= PORT_TYPE_SAS;
		break;
	case 0x1d:
	default:
		phy->phy_type |= PORT_TYPE_SATA;
		break;
	}
}

static void set_phy_tuning(struct mvs_info *mvi, int phy_id,
			   struct phy_tuning phy_tuning)
{
	u32 tmp, setting_0 = 0, setting_1 = 0;
	u8 i;

	/* Remap information for B0 chip:
	*
	* R0Ch -> R118h[15:0] (Adapted DFE F3 - F5 coefficient)
	* R0Dh -> R118h[31:16] (Generation 1 Setting 0)
	* R0Eh -> R11Ch[15:0]  (Generation 1 Setting 1)
	* R0Fh -> R11Ch[31:16] (Generation 2 Setting 0)
	* R10h -> R120h[15:0]  (Generation 2 Setting 1)
	* R11h -> R120h[31:16] (Generation 3 Setting 0)
	* R12h -> R124h[15:0]  (Generation 3 Setting 1)
	* R13h -> R124h[31:16] (Generation 4 Setting 0 (Reserved))
	*/

	/* A0 has a different set of registers */
	if (mvi->pdev->revision == VANIR_A0_REV)
		return;

	for (i = 0; i < 3; i++) {
		/* loop 3 times, set Gen 1, Gen 2, Gen 3 */
		switch (i) {
		case 0:
			setting_0 = GENERATION_1_SETTING;
			setting_1 = GENERATION_1_2_SETTING;
			break;
		case 1:
			setting_0 = GENERATION_1_2_SETTING;
			setting_1 = GENERATION_2_3_SETTING;
			break;
		case 2:
			setting_0 = GENERATION_2_3_SETTING;
			setting_1 = GENERATION_3_4_SETTING;
			break;
		}

		/* Set:
		*
		* Transmitter Emphasis Enable
		* Transmitter Emphasis Amplitude
		* Transmitter Amplitude
		*/
		mvs_write_port_vsr_addr(mvi, phy_id, setting_0);
		tmp = mvs_read_port_vsr_data(mvi, phy_id);
		tmp &= ~(0xFBE << 16);
		tmp |= (((phy_tuning.trans_emp_en << 11) |
			(phy_tuning.trans_emp_amp << 7) |
			(phy_tuning.trans_amp << 1)) << 16);
		mvs_write_port_vsr_data(mvi, phy_id, tmp);

		/* Set Transmitter Amplitude Adjust */
		mvs_write_port_vsr_addr(mvi, phy_id, setting_1);
		tmp = mvs_read_port_vsr_data(mvi, phy_id);
		tmp &= ~(0xC000);
		tmp |= (phy_tuning.trans_amp_adj << 14);
		mvs_write_port_vsr_data(mvi, phy_id, tmp);
	}
}

static void set_phy_ffe_tuning(struct mvs_info *mvi, int phy_id,
			       struct ffe_control ffe)
{
	u32 tmp;

	/* Don't run this if A0/B0 */
	if ((mvi->pdev->revision == VANIR_A0_REV)
		|| (mvi->pdev->revision == VANIR_B0_REV))
		return;

	/* FFE Resistor and Capacitor */
	/* R10Ch DFE Resolution Control/Squelch and FFE Setting
	 *
	 * FFE_FORCE            [7]
	 * FFE_RES_SEL          [6:4]
	 * FFE_CAP_SEL          [3:0]
	 */
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_FFE_CONTROL);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	tmp &= ~0xFF;

	/* Read from HBA_Info_Page */
	tmp |= ((0x1 << 7) |
		(ffe.ffe_rss_sel << 4) |
		(ffe.ffe_cap_sel << 0));

	mvs_write_port_vsr_data(mvi, phy_id, tmp);

	/* R064h PHY Mode Register 1
	 *
	 * DFE_DIS		18
	 */
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	tmp &= ~0x40001;
	/* Hard coding */
	/* No defines in HBA_Info_Page */
	tmp |= (0 << 18);
	mvs_write_port_vsr_data(mvi, phy_id, tmp);

	/* R110h DFE F0-F1 Coefficient Control/DFE Update Control
	 *
	 * DFE_UPDATE_EN        [11:6]
	 * DFE_FX_FORCE         [5:0]
	 */
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_DFE_UPDATE_CRTL);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	tmp &= ~0xFFF;
	/* Hard coding */
	/* No defines in HBA_Info_Page */
	tmp |= ((0x3F << 6) | (0x0 << 0));
	mvs_write_port_vsr_data(mvi, phy_id, tmp);

	/* R1A0h Interface and Digital Reference Clock Control/Reserved_50h
	 *
	 * FFE_TRAIN_EN         3
	 */
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	tmp &= ~0x8;
	/* Hard coding */
	/* No defines in HBA_Info_Page */
	tmp |= (0 << 3);
	mvs_write_port_vsr_data(mvi, phy_id, tmp);
}

/*Notice: this function must be called when phy is disabled*/
static void set_phy_rate(struct mvs_info *mvi, int phy_id, u8 rate)
{
	union reg_phy_cfg phy_cfg, phy_cfg_tmp;
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
	phy_cfg_tmp.v = mvs_read_port_vsr_data(mvi, phy_id);
	phy_cfg.v = 0;
	phy_cfg.u.disable_phy = phy_cfg_tmp.u.disable_phy;
	phy_cfg.u.sas_support = 1;
	phy_cfg.u.sata_support = 1;
	phy_cfg.u.sata_host_mode = 1;

	switch (rate) {
	case 0x0:
		/* support 1.5 Gbps */
		phy_cfg.u.speed_support = 1;
		phy_cfg.u.snw_3_support = 0;
		phy_cfg.u.tx_lnk_parity = 1;
		phy_cfg.u.tx_spt_phs_lnk_rate = 0x30;
		break;
	case 0x1:

		/* support 1.5, 3.0 Gbps */
		phy_cfg.u.speed_support = 3;
		phy_cfg.u.tx_spt_phs_lnk_rate = 0x3c;
		phy_cfg.u.tx_lgcl_lnk_rate = 0x08;
		break;
	case 0x2:
	default:
		/* support 1.5, 3.0, 6.0 Gbps */
		phy_cfg.u.speed_support = 7;
		phy_cfg.u.snw_3_support = 1;
		phy_cfg.u.tx_lnk_parity = 1;
		phy_cfg.u.tx_spt_phs_lnk_rate = 0x3f;
		phy_cfg.u.tx_lgcl_lnk_rate = 0x09;
		break;
	}
	mvs_write_port_vsr_data(mvi, phy_id, phy_cfg.v);
}

static void mvs_94xx_config_reg_from_hba(struct mvs_info *mvi, int phy_id)
{
	u32 temp;
	temp = (u32)(*(u32 *)&mvi->hba_info_param.phy_tuning[phy_id]);
	if (temp == 0xFFFFFFFFL) {
		mvi->hba_info_param.phy_tuning[phy_id].trans_emp_amp = 0x6;
		mvi->hba_info_param.phy_tuning[phy_id].trans_amp = 0x1A;
		mvi->hba_info_param.phy_tuning[phy_id].trans_amp_adj = 0x3;
	}

	temp = (u8)(*(u8 *)&mvi->hba_info_param.ffe_ctl[phy_id]);
	if (temp == 0xFFL) {
		switch (mvi->pdev->revision) {
		case VANIR_A0_REV:
		case VANIR_B0_REV:
			mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
			mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0x7;
			break;
		case VANIR_C0_REV:
		case VANIR_C1_REV:
		case VANIR_C2_REV:
		default:
			mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
			mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0xC;
			break;
		}
	}

	temp = (u8)(*(u8 *)&mvi->hba_info_param.phy_rate[phy_id]);
	if (temp == 0xFFL)
		/*set default phy_rate = 6Gbps*/
		mvi->hba_info_param.phy_rate[phy_id] = 0x2;

	set_phy_tuning(mvi, phy_id,
		mvi->hba_info_param.phy_tuning[phy_id]);
	set_phy_ffe_tuning(mvi, phy_id,
		mvi->hba_info_param.ffe_ctl[phy_id]);
	set_phy_rate(mvi, phy_id,
		mvi->hba_info_param.phy_rate[phy_id]);
}

static void mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id)
{
	void __iomem *regs = mvi->regs;
	u32 tmp;

	tmp = mr32(MVS_PCS);
	tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2);
	mw32(MVS_PCS, tmp);
}

static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
{
	u32 tmp;
	u32 delay = 5000;
	if (hard == MVS_PHY_TUNE) {
		mvs_write_port_cfg_addr(mvi, phy_id, PHYR_SATA_CTL);
		tmp = mvs_read_port_cfg_data(mvi, phy_id);
		mvs_write_port_cfg_data(mvi, phy_id, tmp|0x20000000);
		mvs_write_port_cfg_data(mvi, phy_id, tmp|0x100000);
		return;
	}
	tmp = mvs_read_port_irq_stat(mvi, phy_id);
	tmp &= ~PHYEV_RDY_CH;
	mvs_write_port_irq_stat(mvi, phy_id, tmp);
	if (hard) {
		tmp = mvs_read_phy_ctl(mvi, phy_id);
		tmp |= PHY_RST_HARD;
		mvs_write_phy_ctl(mvi, phy_id, tmp);
		do {
			tmp = mvs_read_phy_ctl(mvi, phy_id);
			udelay(10);
			delay--;
		} while ((tmp & PHY_RST_HARD) && delay);
		if (!delay)
			mv_dprintk("phy hard reset failed.\n");
	} else {
		tmp = mvs_read_phy_ctl(mvi, phy_id);
		tmp |= PHY_RST;
		mvs_write_phy_ctl(mvi, phy_id, tmp);
	}
}

static void mvs_94xx_phy_disable(struct mvs_info *mvi, u32 phy_id)
{
	u32 tmp;
	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	mvs_write_port_vsr_data(mvi, phy_id, tmp | 0x00800000);
}

static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)
{
	u32 tmp;
	u8 revision = 0;

	revision = mvi->pdev->revision;
	if (revision == VANIR_A0_REV) {
		mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
		mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1);
	}
	if (revision == VANIR_B0_REV) {
		mvs_write_port_vsr_addr(mvi, phy_id, CMD_APP_MEM_CTL);
		mvs_write_port_vsr_data(mvi, phy_id, 0x08001006);
		mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
		mvs_write_port_vsr_data(mvi, phy_id, 0x0000705f);
	}

	mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
	tmp = mvs_read_port_vsr_data(mvi, phy_id);
	tmp |= bit(0);
	mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff);
}

static void mvs_94xx_sgpio_init(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	u32 tmp;

	tmp = mr32(MVS_HST_CHIP_CONFIG);
	tmp |= 0x100;
	mw32(MVS_HST_CHIP_CONFIG, tmp);

	mw32(MVS_SGPIO_CTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
		MVS_SGPIO_CTRL_SDOUT_AUTO << MVS_SGPIO_CTRL_SDOUT_SHIFT);

	mw32(MVS_SGPIO_CFG1 + MVS_SGPIO_HOST_OFFSET * mvi->id,
		8 << MVS_SGPIO_CFG1_LOWA_SHIFT |
		8 << MVS_SGPIO_CFG1_HIA_SHIFT |
		4 << MVS_SGPIO_CFG1_LOWB_SHIFT |
		4 << MVS_SGPIO_CFG1_HIB_SHIFT |
		2 << MVS_SGPIO_CFG1_MAXACTON_SHIFT |
		1 << MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT
	);

	mw32(MVS_SGPIO_CFG2 + MVS_SGPIO_HOST_OFFSET * mvi->id,
		(300000 / 100) << MVS_SGPIO_CFG2_CLK_SHIFT | /* 100kHz clock */
		66 << MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/
	);

	mw32(MVS_SGPIO_CFG0 + MVS_SGPIO_HOST_OFFSET * mvi->id,
		MVS_SGPIO_CFG0_ENABLE |
		MVS_SGPIO_CFG0_BLINKA |
		MVS_SGPIO_CFG0_BLINKB |
		/* 3*4 data bits / PDU */
		(12 - 1) << MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT
	);

	mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
		DEFAULT_SGPIO_BITS);

	mw32(MVS_SGPIO_DSRC + MVS_SGPIO_HOST_OFFSET * mvi->id,
		((mvi->id * 4) + 3) << (8 * 3) |
		((mvi->id * 4) + 2) << (8 * 2) |
		((mvi->id * 4) + 1) << (8 * 1) |
		((mvi->id * 4) + 0) << (8 * 0));

}

static int mvs_94xx_init(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs;
	int i;
	u32 tmp, cctl;
	u8 revision;

	revision = mvi->pdev->revision;
	mvs_show_pcie_usage(mvi);
	if (mvi->flags & MVF_FLAG_SOC) {
		tmp = mr32(MVS_PHY_CTL);
		tmp &= ~PCTL_PWR_OFF;
		tmp |= PCTL_PHY_DSBL;
		mw32(MVS_PHY_CTL, tmp);
	}

	/* Init Chip */
	/* make sure RST is set; HBA_RST /should/ have done that for us */
	cctl = mr32(MVS_CTL) & 0xFFFF;
	if (cctl & CCTL_RST)
		cctl &= ~CCTL_RST;
	else
		mw32_f(MVS_CTL, cctl | CCTL_RST);

	if (mvi->flags & MVF_FLAG_SOC) {
		tmp = mr32(MVS_PHY_CTL);
		tmp &= ~PCTL_PWR_OFF;
		tmp |= PCTL_COM_ON;
		tmp &= ~PCTL_PHY_DSBL;
		tmp |= PCTL_LINK_RST;
		mw32(MVS_PHY_CTL, tmp);
		msleep(100);
		tmp &= ~PCTL_LINK_RST;
		mw32(MVS_PHY_CTL, tmp);
		msleep(100);
	}

	/* disable Multiplexing, enable phy implemented */
	mw32(MVS_PORTS_IMP, 0xFF);

	if (revision == VANIR_A0_REV) {
		mw32(MVS_PA_VSR_ADDR, CMD_CMWK_OOB_DET);
		mw32(MVS_PA_VSR_PORT, 0x00018080);
	}
	mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE2);
	if (revision == VANIR_A0_REV || revision == VANIR_B0_REV)
		/* set 6G/3G/1.5G, multiplexing, without SSC */
		mw32(MVS_PA_VSR_PORT, 0x0084d4fe);
	else
		/* set 6G/3G/1.5G, multiplexing, with and without SSC */
		mw32(MVS_PA_VSR_PORT, 0x0084fffe);

	if (revision == VANIR_B0_REV) {
		mw32(MVS_PA_VSR_ADDR, CMD_APP_MEM_CTL);
		mw32(MVS_PA_VSR_PORT, 0x08001006);
		mw32(MVS_PA_VSR_ADDR, CMD_HOST_RD_DATA);
		mw32(MVS_PA_VSR_PORT, 0x0000705f);
	}

	/* reset control */
	mw32(MVS_PCS, 0);		/* MVS_PCS */
	mw32(MVS_STP_REG_SET_0, 0);
	mw32(MVS_STP_REG_SET_1, 0);

	/* init phys */
	mvs_phy_hacks(mvi);

	/* disable non data frame retry */
	tmp = mvs_cr32(mvi, CMD_SAS_CTL1);
	if ((revision == VANIR_A0_REV) ||
		(revision == VANIR_B0_REV) ||
		(revision == VANIR_C0_REV)) {
		tmp &= ~0xffff;
		tmp |= 0x007f;
		mvs_cw32(mvi, CMD_SAS_CTL1, tmp);
	}

	/* set LED blink when IO*/
	mw32(MVS_PA_VSR_ADDR, VSR_PHY_ACT_LED);
	tmp = mr32(MVS_PA_VSR_PORT);
	tmp &= 0xFFFF00FF;
	tmp |= 0x00003300;
	mw32(MVS_PA_VSR_PORT, tmp);

	mw32(MVS_CMD_LIST_LO, mvi->slot_dma);
	mw32(MVS_CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);

	mw32(MVS_RX_FIS_LO, mvi->rx_fis_dma);
	mw32(MVS_RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);

	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ);
	mw32(MVS_TX_LO, mvi->tx_dma);
	mw32(MVS_TX_HI, (mvi->tx_dma >> 16) >> 16);

	mw32(MVS_RX_CFG, MVS_RX_RING_SZ);
	mw32(MVS_RX_LO, mvi->rx_dma);
	mw32(MVS_RX_HI, (mvi->rx_dma >> 16) >> 16);

	for (i = 0; i < mvi->chip->n_phy; i++) {
		mvs_94xx_phy_disable(mvi, i);
		/* set phy local SAS address */
		mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4,
						cpu_to_le64(mvi->phy[i].dev_sas_addr));

		mvs_94xx_enable_xmt(mvi, i);
		mvs_94xx_config_reg_from_hba(mvi, i);
		mvs_94xx_phy_enable(mvi, i);

		mvs_94xx_phy_reset(mvi, i, PHY_RST_HARD);
		msleep(500);
		mvs_94xx_detect_porttype(mvi, i);
	}

	if (mvi->flags & MVF_FLAG_SOC) {
		/* set select registers */
		writel(0x0E008000, regs + 0x000);
		writel(0x59000008, regs + 0x004);
		writel(0x20, regs + 0x008);
		writel(0x20, regs + 0x00c);
		writel(0x20, regs + 0x010);
		writel(0x20, regs + 0x014);
		writel(0x20, regs + 0x018);
		writel(0x20, regs + 0x01c);
	}
	for (i = 0; i < mvi->chip->n_phy; i++) {
		/* clear phy int status */
		tmp = mvs_read_port_irq_stat(mvi, i);
		tmp &= ~PHYEV_SIG_FIS;
		mvs_write_port_irq_stat(mvi, i, tmp);

		/* set phy int mask */
		tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH |
			PHYEV_ID_DONE  | PHYEV_DCDR_ERR | PHYEV_CRC_ERR ;
		mvs_write_port_irq_mask(mvi, i, tmp);

		msleep(100);
		mvs_update_phyinfo(mvi, i, 1);
	}

	/* little endian for open address and command table, etc. */
	cctl = mr32(MVS_CTL);
	cctl |= CCTL_ENDIAN_CMD;
	cctl &= ~CCTL_ENDIAN_OPEN;
	cctl |= CCTL_ENDIAN_RSP;
	mw32_f(MVS_CTL, cctl);

	/* reset CMD queue */
	tmp = mr32(MVS_PCS);
	tmp |= PCS_CMD_RST;
	tmp &= ~PCS_SELF_CLEAR;
	mw32(MVS_PCS, tmp);
	/*
	 * the max count is 0x1ff, while our max slot is 0x200,
	 * it will make count 0.
	 */
	tmp = 0;
	if (MVS_CHIP_SLOT_SZ > 0x1ff)
		mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
	else
		mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);

	/* default interrupt coalescing time is 128us */
	tmp = 0x10000 | interrupt_coalescing;
	mw32(MVS_INT_COAL_TMOUT, tmp);

	/* ladies and gentlemen, start your engines */
	mw32(MVS_TX_CFG, 0);
	mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);
	mw32(MVS_RX_CFG, MVS_RX_RING_SZ | RX_EN);
	/* enable CMD/CMPL_Q/RESP mode */
	mw32(MVS_PCS, PCS_SATA_RETRY_2 | PCS_FIS_RX_EN |
		PCS_CMD_EN | PCS_CMD_STOP_ERR);

	/* enable completion queue interrupt */
	tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
		CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR);
	tmp |= CINT_PHY_MASK;
	mw32(MVS_INT_MASK, tmp);

	tmp = mvs_cr32(mvi, CMD_LINK_TIMER);
	tmp |= 0xFFFF0000;
	mvs_cw32(mvi, CMD_LINK_TIMER, tmp);

	/* tune STP performance */
	tmp = 0x003F003F;
	mvs_cw32(mvi, CMD_PL_TIMER, tmp);

	/* This can improve expander large block size seq write performance */
	tmp = mvs_cr32(mvi, CMD_PORT_LAYER_TIMER1);
	tmp |= 0xFFFF007F;
	mvs_cw32(mvi, CMD_PORT_LAYER_TIMER1, tmp);

	/* change the connection open-close behavior (bit 9)
	 * set bit8 to 1 for performance tuning */
	tmp = mvs_cr32(mvi, CMD_SL_MODE0);
	tmp |= 0x00000300;
	/* set bit0 to 0 to enable retry for no_dest reject case */
	tmp &= 0xFFFFFFFE;
	mvs_cw32(mvi, CMD_SL_MODE0, tmp);

	/* Enable SRS interrupt */
	mw32(MVS_INT_MASK_SRS_0, 0xFFFF);

	mvs_94xx_sgpio_init(mvi);

	return 0;
}

static int mvs_94xx_ioremap(struct mvs_info *mvi)
{
	if (!mvs_ioremap(mvi, 2, -1)) {
		mvi->regs_ex = mvi->regs + 0x10200;
		mvi->regs += 0x20000;
		if (mvi->id == 1)
			mvi->regs += 0x4000;
		return 0;
	}
	return -1;
}

static void mvs_94xx_iounmap(struct mvs_info *mvi)
{
	if (mvi->regs) {
		mvi->regs -= 0x20000;
		if (mvi->id == 1)
			mvi->regs -= 0x4000;
		mvs_iounmap(mvi->regs);
	}
}

static void mvs_94xx_interrupt_enable(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs_ex;
	u32 tmp;

	tmp = mr32(MVS_GBL_CTL);
	tmp |= (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
	mw32(MVS_GBL_INT_STAT, tmp);
	writel(tmp, regs + 0x0C);
	writel(tmp, regs + 0x10);
	writel(tmp, regs + 0x14);
	writel(tmp, regs + 0x18);
	mw32(MVS_GBL_CTL, tmp);
}

static void mvs_94xx_interrupt_disable(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs_ex;
	u32 tmp;

	tmp = mr32(MVS_GBL_CTL);

	tmp &= ~(MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
	mw32(MVS_GBL_INT_STAT, tmp);
	writel(tmp, regs + 0x0C);
	writel(tmp, regs + 0x10);
	writel(tmp, regs + 0x14);
	writel(tmp, regs + 0x18);
	mw32(MVS_GBL_CTL, tmp);
}

static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq)
{
	void __iomem *regs = mvi->regs_ex;
	u32 stat = 0;
	if (!(mvi->flags & MVF_FLAG_SOC)) {
		stat = mr32(MVS_GBL_INT_STAT);

		if (!(stat & (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B)))
			return 0;
	}
	return stat;
}

static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
{
	void __iomem *regs = mvi->regs;

	if (((stat & MVS_IRQ_SAS_A) && mvi->id == 0) ||
			((stat & MVS_IRQ_SAS_B) && mvi->id == 1)) {
		mw32_f(MVS_INT_STAT, CINT_DONE);

		spin_lock(&mvi->lock);
		mvs_int_full(mvi);
		spin_unlock(&mvi->lock);
	}
	return IRQ_HANDLED;
}

static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx)
{
	u32 tmp;
	tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3));
	if (tmp & 1 << (slot_idx % 32)) {
		mv_printk("command active %08X,  slot [%x].\n", tmp, slot_idx);
		mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3),
			1 << (slot_idx % 32));
		do {
			tmp = mvs_cr32(mvi,
				MVS_COMMAND_ACTIVE + (slot_idx >> 3));
		} while (tmp & 1 << (slot_idx % 32));
	}
}

static void
mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)
{
	void __iomem *regs = mvi->regs;
	u32 tmp;

	if (clear_all) {
		tmp = mr32(MVS_INT_STAT_SRS_0);
		if (tmp) {
			mv_dprintk("check SRS 0 %08X.\n", tmp);
			mw32(MVS_INT_STAT_SRS_0, tmp);
		}
		tmp = mr32(MVS_INT_STAT_SRS_1);
		if (tmp) {
			mv_dprintk("check SRS 1 %08X.\n", tmp);
			mw32(MVS_INT_STAT_SRS_1, tmp);
		}
	} else {
		if (reg_set > 31)
			tmp = mr32(MVS_INT_STAT_SRS_1);
		else
			tmp = mr32(MVS_INT_STAT_SRS_0);

		if (tmp & (1 << (reg_set % 32))) {
			mv_dprintk("register set 0x%x was stopped.\n", reg_set);
			if (reg_set > 31)
				mw32(MVS_INT_STAT_SRS_1, 1 << (reg_set % 32));
			else
				mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));
		}
	}
}

static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
				u32 tfs)
{
	void __iomem *regs = mvi->regs;
	u32 tmp;
	mvs_94xx_clear_srs_irq(mvi, 0, 1);

	tmp = mr32(MVS_INT_STAT);
	mw32(MVS_INT_STAT, tmp | CINT_CI_STOP);
	tmp = mr32(MVS_PCS) | 0xFF00;
	mw32(MVS_PCS, tmp);
}

static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs;
	u32 err_0, err_1;
	u8 i;
	struct mvs_device *device;

	err_0 = mr32(MVS_NON_NCQ_ERR_0);
	err_1 = mr32(MVS_NON_NCQ_ERR_1);

	mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n",
			err_0, err_1);
	for (i = 0; i < 32; i++) {
		if (err_0 & bit(i)) {
			device = mvs_find_dev_by_reg_set(mvi, i);
			if (device)
				mvs_release_task(mvi, device->sas_device);
		}
		if (err_1 & bit(i)) {
			device = mvs_find_dev_by_reg_set(mvi, i+32);
			if (device)
				mvs_release_task(mvi, device->sas_device);
		}
	}

	mw32(MVS_NON_NCQ_ERR_0, err_0);
	mw32(MVS_NON_NCQ_ERR_1, err_1);
}

static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
{
	void __iomem *regs = mvi->regs;
	u8 reg_set = *tfs;

	if (*tfs == MVS_ID_NOT_MAPPED)
		return;

	mvi->sata_reg_set &= ~bit(reg_set);
	if (reg_set < 32)
		w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set);
	else
		w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32));

	*tfs = MVS_ID_NOT_MAPPED;

	return;
}

static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)
{
	int i;
	void __iomem *regs = mvi->regs;

	if (*tfs != MVS_ID_NOT_MAPPED)
		return 0;

	i = mv_ffc64(mvi->sata_reg_set);
	if (i >= 32) {
		mvi->sata_reg_set |= bit(i);
		w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32));
		*tfs = i;
		return 0;
	} else if (i >= 0) {
		mvi->sata_reg_set |= bit(i);
		w_reg_set_enable(i, (u32)mvi->sata_reg_set);
		*tfs = i;
		return 0;
	}
	return MVS_ID_NOT_MAPPED;
}

static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd)
{
	int i;
	struct scatterlist *sg;
	struct mvs_prd *buf_prd = prd;
	struct mvs_prd_imt im_len;
	*(u32 *)&im_len = 0;
	for_each_sg(scatter, sg, nr, i) {
		buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
		im_len.len = sg_dma_len(sg);
		buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
		buf_prd++;
	}
}

static int mvs_94xx_oob_done(struct mvs_info *mvi, int i)
{
	u32 phy_st;
	phy_st = mvs_read_phy_ctl(mvi, i);
	if (phy_st & PHY_READY_MASK)
		return 1;
	return 0;
}

static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id,
					struct sas_identify_frame *id)
{
	int i;
	u32 id_frame[7];

	for (i = 0; i < 7; i++) {
		mvs_write_port_cfg_addr(mvi, port_id,
					CONFIG_ID_FRAME0 + i * 4);
		id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
	}
	memcpy(id, id_frame, 28);
}

static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id,
					struct sas_identify_frame *id)
{
	int i;
	u32 id_frame[7];

	for (i = 0; i < 7; i++) {
		mvs_write_port_cfg_addr(mvi, port_id,
					CONFIG_ATT_ID_FRAME0 + i * 4);
		id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
		mv_dprintk("94xx phy %d atta frame %d %x.\n",
			port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]);
	}
	memcpy(id, id_frame, 28);
}

static u32 mvs_94xx_make_dev_info(struct sas_identify_frame *id)
{
	u32 att_dev_info = 0;

	att_dev_info |= id->dev_type;
	if (id->stp_iport)
		att_dev_info |= PORT_DEV_STP_INIT;
	if (id->smp_iport)
		att_dev_info |= PORT_DEV_SMP_INIT;
	if (id->ssp_iport)
		att_dev_info |= PORT_DEV_SSP_INIT;
	if (id->stp_tport)
		att_dev_info |= PORT_DEV_STP_TRGT;
	if (id->smp_tport)
		att_dev_info |= PORT_DEV_SMP_TRGT;
	if (id->ssp_tport)
		att_dev_info |= PORT_DEV_SSP_TRGT;

	att_dev_info |= (u32)id->phy_id<<24;
	return att_dev_info;
}

static u32 mvs_94xx_make_att_info(struct sas_identify_frame *id)
{
	return mvs_94xx_make_dev_info(id);
}

static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i,
				struct sas_identify_frame *id)
{
	struct mvs_phy *phy = &mvi->phy[i];
	struct asd_sas_phy *sas_phy = &phy->sas_phy;
	mv_dprintk("get all reg link rate is 0x%x\n", phy->phy_status);
	sas_phy->linkrate =
		(phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
			PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
	sas_phy->linkrate += 0x8;
	mv_dprintk("get link rate is %d\n", sas_phy->linkrate);
	phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
	phy->maximum_linkrate = SAS_LINK_RATE_6_0_GBPS;
	mvs_94xx_get_dev_identify_frame(mvi, i, id);
	phy->dev_info = mvs_94xx_make_dev_info(id);

	if (phy->phy_type & PORT_TYPE_SAS) {
		mvs_94xx_get_att_identify_frame(mvi, i, id);
		phy->att_dev_info = mvs_94xx_make_att_info(id);
		phy->att_dev_sas_addr = *(u64 *)id->sas_addr;
	} else {
		phy->att_dev_info = PORT_DEV_STP_TRGT | 1;
	}

	/* enable spin up bit */
	mvs_write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
	mvs_write_port_cfg_data(mvi, i, 0x04);

}

static void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id,
				       struct sas_phy_linkrates *rates)
{
	u32 lrmax = 0;
	u32 tmp;

	tmp = mvs_read_phy_ctl(mvi, phy_id);
	lrmax = (rates->maximum_linkrate - SAS_LINK_RATE_1_5_GBPS) << 12;

	if (lrmax) {
		tmp &= ~(0x3 << 12);
		tmp |= lrmax;
	}
	mvs_write_phy_ctl(mvi, phy_id, tmp);
	mvs_94xx_phy_reset(mvi, phy_id, PHY_RST_HARD);
}

static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi)
{
	u32 tmp;
	void __iomem *regs = mvi->regs;
	tmp = mr32(MVS_STP_REG_SET_0);
	mw32(MVS_STP_REG_SET_0, 0);
	mw32(MVS_STP_REG_SET_0, tmp);
	tmp = mr32(MVS_STP_REG_SET_1);
	mw32(MVS_STP_REG_SET_1, 0);
	mw32(MVS_STP_REG_SET_1, tmp);
}


static u32 mvs_94xx_spi_read_data(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	return mr32(SPI_RD_DATA_REG_94XX);
}

static void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	 mw32(SPI_RD_DATA_REG_94XX, data);
}


static int mvs_94xx_spi_buildcmd(struct mvs_info *mvi,
				 u32      *dwCmd,
				 u8       cmd,
				 u8       read,
				 u8       length,
				 u32      addr
				)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	u32  dwTmp;

	dwTmp = ((u32)cmd << 8) | ((u32)length << 4);
	if (read)
		dwTmp |= SPI_CTRL_READ_94XX;

	if (addr != MV_MAX_U32) {
		mw32(SPI_ADDR_REG_94XX, (addr & 0x0003FFFFL));
		dwTmp |= SPI_ADDR_VLD_94XX;
	}

	*dwCmd = dwTmp;
	return 0;
}


static int mvs_94xx_spi_issuecmd(struct mvs_info *mvi, u32 cmd)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	mw32(SPI_CTRL_REG_94XX, cmd | SPI_CTRL_SpiStart_94XX);

	return 0;
}

static int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout)
{
	void __iomem *regs = mvi->regs_ex - 0x10200;
	u32   i, dwTmp;

	for (i = 0; i < timeout; i++) {
		dwTmp = mr32(SPI_CTRL_REG_94XX);
		if (!(dwTmp & SPI_CTRL_SpiStart_94XX))
			return 0;
		msleep(10);
	}

	return -1;
}

static void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,
			     int buf_len, int from, void *prd)
{
	int i;
	struct mvs_prd *buf_prd = prd;
	dma_addr_t buf_dma;
	struct mvs_prd_imt im_len;

	*(u32 *)&im_len = 0;
	buf_prd += from;

#define PRD_CHAINED_ENTRY 0x01
	if ((mvi->pdev->revision == VANIR_A0_REV) ||
			(mvi->pdev->revision == VANIR_B0_REV))
		buf_dma = (phy_mask <= 0x08) ?
				mvi->bulk_buffer_dma : mvi->bulk_buffer_dma1;
	else
		return;

	for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) {
		if (i == MAX_SG_ENTRY - 1) {
			buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1));
			im_len.len = 2;
			im_len.misc_ctl = PRD_CHAINED_ENTRY;
		} else {
			buf_prd->addr = cpu_to_le64(buf_dma);
			im_len.len = buf_len;
		}
		buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
	}
}

static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time)
{
	void __iomem *regs = mvi->regs;
	u32 tmp = 0;
	/*
	 * the max count is 0x1ff, while our max slot is 0x200,
	 * it will make count 0.
	 */
	if (time == 0) {
		mw32(MVS_INT_COAL, 0);
		mw32(MVS_INT_COAL_TMOUT, 0x10000);
	} else {
		if (MVS_CHIP_SLOT_SZ > 0x1ff)
			mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
		else
			mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);

		tmp = 0x10000 | time;
		mw32(MVS_INT_COAL_TMOUT, tmp);
	}

}

static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
			u8 reg_type, u8 reg_index,
			u8 reg_count, u8 *write_data)
{
	int i;

	switch (reg_type) {

	case SAS_GPIO_REG_TX_GP:
		if (reg_index == 0)
			return -EINVAL;

		if (reg_count > 1)
			return -EINVAL;

		if (reg_count == 0)
			return 0;

		/* maximum supported bits = hosts * 4 drives * 3 bits */
		for (i = 0; i < mvs_prv->n_host * 4 * 3; i++) {

			/* select host */
			struct mvs_info *mvi = mvs_prv->mvi[i/(4*3)];

			void __iomem *regs = mvi->regs_ex - 0x10200;

			int drive = (i/3) & (4-1); /* drive number on host */
			int driveshift = drive * 8; /* bit offset of drive */
			u32 block = ioread32be(regs + MVS_SGPIO_DCTRL +
				MVS_SGPIO_HOST_OFFSET * mvi->id);

			/*
			* if bit is set then create a mask with the first
			* bit of the drive set in the mask ...
			*/
			u32 bit = get_unaligned_be32(write_data) & (1 << i) ?
				1 << driveshift : 0;

			/*
			* ... and then shift it to the right position based
			* on the led type (activity/id/fail)
			*/
			switch (i%3) {
			case 0: /* activity */
				block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT)
					<< driveshift);
					/* hardwire activity bit to SOF */
				block |= LED_BLINKA_SOF << (
					MVS_SGPIO_DCTRL_ACT_SHIFT +
					driveshift);
				break;
			case 1: /* id */
				block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT)
					<< driveshift);
				block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT;
				break;
			case 2: /* fail */
				block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT)
					<< driveshift);
				block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT;
				break;
			}

			iowrite32be(block,
				regs + MVS_SGPIO_DCTRL +
				MVS_SGPIO_HOST_OFFSET * mvi->id);

		}

		return reg_count;

	case SAS_GPIO_REG_TX:
		if (reg_index + reg_count > mvs_prv->n_host)
			return -EINVAL;

		for (i = 0; i < reg_count; i++) {
			struct mvs_info *mvi = mvs_prv->mvi[i+reg_index];
			void __iomem *regs = mvi->regs_ex - 0x10200;

			mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
				((u32 *) write_data)[i]);
		}
		return reg_count;
	}
	return -ENOSYS;
}

const struct mvs_dispatch mvs_94xx_dispatch = {
	"mv94xx",
	mvs_94xx_init,
	NULL,
	mvs_94xx_ioremap,
	mvs_94xx_iounmap,
	mvs_94xx_isr,
	mvs_94xx_isr_status,
	mvs_94xx_interrupt_enable,
	mvs_94xx_interrupt_disable,
	mvs_read_phy_ctl,
	mvs_write_phy_ctl,
	mvs_read_port_cfg_data,
	mvs_write_port_cfg_data,
	mvs_write_port_cfg_addr,
	mvs_read_port_vsr_data,
	mvs_write_port_vsr_data,
	mvs_write_port_vsr_addr,
	mvs_read_port_irq_stat,
	mvs_write_port_irq_stat,
	mvs_read_port_irq_mask,
	mvs_write_port_irq_mask,
	mvs_94xx_command_active,
	mvs_94xx_clear_srs_irq,
	mvs_94xx_issue_stop,
	mvs_start_delivery,
	mvs_rx_update,
	mvs_int_full,
	mvs_94xx_assign_reg_set,
	mvs_94xx_free_reg_set,
	mvs_get_prd_size,
	mvs_get_prd_count,
	mvs_94xx_make_prd,
	mvs_94xx_detect_porttype,
	mvs_94xx_oob_done,
	mvs_94xx_fix_phy_info,
	NULL,
	mvs_94xx_phy_set_link_rate,
	mvs_hw_max_link_rate,
	mvs_94xx_phy_disable,
	mvs_94xx_phy_enable,
	mvs_94xx_phy_reset,
	NULL,
	mvs_94xx_clear_active_cmds,
	mvs_94xx_spi_read_data,
	mvs_94xx_spi_write_data,
	mvs_94xx_spi_buildcmd,
	mvs_94xx_spi_issuecmd,
	mvs_94xx_spi_waitdataready,
	mvs_94xx_fix_dma,
	mvs_94xx_tune_interrupt,
	mvs_94xx_non_spec_ncq_error,
	mvs_94xx_gpio_write,
};

