/*
* sata_mv.c - Marvell SATA support
*
* Copyright 2008-2009: Marvell Corporation, all rights reserved.
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005 Red Hat, Inc. All rights reserved.
*
* Originally written by Brett Russ.
* Extensive overhaul and enhancement by Mark Lord <mlord@pobox.com>.
*
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
* 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
*
*/
/*
* sata_mv TODO list:
*
* --> Develop a low-power-consumption strategy, and implement it.
*
* --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
*
* --> [Experiment, Marvell value added] Is it possible to use target
* mode to cross-connect two Linux boxes with Marvell cards? If so,
* creating LibATA target mode support would be very interesting.
*
* Target mode, for those without docs, is the ability to directly
* connect two SATA ports.
*/
/*
* 80x1-B2 errata PCI#11:
*
* Users of the 6041/6081 Rev.B2 chips (current is C0)
* should be careful to insert those cards only onto PCI-X bus #0,
* and only in device slots 0..7, not higher. The chips may not
* work correctly otherwise (note: this is a pretty rare condition).
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mbus.h>
#include <linux/bitops.h>
#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
#define DRV_VERSION "1.28"
/*
* module options
*/
static int msi;
#ifdef CONFIG_PCI
module_param(msi, int, S_IRUGO);
MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
#endif
static int irq_coalescing_io_count;
module_param(irq_coalescing_io_count, int, S_IRUGO);
MODULE_PARM_DESC(irq_coalescing_io_count,
"IRQ coalescing I/O count threshold (0..255)");
static int irq_coalescing_usecs;
module_param(irq_coalescing_usecs, int, S_IRUGO);
MODULE_PARM_DESC(irq_coalescing_usecs,
"IRQ coalescing time threshold in usecs");
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
MV_PRIMARY_BAR = 0, /* offset 0x10: memory space */
MV_IO_BAR = 2, /* offset 0x18: IO space */
MV_MISC_BAR = 3, /* offset 0x1c: FLASH, NVRAM, SRAM */
MV_MAJOR_REG_AREA_SZ = 0x10000, /* 64KB */
MV_MINOR_REG_AREA_SZ = 0x2000, /* 8KB */
/* For use with both IRQ coalescing methods ("all ports" or "per-HC" */
COAL_CLOCKS_PER_USEC = 150, /* for calculating COAL_TIMEs */
MAX_COAL_TIME_THRESHOLD = ((1 << 24) - 1), /* internal clocks count */
MAX_COAL_IO_COUNT = 255, /* completed I/O count */
MV_PCI_REG_BASE = 0,
/*
* Per-chip ("all ports") interrupt coalescing feature.
* This is only for GEN_II / GEN_IIE hardware.
*
* Coalescing defers the interrupt until either the IO_THRESHOLD
* (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
*/
COAL_REG_BASE = 0x18000,
IRQ_COAL_CAUSE = (COAL_REG_BASE + 0x08),
ALL_PORTS_COAL_IRQ = (1 << 4), /* all ports irq event */
IRQ_COAL_IO_THRESHOLD = (COAL_REG_BASE + 0xcc),
IRQ_COAL_TIME_THRESHOLD = (COAL_REG_BASE + 0xd0),
/*
* Registers for the (unused here) transaction coalescing feature:
*/
TRAN_COAL_CAUSE_LO = (COAL_REG_BASE + 0x88),
TRAN_COAL_CAUSE_HI = (COAL_REG_BASE + 0x8c),
SATAHC0_REG_BASE = 0x20000,
FLASH_CTL = 0x1046c,
GPIO_PORT_CTL = 0x104f0,
RESET_CFG = 0x180d8,
MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ,
MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ,
MV_SATAHC_ARBTR_REG_SZ = MV_MINOR_REG_AREA_SZ, /* arbiter */
MV_PORT_REG_SZ = MV_MINOR_REG_AREA_SZ,
MV_MAX_Q_DEPTH = 32,
MV_MAX_Q_DEPTH_MASK = MV_MAX_Q_DEPTH - 1,
/* CRQB needs alignment on a 1KB boundary. Size == 1KB
* CRPB needs alignment on a 256B boundary. Size == 256B
* ePRD (SG) entries need alignment on a 16B boundary. Size == 16B
*/
MV_CRQB_Q_SZ = (32 * MV_MAX_Q_DEPTH),
MV_CRPB_Q_SZ = (8 * MV_MAX_Q_DEPTH),
MV_MAX_SG_CT = 256,
MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT),
/* Determine hc from 0-7 port: hc = port >> MV_PORT_HC_SHIFT */
MV_PORT_HC_SHIFT = 2,
MV_PORTS_PER_HC = (1 << MV_PORT_HC_SHIFT), /* 4 */
/* Determine hc port from 0-7 port: hardport = port & MV_PORT_MASK */
MV_PORT_MASK = (MV_PORTS_PER_HC - 1), /* 3 */
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI,
MV_GEN_II_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NCQ |
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA,
MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN,
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */
CRQB_PMP_SHIFT = 12, /* CRQB Gen-II/IIE PMP shift */
CRQB_HOSTQ_SHIFT = 17, /* CRQB Gen-II/IIE HostQueTag shift */
CRQB_CMD_ADDR_SHIFT = 8,
CRQB_CMD_CS = (0x2 << 11),
CRQB_CMD_LAST = (1 << 15),
CRPB_FLAG_STATUS_SHIFT = 8,
CRPB_IOID_SHIFT_6 = 5, /* CRPB Gen-II IO Id shift */
CRPB_IOID_SHIFT_7 = 7, /* CRPB Gen-IIE IO Id shift */
EPRD_FLAG_END_OF_TBL = (1 << 31),
/* PCI interface registers */
MV_PCI_COMMAND = 0xc00,
MV_PCI_COMMAND_MWRCOM = (1 << 4), /* PCI Master Write Combining */
MV_PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */
PCI_MAIN_CMD_STS = 0xd30,
STOP_PCI_MASTER = (1 << 2),
PCI_MASTER_EMPTY = (1 << 3),
GLOB_SFT_RST = (1 << 4),
MV_PCI_MODE = 0xd00,
MV_PCI_MODE_MASK = 0x30,
MV_PCI_EXP_ROM_BAR_CTL = 0xd2c,
MV_PCI_DISC_TIMER = 0xd04,
MV_PCI_MSI_TRIGGER = 0xc38,
MV_PCI_SERR_MASK = 0xc28,
MV_PCI_XBAR_TMOUT = 0x1d04,
MV_PCI_ERR_LOW_ADDRESS = 0x1d40,
MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
MV_PCI_ERR_ATTRIBUTE = 0x1d48,
MV_PCI_ERR_COMMAND = 0x1d50,
PCI_IRQ_CAUSE = 0x1d58,
PCI_IRQ_MASK = 0x1d5c,
PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */
PCIE_IRQ_CAUSE = 0x1900,
PCIE_IRQ_MASK = 0x1910,
PCIE_UNMASK_ALL_IRQS = 0x40a, /* assorted bits */
/* Host Controller Main Interrupt Cause/Mask registers (1 per-chip) */
PCI_HC_MAIN_IRQ_CAUSE = 0x1d60,
PCI_HC_MAIN_IRQ_MASK = 0x1d64,
SOC_HC_MAIN_IRQ_CAUSE = 0x20020,
SOC_HC_MAIN_IRQ_MASK = 0x20024,
ERR_IRQ = (1 << 0), /* shift by (2 * port #) */
DONE_IRQ = (1 << 1), /* shift by (2 * port #) */
HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */
HC_SHIFT = 9, /* bits 9-17 = HC1's ports */
DONE_IRQ_0_3 = 0x000000aa, /* DONE_IRQ ports 0,1,2,3 */
DONE_IRQ_4_7 = (DONE_IRQ_0_3 << HC_SHIFT), /* 4,5,6,7 */
PCI_ERR = (1 << 18),
TRAN_COAL_LO_DONE = (1 << 19), /* transaction coalescing */
TRAN_COAL_HI_DONE = (1 << 20), /* transaction coalescing */
PORTS_0_3_COAL_DONE = (1 << 8), /* HC0 IRQ coalescing */
PORTS_4_7_COAL_DONE = (1 << 17), /* HC1 IRQ coalescing */
ALL_PORTS_COAL_DONE = (1 << 21), /* GEN_II(E) IRQ coalescing */
GPIO_INT = (1 << 22),
SELF_INT = (1 << 23),
TWSI_INT = (1 << 24),
HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */
HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
/* SATAHC registers */
HC_CFG = 0x00,
HC_IRQ_CAUSE = 0x14,
DMA_IRQ = (1 << 0), /* shift by port # */
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
/*
* Per-HC (Host-Controller) interrupt coalescing feature.
* This is present on all chip generations.
*
* Coalescing defers the interrupt until either the IO_THRESHOLD
* (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
*/
HC_IRQ_COAL_IO_THRESHOLD = 0x000c,
HC_IRQ_COAL_TIME_THRESHOLD = 0x0010,
SOC_LED_CTRL = 0x2c,
SOC_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
SOC_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex dev presence */
/* with dev activity LED */
/* Shadow block registers */
SHD_BLK = 0x100,
SHD_CTL_AST = 0x20, /* ofs from SHD_BLK */
/* SATA registers */
SATA_STATUS = 0x300, /* ctrl, err regs follow status */
SATA_ACTIVE = 0x350,
FIS_IRQ_CAUSE = 0x364,
FIS_IRQ_CAUSE_AN = (1 << 9), /* async notification */
LTMODE = 0x30c, /* requires read-after-write */
LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */
PHY_MODE2 = 0x330,
PHY_MODE3 = 0x310,
PHY_MODE4 = 0x314, /* requires read-after-write */
PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */
PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */
PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */
PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */
SATA_IFCTL = 0x344,
SATA_TESTCTL = 0x348,
SATA_IFSTAT = 0x34c,
VENDOR_UNIQUE_FIS = 0x35c,
FISCFG = 0x360,
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
PHY_MODE9_GEN2 = 0x398,
PHY_MODE9_GEN1 = 0x39c,
PHYCFG_OFS = 0x3a0, /* only in 65n devices */
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
SATA_IFCFG = 0x050,
MV_M2_PREAMP_MASK = 0x7e0,
/* Port registers */
EDMA_CFG = 0,
EDMA_CFG_Q_DEPTH = 0x1f, /* max device queue depth */
EDMA_CFG_NCQ = (1 << 5), /* for R/W FPDMA queued */
EDMA_CFG_NCQ_GO_ON_ERR = (1 << 14), /* continue on error */
EDMA_CFG_RD_BRST_EXT = (1 << 11), /* read burst 512B */
EDMA_CFG_WR_BUFF_LEN = (1 << 13), /* write buffer 512B */
EDMA_CFG_EDMA_FBS = (1 << 16), /* EDMA FIS-Based Switching */
EDMA_CFG_FBS = (1 << 26), /* FIS-Based Switching */
EDMA_ERR_IRQ_CAUSE = 0x8,
EDMA_ERR_IRQ_MASK = 0xc,
EDMA_ERR_D_PAR = (1 << 0), /* UDMA data parity err */
EDMA_ERR_PRD_PAR = (1 << 1), /* UDMA PRD parity err */
EDMA_ERR_DEV = (1 << 2), /* device error */
EDMA_ERR_DEV_DCON = (1 << 3), /* device disconnect */
EDMA_ERR_DEV_CON = (1 << 4), /* device connected */
EDMA_ERR_SERR = (1 << 5), /* SError bits [WBDST] raised */
EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */
EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */
EDMA_ERR_BIST_ASYNC = (1 << 8), /* BIST FIS or Async Notify */
EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */
EDMA_ERR_CRQB_PAR = (1 << 9), /* CRQB parity error */
EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */
EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */
EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */
EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */
EDMA_ERR_LNK_CTRL_RX_0 = (1 << 13), /* transient: CRC err */
EDMA_ERR_LNK_CTRL_RX_1 = (1 << 14), /* transient: FIFO err */
EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), /* fatal: caught SYNC */
EDMA_ERR_LNK_CTRL_RX_3 = (1 << 16), /* transient: FIS rx err */
EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */
EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */
EDMA_ERR_LNK_CTRL_TX_0 = (1 << 21), /* transient: CRC err */
EDMA_ERR_LNK_CTRL_TX_1 = (1 << 22), /* transient: FIFO err */
EDMA_ERR_LNK_CTRL_TX_2 = (1 << 23), /* transient: caught SYNC */
EDMA_ERR_LNK_CTRL_TX_3 = (1 << 24), /* transient: caught DMAT */
EDMA_ERR_LNK_CTRL_TX_4 = (1 << 25), /* transient: FIS collision */
EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */
EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */
EDMA_ERR_OVERRUN_5 = (1 << 5),
EDMA_ERR_UNDERRUN_5 = (1 << 6),
EDMA_ERR_IRQ_TRANSIENT = EDMA_ERR_LNK_CTRL_RX_0 |
EDMA_ERR_LNK_CTRL_RX_1 |
EDMA_ERR_LNK_CTRL_RX_3 |
EDMA_ERR_LNK_CTRL_TX,
EDMA_EH_FREEZE = EDMA_ERR_D_PAR |
EDMA_ERR_PRD_PAR |
EDMA_ERR_DEV_DCON |
EDMA_ERR_DEV_CON |
EDMA_ERR_SERR |
EDMA_ERR_SELF_DIS |
EDMA_ERR_CRQB_PAR |
EDMA_ERR_CRPB_PAR |
EDMA_ERR_INTRL_PAR |
EDMA_ERR_IORDY |
EDMA_ERR_LNK_CTRL_RX_2 |
EDMA_ERR_LNK_DATA_RX |
EDMA_ERR_LNK_DATA_TX |
EDMA_ERR_TRANS_PROTO,
EDMA_EH_FREEZE_5 = EDMA_ERR_D_PAR |
EDMA_ERR_PRD_PAR |
EDMA_ERR_DEV_DCON |
EDMA_ERR_DEV_CON |
EDMA_ERR_OVERRUN_5 |
EDMA_ERR_UNDERRUN_5 |
EDMA_ERR_SELF_DIS_5 |
EDMA_ERR_CRQB_PAR |
EDMA_ERR_CRPB_PAR |
EDMA_ERR_INTRL_PAR |
EDMA_ERR_IORDY,
EDMA_REQ_Q_BASE_HI = 0x10,
EDMA_REQ_Q_IN_PTR = 0x14, /* also contains BASE_LO */
EDMA_REQ_Q_OUT_PTR = 0x18,
EDMA_REQ_Q_PTR_SHIFT = 5,
EDMA_RSP_Q_BASE_HI = 0x1c,
EDMA_RSP_Q_IN_PTR = 0x20,
EDMA_RSP_Q_OUT_PTR = 0x24, /* also contains BASE_LO */
EDMA_RSP_Q_PTR_SHIFT = 3,
EDMA_CMD = 0x28, /* EDMA command register */
EDMA_EN = (1 << 0), /* enable EDMA */
EDMA_DS = (1 << 1), /* disable EDMA; self-negated */
EDMA_RESET = (1 << 2), /* reset eng/trans/link/phy */
EDMA_STATUS = 0x30, /* EDMA engine status */
EDMA_STATUS_CACHE_EMPTY = (1 << 6), /* GenIIe command cache empty */
EDMA_STATUS_IDLE = (1 << 7), /* GenIIe EDMA enabled/idle */
EDMA_IORDY_TMOUT = 0x34,
EDMA_ARB_CFG = 0x38,
EDMA_HALTCOND = 0x60, /* GenIIe halt conditions */
EDMA_UNKNOWN_RSVD = 0x6C, /* GenIIe unknown/reserved */
BMDMA_CMD = 0x224, /* bmdma command register */
BMDMA_STATUS = 0x228, /* bmdma status register */
BMDMA_PRD_LOW = 0x22c, /* bmdma PRD addr 31:0 */
BMDMA_PRD_HIGH = 0x230, /* bmdma PRD addr 63:32 */
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
MV_HP_ERRATA_50XXB0 = (1 << 1),
MV_HP_ERRATA_50XXB2 = (1 << 2),
MV_HP_ERRATA_60X1B2 = (1 << 3),
MV_HP_ERRATA_60X1C0 = (1 << 4),
MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */
MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */
MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */
MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
MV_HP_QUIRK_LED_BLINK_EN = (1 << 12), /* is led blinking enabled? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */
MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */
MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */
MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */
};
#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
#define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
#define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE)
#define IS_SOC(hpriv) ((hpriv)->hp_flags & MV_HP_FLAG_SOC)
#define WINDOW_CTRL(i) (0x20030 + ((i) << 4))
#define WINDOW_BASE(i) (0x20034 + ((i) << 4))
enum {
/* DMA boundary 0xffff is required by the s/g splitting
* we need on /length/ in mv_fill-sg().
*/
MV_DMA_BOUNDARY = 0xffffU,
/* mask of register bits containing lower 32 bits
* of EDMA request queue DMA address
*/
EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
/* ditto, for response queue */
EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
};
enum chip_type {
chip_504x,
chip_508x,
chip_5080,
chip_604x,
chip_608x,
chip_6042,
chip_7042,
chip_soc,
};
/* Command ReQuest Block: 32B */
struct mv_crqb {
__le32 sg_addr;
__le32 sg_addr_hi;
__le16 ctrl_flags;
__le16 ata_cmd[11];
};