/*
 * Marvell 88SE64xx/88SE94xx register IO interface
 *
 * 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
*/


#ifndef _MV_CHIPS_H_
#define _MV_CHIPS_H_

#define mr32(reg)	readl(regs + reg)
#define mw32(reg, val)	writel((val), regs + reg)
#define mw32_f(reg, val)	do {			\
				mw32(reg, val);	\
				mr32(reg);	\
			} while (0)

#define iow32(reg, val) 	outl(val, (unsigned long)(regs + reg))
#define ior32(reg) 		inl((unsigned long)(regs + reg))
#define iow16(reg, val) 	outw((unsigned long)(val, regs + reg))
#define ior16(reg) 		inw((unsigned long)(regs + reg))
#define iow8(reg, val) 		outb((unsigned long)(val, regs + reg))
#define ior8(reg) 		inb((unsigned long)(regs + reg))

static inline u32 mvs_cr32(struct mvs_info *mvi, u32 addr)
{
	void __iomem *regs = mvi->regs;
	mw32(MVS_CMD_ADDR, addr);
	return mr32(MVS_CMD_DATA);
}

static inline void mvs_cw32(struct mvs_info *mvi, u32 addr, u32 val)
{
	void __iomem *regs = mvi->regs;
	mw32(MVS_CMD_ADDR, addr);
	mw32(MVS_CMD_DATA, val);
}

static inline u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port)
{
	void __iomem *regs = mvi->regs;
	return (port < 4) ? mr32(MVS_P0_SER_CTLSTAT + port * 4) :
		mr32(MVS_P4_SER_CTLSTAT + (port - 4) * 4);
}

static inline void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val)
{
	void __iomem *regs = mvi->regs;
	if (port < 4)
		mw32(MVS_P0_SER_CTLSTAT + port * 4, val);
	else
		mw32(MVS_P4_SER_CTLSTAT + (port - 4) * 4, val);
}

static inline u32 mvs_read_port(struct mvs_info *mvi, u32 off,
				u32 off2, u32 port)
{
	void __iomem *regs = mvi->regs + off;
	void __iomem *regs2 = mvi->regs + off2;
	return (port < 4) ? readl(regs + port * 8) :
		readl(regs2 + (port - 4) * 8);
}

static inline void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2,
				u32 port, u32 val)
{
	void __iomem *regs = mvi->regs + off;
	void __iomem *regs2 = mvi->regs + off2;
	if (port < 4)
		writel(val, regs + port * 8);
	else
		writel(val, regs2 + (port - 4) * 8);
}

static inline u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port)
{
	return mvs_read_port(mvi, MVS_P0_CFG_DATA,
			MVS_P4_CFG_DATA, port);
}

static inline void mvs_write_port_cfg_data(struct mvs_info *mvi,
						u32 port, u32 val)
{
	mvs_write_port(mvi, MVS_P0_CFG_DATA,
			MVS_P4_CFG_DATA, port, val);
}

static inline void mvs_write_port_cfg_addr(struct mvs_info *mvi,
						u32 port, u32 addr)
{
	mvs_write_port(mvi, MVS_P0_CFG_ADDR,
			MVS_P4_CFG_ADDR, port, addr);
	mdelay(10);
}

static inline u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port)
{
	return mvs_read_port(mvi, MVS_P0_VSR_DATA,
			MVS_P4_VSR_DATA, port);
}

static inline void mvs_write_port_vsr_data(struct mvs_info *mvi,
						u32 port, u32 val)
{
	mvs_write_port(mvi, MVS_P0_VSR_DATA,
			MVS_P4_VSR_DATA, port, val);
}

static inline void mvs_write_port_vsr_addr(struct mvs_info *mvi,
						u32 port, u32 addr)
{
	mvs_write_port(mvi, MVS_P0_VSR_ADDR,
			MVS_P4_VSR_ADDR, port, addr);
	mdelay(10);
}

static inline u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port)
{
	return mvs_read_port(mvi, MVS_P0_INT_STAT,
			MVS_P4_INT_STAT, port);
}

static inline void mvs_write_port_irq_stat(struct mvs_info *mvi,
						u32 port, u32 val)
{
	mvs_write_port(mvi, MVS_P0_INT_STAT,
			MVS_P4_INT_STAT, port, val);
}

static inline u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port)
{
	return mvs_read_port(mvi, MVS_P0_INT_MASK,
			MVS_P4_INT_MASK, port);

}

