/*
 * 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;

	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);

	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);
}

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_NON_SPEC_NCQ_ERROR)
		MVS_CHIP_DISP->non_spec_ncq_error(mvi);

	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_ */

