/*
* drivers/ata/sata_dwc_460ex.c
*
* Synopsys DesignWare Cores (DWC) SATA host driver
*
* Author: Mark Miesfeld <mmiesfeld@amcc.com>
*
* Ported from 2.6.19.2 to 2.6.25/26 by Stefan Roese <sr@denx.de>
* Copyright 2008 DENX Software Engineering
*
* Based on versions provided by AMCC and Synopsys which are:
* Copyright 2006 Applied Micro Circuits Corporation
* COPYRIGHT (C) 2005 SYNOPSYS, INC. ALL RIGHTS RESERVED
*
* 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; either version 2 of the License, or (at your
* option) any later version.
*/
#ifdef CONFIG_SATA_DWC_DEBUG
#define DEBUG
#endif
#ifdef CONFIG_SATA_DWC_VDEBUG
#define VERBOSE_DEBUG
#define DEBUG_NCQ
#endif
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/libata.h>
#include <linux/slab.h>
#include "libata.h"
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
/* These two are defined in "libata.h" */
#undef DRV_NAME
#undef DRV_VERSION
#define DRV_NAME "sata-dwc"
#define DRV_VERSION "1.3"
#define sata_dwc_writel(a, v) writel_relaxed(v, a)
#define sata_dwc_readl(a) readl_relaxed(a)
#ifndef NO_IRQ
#define NO_IRQ 0
#endif
#define AHB_DMA_BRST_DFLT 64 /* 16 data items burst length */
enum {
SATA_DWC_MAX_PORTS = 1,
SATA_DWC_SCR_OFFSET = 0x24,
SATA_DWC_REG_OFFSET = 0x64,
};
/* DWC SATA Registers */
struct sata_dwc_regs {
u32 fptagr; /* 1st party DMA tag */
u32 fpbor; /* 1st party DMA buffer offset */
u32 fptcr; /* 1st party DMA Xfr count */
u32 dmacr; /* DMA Control */
u32 dbtsr; /* DMA Burst Transac size */
u32 intpr; /* Interrupt Pending */
u32 intmr; /* Interrupt Mask */
u32 errmr; /* Error Mask */
u32 llcr; /* Link Layer Control */
u32 phycr; /* PHY Control */
u32 physr; /* PHY Status */
u32 rxbistpd; /* Recvd BIST pattern def register */
u32 rxbistpd1; /* Recvd BIST data dword1 */
u32 rxbistpd2; /* Recvd BIST pattern data dword2 */
u32 txbistpd; /* Trans BIST pattern def register */
u32 txbistpd1; /* Trans BIST data dword1 */
u32 txbistpd2; /* Trans BIST data dword2 */
u32 bistcr; /* BIST Control Register */
u32 bistfctr; /* BIST FIS Count Register */
u32 bistsr; /* BIST Status Register */
u32 bistdecr; /* BIST Dword Error count register */
u32 res[15]; /* Reserved locations */
u32 testr; /* Test Register */
u32 versionr; /* Version Register */
u32 idr; /* ID Register */
u32 unimpl[192]; /* Unimplemented */
u32 dmadr[256]; /* FIFO Locations in DMA Mode */
};
enum {
SCR_SCONTROL_DET_ENABLE = 0x00000001,
SCR_SSTATUS_DET_PRESENT = 0x00000001,
SCR_SERROR_DIAG_X = 0x04000000,
/* DWC SATA Register Operations */
SATA_DWC_TXFIFO_DEPTH = 0x01FF,
SATA_DWC_RXFIFO_DEPTH = 0x01FF,
SATA_DWC_DMACR_TMOD_TXCHEN = 0x00000004,
SATA_DWC_DMACR_TXCHEN = (0x00000001 | SATA_DWC_DMACR_TMOD_TXCHEN),
SATA_DWC_DMACR_RXCHEN = (0x00000002 | SATA_DWC_DMACR_TMOD_TXCHEN),
SATA_DWC_DMACR_TXRXCH_CLEAR = SATA_DWC_DMACR_TMOD_TXCHEN,
SATA_DWC_INTPR_DMAT = 0x00000001,
SATA_DWC_INTPR_NEWFP = 0x00000002,
SATA_DWC_INTPR_PMABRT = 0x00000004,
SATA_DWC_INTPR_ERR = 0x00000008,
SATA_DWC_INTPR_NEWBIST = 0x00000010,
SATA_DWC_INTPR_IPF =