static inline void mvs_write_port_irq_mask(struct mvs_info *mvi,
						u32 port, u32 val)
{
	mvs_write_port(mvi, MVS_P0_INT_MASK,
			MVS_P4_INT_MASK, port, val);
}

static inline void __devinit mvs_phy_hacks(struct mvs_info *mvi)
{
	u32 tmp;

	/* workaround for SATA R-ERR, to ignore phy glitch */
	tmp = mvs_cr32(mvi, CMD_PHY_TIMER);
	tmp &= ~(1 << 9);
	tmp |= (1 << 10);
	mvs_cw32(mvi, CMD_PHY_TIMER, tmp);

	/* enable retry 127 times */
	mvs_cw32(mvi, CMD_SAS_CTL1, 0x7f7f);

	/* extend open frame timeout to max */
	tmp = mvs_cr32(mvi, CMD_SAS_CTL0);
	tmp &= ~0xffff;
	tmp |= 0x3fff;
	mvs_cw32(mvi, CMD_SAS_CTL0, tmp);

	/* workaround for WDTIMEOUT , set to 550 ms */
	mvs_cw32(mvi, CMD_WD_TIMER, 0x7a0000);

	/* not to halt for different port op during wideport link change */
	mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d);

	/* workaround for Seagate disk not-found OOB sequence, recv
	 * COMINIT before sending out COMWAKE */
	tmp = mvs_cr32(mvi, CMD_PHY_MODE_21);
	tmp &= 0x0000ffff;
	tmp |= 0x00fa0000;
	mvs_cw32(mvi, CMD_PHY_MODE_21, tmp);

	tmp = mvs_cr32(mvi, CMD_PHY_TIMER);
	tmp &= 0x1fffffff;
	tmp |= (2U << 29);	/* 8 ms retry */
	mvs_cw32(mvi, CMD_PHY_TIMER, tmp);
}

static inline void mvs_int_sata(struct mvs_info *mvi)
{
	u32 tmp;
	void __iomem *regs = mvi->regs;
	tmp = mr32(MVS_INT_STAT_SRS_0);
	if (tmp)
		mw32(MVS_INT_STAT_SRS_0, tmp);
	MVS_CHIP_DISP->clear_active_cmds(mvi);
}

static inline void mvs_int_full(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs;
	u32 tmp, stat;
	int i;

	stat = mr32(MVS_INT_STAT);
	mvs_int_rx(mvi, false);

	for (i = 0; i < mvi->chip->n_phy; i++) {
		tmp = (stat >> i) & (CINT_PORT | CINT_PORT_STOPPED);
		if (tmp)
			mvs_int_port(mvi, i, tmp);
	}

	if (stat & CINT_SRS)
		mvs_int_sata(mvi);

	mw32(MVS_INT_STAT, stat);
}

static inline void mvs_start_delivery(struct mvs_info *mvi, u32 tx)
{
	void __iomem *regs = mvi->regs;
	mw32(MVS_TX_PROD_IDX, tx);
}

static inline u32 mvs_rx_update(struct mvs_info *mvi)
{
	void __iomem *regs = mvi->regs;
	return mr32(MVS_RX_CONS_IDX);
}

static inline u32 mvs_get_prd_size(void)
{
	return sizeof(struct mvs_prd);
}

static inline u32 mvs_get_prd_count(void)
{
	return MAX_SG_ENTRY;
}

static inline void mvs_show_pcie_usage(struct mvs_info *mvi)
{
	u16 link_stat, link_spd;
	const char *spd[] = {
		"UnKnown",
		"2.5",
		"5.0",
	};
	if (mvi->flags & MVF_FLAG_SOC || mvi->id > 0)
		return;

	pci_read_config_word(mvi->pdev, PCR_LINK_STAT, &link_stat);
	link_spd = (link_stat & PLS_LINK_SPD) >> PLS_LINK_SPD_OFFS;
	if (link_spd >= 3)
		link_spd = 0;
	dev_printk(KERN_INFO, mvi->dev,
		"mvsas: PCI-E x%u, Bandwidth Usage: %s Gbps\n",
	       (link_stat & PLS_NEG_LINK_WD) >> PLS_NEG_LINK_WD_OFFS,
	       spd[link_spd]);
}

static inline u32 mvs_hw_max_link_rate(void)
{
	return MAX_LINK_RATE;
}

#endif  /* _MV_CHIPS_H_ */

