]> git.sur5r.net Git - u-boot/commitdiff
sata: Move drivers into new drivers/ata directory
authorSimon Glass <sjg@chromium.org>
Thu, 15 Jun 2017 03:28:26 +0000 (21:28 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 11 Jul 2017 16:08:19 +0000 (10:08 -0600)
At present we have the SATA and PATA drivers mixed up in the drivers/block
directory. It is better to split them out into their own place. Use
drivers/ata which is what Linux does.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
48 files changed:
arch/powerpc/cpu/mpc85xx/cpu_init.c
common/Makefile
common/sata.c [deleted file]
drivers/Kconfig
drivers/Makefile
drivers/ata/Kconfig [new file with mode: 0644]
drivers/ata/Makefile [new file with mode: 0644]
drivers/ata/ahci-uclass.c [new file with mode: 0644]
drivers/ata/ahci.c [new file with mode: 0644]
drivers/ata/dwc_ahci.c [new file with mode: 0644]
drivers/ata/dwc_ahsata.c [new file with mode: 0644]
drivers/ata/dwc_ahsata.h [new file with mode: 0644]
drivers/ata/fsl_sata.c [new file with mode: 0644]
drivers/ata/fsl_sata.h [new file with mode: 0644]
drivers/ata/libata.c [new file with mode: 0644]
drivers/ata/mvsata_ide.c [new file with mode: 0644]
drivers/ata/mxc_ata.c [new file with mode: 0644]
drivers/ata/sata.c [new file with mode: 0644]
drivers/ata/sata_ceva.c [new file with mode: 0644]
drivers/ata/sata_dwc.c [new file with mode: 0644]
drivers/ata/sata_dwc.h [new file with mode: 0644]
drivers/ata/sata_mv.c [new file with mode: 0644]
drivers/ata/sata_sandbox.c [new file with mode: 0644]
drivers/ata/sata_sil.c [new file with mode: 0644]
drivers/ata/sata_sil.h [new file with mode: 0644]
drivers/ata/sata_sil3114.c [new file with mode: 0644]
drivers/ata/sata_sil3114.h [new file with mode: 0644]
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/ahci-uclass.c [deleted file]
drivers/block/ahci.c [deleted file]
drivers/block/dwc_ahci.c [deleted file]
drivers/block/dwc_ahsata.c [deleted file]
drivers/block/dwc_ahsata.h [deleted file]
drivers/block/fsl_sata.c [deleted file]
drivers/block/fsl_sata.h [deleted file]
drivers/block/libata.c [deleted file]
drivers/block/mvsata_ide.c [deleted file]
drivers/block/mxc_ata.c [deleted file]
drivers/block/sata_ceva.c [deleted file]
drivers/block/sata_dwc.c [deleted file]
drivers/block/sata_dwc.h [deleted file]
drivers/block/sata_mv.c [deleted file]
drivers/block/sata_sandbox.c [deleted file]
drivers/block/sata_sil.c [deleted file]
drivers/block/sata_sil.h [deleted file]
drivers/block/sata_sil3114.c [deleted file]
drivers/block/sata_sil3114.h [deleted file]

index 388fe2b4ef55cd291b54771c30957dff342a88bb..a3076d8d71005a16d0d166d9c8c9ea55b78c0d83 100644 (file)
@@ -48,7 +48,7 @@
 #ifndef CONFIG_ARCH_QEMU_E500
 #include <fsl_ddr.h>
 #endif
-#include "../../../../drivers/block/fsl_sata.h"
+#include "../../../../drivers/ata/fsl_sata.h"
 #ifdef CONFIG_U_QE
 #include <fsl_qe.h>
 #endif
index fdf5c31b1c90f762f599fb6c238d4d897042d490..f04ddc8352128a2e8293177c576c4c044b1d5366 100644 (file)
@@ -79,7 +79,6 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
 obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
 obj-$(CONFIG_LYNXKDI) += lynxkdi.o
 obj-$(CONFIG_MENU) += menu.o
-obj-$(CONFIG_SATA) += sata.o
 obj-$(CONFIG_SCSI) += scsi.o
 obj-$(CONFIG_UPDATE_TFTP) += update.o
 obj-$(CONFIG_DFU_TFTP) += update.o
diff --git a/common/sata.c b/common/sata.c
deleted file mode 100644 (file)
index 42ff5c7..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2000-2005, DENX Software Engineering
- *             Wolfgang Denk <wd@denx.de>
- * Copyright (C) Procsys. All rights reserved.
- *             Mushtaq Khan <mushtaq_k@procsys.com>
- *                     <mushtaqk_921@yahoo.co.in>
- * Copyright (C) 2008 Freescale Semiconductor, Inc.
- *             Dave Liu <daveliu@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <sata.h>
-
-struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *sata_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
-}
-#endif
-
-#ifdef CONFIG_BLK
-static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
-                               lbaint_t blkcnt, void *dst)
-{
-       return -ENOSYS;
-}
-
-static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
-                                lbaint_t blkcnt, const void *buffer)
-{
-       return -ENOSYS;
-}
-#else
-static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
-                               lbaint_t blkcnt, void *dst)
-{
-       return sata_read(block_dev->devnum, start, blkcnt, dst);
-}
-
-static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
-                                lbaint_t blkcnt, const void *buffer)
-{
-       return sata_write(block_dev->devnum, start, blkcnt, buffer);
-}
-#endif
-
-int __sata_initialize(void)
-{
-       int rc, ret = -1;
-       int i;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
-               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
-               sata_dev_desc[i].if_type = IF_TYPE_SATA;
-               sata_dev_desc[i].devnum = i;
-               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
-               sata_dev_desc[i].lba = 0;
-               sata_dev_desc[i].blksz = 512;
-               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
-#ifndef CONFIG_BLK
-               sata_dev_desc[i].block_read = sata_bread;
-               sata_dev_desc[i].block_write = sata_bwrite;
-#endif
-               rc = init_sata(i);
-               if (!rc) {
-                       rc = scan_sata(i);
-                       if (!rc && sata_dev_desc[i].lba > 0 &&
-                           sata_dev_desc[i].blksz > 0) {
-                               part_init(&sata_dev_desc[i]);
-                               ret = i;
-                       }
-               }
-       }
-
-       return ret;
-}
-int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
-
-__weak int __sata_stop(void)
-{
-       int i, err = 0;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
-               err |= reset_sata(i);
-
-       if (err)
-               printf("Could not reset some SATA devices\n");
-
-       return err;
-}
-int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
-
-#ifdef CONFIG_BLK
-static const struct blk_ops sata_blk_ops = {
-       .read   = sata_bread,
-       .write  = sata_bwrite,
-};
-
-U_BOOT_DRIVER(sata_blk) = {
-       .name           = "sata_blk",
-       .id             = UCLASS_BLK,
-       .ops            = &sata_blk_ops,
-};
-#else
-U_BOOT_LEGACY_BLK(sata) = {
-       .if_typename    = "sata",
-       .if_type        = IF_TYPE_SATA,
-       .max_devs       = CONFIG_SYS_SATA_MAX_DEVICE,
-       .desc           = sata_dev_desc,
-};
-#endif
index a736386a0d54631dca82c5c7558653965f74b633..63e4034c5653b34dd53bd0c080ebc22a6b3edaaf 100644 (file)
@@ -6,6 +6,8 @@ source "drivers/core/Kconfig"
 
 source "drivers/adc/Kconfig"
 
+source "drivers/ata/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
index 058bccb761d71a5c8383e57b4efd5e159c960aa5..9bbcc7bf9c9cbb7704fa6f898817dc8cf689f38f 100644 (file)
@@ -45,7 +45,7 @@ obj-$(CONFIG_SPL_DFU_SUPPORT) += dfu/
 obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/
 obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/
 obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/
-obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
+obj-$(CONFIG_SPL_SATA_SUPPORT) += ata/
 obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += block/
 obj-$(CONFIG_SPL_MMC_SUPPORT) += block/
 endif
@@ -66,6 +66,7 @@ endif
 ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
 
 obj-y += adc/
+obj-y += ata/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
new file mode 100644 (file)
index 0000000..6427f1b
--- /dev/null
@@ -0,0 +1,62 @@
+config AHCI
+       bool "Support SATA controllers with driver model"
+       depends on DM
+       help
+         This enables a uclass for disk controllers in U-Boot. Various driver
+         types can use this, such as AHCI/SATA. It does not provide any standard
+         operations at present. The block device interface has not been converted
+         to driver model.
+
+config SATA
+       bool "Support SATA controllers"
+       help
+         This enables support for SATA (Serial Advanced Technology
+         Attachment), a serial bus standard for connecting to hard drives and
+         other storage devices.
+
+         SATA replaces PATA (originally just ATA), which stands for Parallel AT
+         Attachment, where AT refers to an IBM AT (Advanced Technology)
+         computer released in 1984.
+
+         See also CMD_SATA which provides command-line support.
+
+config SCSI
+       bool "Support SCSI controllers"
+       help
+         This enables support for SCSI (Small Computer System Interface),
+         a parallel interface widely used with storage peripherals such as
+         hard drives and optical drives. The SCSI standards define physical
+         interfaces as well as protocols for controlling devices and
+         tranferring data.
+
+config DM_SCSI
+       bool "Support SCSI controllers with driver model"
+       depends on BLK
+       help
+         This option enables the SCSI (Small Computer System Interface) uclass
+         which supports SCSI and SATA HDDs. For every device configuration
+         (IDs/LUNs) a block device is created with RAW read/write and
+         filesystem support.
+
+menu "SATA/SCSI device support"
+
+config SATA_CEVA
+       bool "Ceva Sata controller"
+       depends on AHCI
+       depends on DM_SCSI
+       help
+         This option enables Ceva Sata controller hard IP available on Xilinx
+         ZynqMP. Support up to 2 external devices. Complient with SATA 3.1 and
+         AHCI 1.3 specifications with hot-plug detect feature.
+
+
+config DWC_AHCI
+       bool "Enable Synopsys DWC AHCI driver support"
+       select SCSI_AHCI
+       select PHY
+       depends on DM_SCSI
+       help
+         Enable this driver to support Sata devices through
+         Synopsys DWC AHCI module.
+
+endmenu
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
new file mode 100644 (file)
index 0000000..c48184c
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
+obj-$(CONFIG_AHCI) += ahci-uclass.o
+obj-$(CONFIG_SCSI_AHCI) += ahci.o
+obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
+obj-$(CONFIG_FSL_SATA) += fsl_sata.o
+obj-$(CONFIG_LIBATA) += libata.o
+obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
+obj-$(CONFIG_MX51_PATA) += mxc_ata.o
+obj-$(CONFIG_SATA) += sata.o
+obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
+obj-$(CONFIG_SATA_DWC) += sata_dwc.o
+obj-$(CONFIG_SATA_MV) += sata_mv.o
+obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
+obj-$(CONFIG_SATA_SIL) += sata_sil.o
+obj-$(CONFIG_SANDBOX) += sata_sandbox.o
diff --git a/drivers/ata/ahci-uclass.c b/drivers/ata/ahci-uclass.c
new file mode 100644 (file)
index 0000000..7b8c326
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+
+UCLASS_DRIVER(ahci) = {
+       .id             = UCLASS_AHCI,
+       .name           = "ahci",
+};
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
new file mode 100644 (file)
index 0000000..f474471
--- /dev/null
@@ -0,0 +1,1094 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006.
+ * Author: Jason Jin<Jason.jin@freescale.com>
+ *         Zhang Wei<wei.zhang@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * with the reference on libata and ahci drvier in kernel
+ */
+#include <common.h>
+
+#include <command.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <scsi.h>
+#include <libata.h>
+#include <linux/ctype.h>
+#include <ahci.h>
+
+static int ata_io_flush(u8 port);
+
+struct ahci_probe_ent *probe_ent = NULL;
+u16 *ataid[AHCI_MAX_PORTS];
+
+#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
+
+/*
+ * Some controllers limit number of blocks they can read/write at once.
+ * Contemporary SSD devices work much faster if the read/write size is aligned
+ * to a power of 2.  Let's set default to 128 and allowing to be overwritten if
+ * needed.
+ */
+#ifndef MAX_SATA_BLOCKS_READ_WRITE
+#define MAX_SATA_BLOCKS_READ_WRITE     0x80
+#endif
+
+/* Maximum timeouts for each event */
+#define WAIT_MS_SPINUP 20000
+#define WAIT_MS_DATAIO 10000
+#define WAIT_MS_FLUSH  5000
+#define WAIT_MS_LINKUP 200
+
+__weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
+{
+       return base + 0x100 + (port * 0x80);
+}
+
+
+static void ahci_setup_port(struct ahci_ioports *port, void __iomem *base,
+                           unsigned int port_idx)
+{
+       base = ahci_port_base(base, port_idx);
+
+       port->cmd_addr = base;
+       port->scr_addr = base + PORT_SCR;
+}
+
+
+#define msleep(a) udelay(a * 1000)
+
+static void ahci_dcache_flush_range(unsigned long begin, unsigned long len)
+{
+       const unsigned long start = begin;
+       const unsigned long end = start + len;
+
+       debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
+       flush_dcache_range(start, end);
+}
+
+/*
+ * SATA controller DMAs to physical RAM.  Ensure data from the
+ * controller is invalidated from dcache; next access comes from
+ * physical RAM.
+ */
+static void ahci_dcache_invalidate_range(unsigned long begin, unsigned long len)
+{
+       const unsigned long start = begin;
+       const unsigned long end = start + len;
+
+       debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
+       invalidate_dcache_range(start, end);
+}
+
+/*
+ * Ensure data for SATA controller is flushed out of dcache and
+ * written to physical memory.
+ */
+static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
+{
+       ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
+                               AHCI_PORT_PRIV_DMA_SZ);
+}
+
+static int waiting_for_cmd_completed(void __iomem *offset,
+                                    int timeout_msec,
+                                    u32 sign)
+{
+       int i;
+       u32 status;
+
+       for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
+               msleep(1);
+
+       return (i < timeout_msec) ? 0 : -1;
+}
+
+int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port)
+{
+       u32 tmp;
+       int j = 0;
+       void __iomem *port_mmio = probe_ent->port[port].port_mmio;
+
+       /*
+        * Bring up SATA link.
+        * SATA link bringup time is usually less than 1 ms; only very
+        * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
+        */
+       while (j < WAIT_MS_LINKUP) {
+               tmp = readl(port_mmio + PORT_SCR_STAT);
+               tmp &= PORT_SCR_STAT_DET_MASK;
+               if (tmp == PORT_SCR_STAT_DET_PHYRDY)
+                       return 0;
+               udelay(1000);
+               j++;
+       }
+       return 1;
+}
+
+#ifdef CONFIG_SUNXI_AHCI
+/* The sunxi AHCI controller requires this undocumented setup */
+static void sunxi_dma_init(void __iomem *port_mmio)
+{
+       clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400);
+}
+#endif
+
+int ahci_reset(void __iomem *base)
+{
+       int i = 1000;
+       u32 __iomem *host_ctl_reg = base + HOST_CTL;
+       u32 tmp = readl(host_ctl_reg); /* global controller reset */
+
+       if ((tmp & HOST_RESET) == 0)
+               writel_with_flush(tmp | HOST_RESET, host_ctl_reg);
+
+       /*
+        * reset must complete within 1 second, or
+        * the hardware should be considered fried.
+        */
+       do {
+               udelay(1000);
+               tmp = readl(host_ctl_reg);
+               i--;
+       } while ((i > 0) && (tmp & HOST_RESET));
+
+       if (i == 0) {
+               printf("controller reset failed (0x%x)\n", tmp);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+{
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# ifdef CONFIG_DM_PCI
+       struct udevice *dev = probe_ent->dev;
+       struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+# else
+       pci_dev_t pdev = probe_ent->dev;
+       unsigned short vendor;
+# endif
+       u16 tmp16;
+#endif
+       void __iomem *mmio = probe_ent->mmio_base;
+       u32 tmp, cap_save, cmd;
+       int i, j, ret;
+       void __iomem *port_mmio;
+       u32 port_map;
+
+       debug("ahci_host_init: start\n");
+
+       cap_save = readl(mmio + HOST_CAP);
+       cap_save &= ((1 << 28) | (1 << 17));
+       cap_save |= (1 << 27);  /* Staggered Spin-up. Not needed. */
+
+       ret = ahci_reset(probe_ent->mmio_base);
+       if (ret)
+               return ret;
+
+       writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
+       writel(cap_save, mmio + HOST_CAP);
+       writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
+
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# ifdef CONFIG_DM_PCI
+       if (pplat->vendor == PCI_VENDOR_ID_INTEL) {
+               u16 tmp16;
+
+               dm_pci_read_config16(dev, 0x92, &tmp16);
+               dm_pci_write_config16(dev, 0x92, tmp16 | 0xf);
+       }
+# else
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
+
+       if (vendor == PCI_VENDOR_ID_INTEL) {
+               u16 tmp16;
+               pci_read_config_word(pdev, 0x92, &tmp16);
+               tmp16 |= 0xf;
+               pci_write_config_word(pdev, 0x92, tmp16);
+       }
+# endif
+#endif
+       probe_ent->cap = readl(mmio + HOST_CAP);
+       probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
+       port_map = probe_ent->port_map;
+       probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
+
+       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
+             probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+
+       if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
+               probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
+
+       for (i = 0; i < probe_ent->n_ports; i++) {
+               if (!(port_map & (1 << i)))
+                       continue;
+               probe_ent->port[i].port_mmio = ahci_port_base(mmio, i);
+               port_mmio = (u8 *) probe_ent->port[i].port_mmio;
+               ahci_setup_port(&probe_ent->port[i], mmio, i);
+
+               /* make sure port is not active */
+               tmp = readl(port_mmio + PORT_CMD);
+               if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+                          PORT_CMD_FIS_RX | PORT_CMD_START)) {
+                       debug("Port %d is active. Deactivating.\n", i);
+                       tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+                                PORT_CMD_FIS_RX | PORT_CMD_START);
+                       writel_with_flush(tmp, port_mmio + PORT_CMD);
+
+                       /* spec says 500 msecs for each bit, so
+                        * this is slightly incorrect.
+                        */
+                       msleep(500);
+               }
+
+#ifdef CONFIG_SUNXI_AHCI
+               sunxi_dma_init(port_mmio);
+#endif
+
+               /* Add the spinup command to whatever mode bits may
+                * already be on in the command register.
+                */
+               cmd = readl(port_mmio + PORT_CMD);
+               cmd |= PORT_CMD_SPIN_UP;
+               writel_with_flush(cmd, port_mmio + PORT_CMD);
+
+               /* Bring up SATA link. */
+               ret = ahci_link_up(probe_ent, i);
+               if (ret) {
+                       printf("SATA link %d timeout.\n", i);
+                       continue;
+               } else {
+                       debug("SATA link ok.\n");
+               }
+
+               /* Clear error status */
+               tmp = readl(port_mmio + PORT_SCR_ERR);
+               if (tmp)
+                       writel(tmp, port_mmio + PORT_SCR_ERR);
+
+               debug("Spinning up device on SATA port %d... ", i);
+
+               j = 0;
+               while (j < WAIT_MS_SPINUP) {
+                       tmp = readl(port_mmio + PORT_TFDATA);
+                       if (!(tmp & (ATA_BUSY | ATA_DRQ)))
+                               break;
+                       udelay(1000);
+                       tmp = readl(port_mmio + PORT_SCR_STAT);
+                       tmp &= PORT_SCR_STAT_DET_MASK;
+                       if (tmp == PORT_SCR_STAT_DET_PHYRDY)
+                               break;
+                       j++;
+               }
+
+               tmp = readl(port_mmio + PORT_SCR_STAT) & PORT_SCR_STAT_DET_MASK;
+               if (tmp == PORT_SCR_STAT_DET_COMINIT) {
+                       debug("SATA link %d down (COMINIT received), retrying...\n", i);
+                       i--;
+                       continue;
+               }
+
+               printf("Target spinup took %d ms.\n", j);
+               if (j == WAIT_MS_SPINUP)
+                       debug("timeout.\n");
+               else
+                       debug("ok.\n");
+
+               tmp = readl(port_mmio + PORT_SCR_ERR);
+               debug("PORT_SCR_ERR 0x%x\n", tmp);
+               writel(tmp, port_mmio + PORT_SCR_ERR);
+
+               /* ack any pending irq events for this port */
+               tmp = readl(port_mmio + PORT_IRQ_STAT);
+               debug("PORT_IRQ_STAT 0x%x\n", tmp);
+               if (tmp)
+                       writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+               writel(1 << i, mmio + HOST_IRQ_STAT);
+
+               /* register linkup ports */
+               tmp = readl(port_mmio + PORT_SCR_STAT);
+               debug("SATA port %d status: 0x%x\n", i, tmp);
+               if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
+                       probe_ent->link_port_map |= (0x01 << i);
+       }
+
+       tmp = readl(mmio + HOST_CTL);
+       debug("HOST_CTL 0x%x\n", tmp);
+       writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+       tmp = readl(mmio + HOST_CTL);
+       debug("HOST_CTL 0x%x\n", tmp);
+#if !defined(CONFIG_DM_SCSI)
+#ifndef CONFIG_SCSI_AHCI_PLAT
+# ifdef CONFIG_DM_PCI
+       dm_pci_read_config16(dev, PCI_COMMAND, &tmp16);
+       tmp |= PCI_COMMAND_MASTER;
+       dm_pci_write_config16(dev, PCI_COMMAND, tmp16);
+# else
+       pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
+       tmp |= PCI_COMMAND_MASTER;
+       pci_write_config_word(pdev, PCI_COMMAND, tmp16);
+# endif
+#endif
+#endif
+       return 0;
+}
+
+
+static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+{
+#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
+# if defined(CONFIG_DM_PCI)
+       struct udevice *dev = probe_ent->dev;
+# else
+       pci_dev_t pdev = probe_ent->dev;
+# endif
+       u16 cc;
+#endif
+       void __iomem *mmio = probe_ent->mmio_base;
+       u32 vers, cap, cap2, impl, speed;
+       const char *speed_s;
+       const char *scc_s;
+
+       vers = readl(mmio + HOST_VERSION);
+       cap = probe_ent->cap;
+       cap2 = readl(mmio + HOST_CAP2);
+       impl = probe_ent->port_map;
+
+       speed = (cap >> 20) & 0xf;
+       if (speed == 1)
+               speed_s = "1.5";
+       else if (speed == 2)
+               speed_s = "3";
+       else if (speed == 3)
+               speed_s = "6";
+       else
+               speed_s = "?";
+
+#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI)
+       scc_s = "SATA";
+#else
+# ifdef CONFIG_DM_PCI
+       dm_pci_read_config16(dev, 0x0a, &cc);
+# else
+       pci_read_config_word(pdev, 0x0a, &cc);
+# endif
+       if (cc == 0x0101)
+               scc_s = "IDE";
+       else if (cc == 0x0106)
+               scc_s = "SATA";
+       else if (cc == 0x0104)
+               scc_s = "RAID";
+       else
+               scc_s = "unknown";
+#endif
+       printf("AHCI %02x%02x.%02x%02x "
+              "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
+              (vers >> 24) & 0xff,
+              (vers >> 16) & 0xff,
+              (vers >> 8) & 0xff,
+              vers & 0xff,
+              ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
+
+       printf("flags: "
+              "%s%s%s%s%s%s%s"
+              "%s%s%s%s%s%s%s"
+              "%s%s%s%s%s%s\n",
+              cap & (1 << 31) ? "64bit " : "",
+              cap & (1 << 30) ? "ncq " : "",
+              cap & (1 << 28) ? "ilck " : "",
+              cap & (1 << 27) ? "stag " : "",
+              cap & (1 << 26) ? "pm " : "",
+              cap & (1 << 25) ? "led " : "",
+              cap & (1 << 24) ? "clo " : "",
+              cap & (1 << 19) ? "nz " : "",
+              cap & (1 << 18) ? "only " : "",
+              cap & (1 << 17) ? "pmp " : "",
+              cap & (1 << 16) ? "fbss " : "",
+              cap & (1 << 15) ? "pio " : "",
+              cap & (1 << 14) ? "slum " : "",
+              cap & (1 << 13) ? "part " : "",
+              cap & (1 << 7) ? "ccc " : "",
+              cap & (1 << 6) ? "ems " : "",
+              cap & (1 << 5) ? "sxs " : "",
+              cap2 & (1 << 2) ? "apst " : "",
+              cap2 & (1 << 1) ? "nvmp " : "",
+              cap2 & (1 << 0) ? "boh " : "");
+}
+
+#ifndef CONFIG_SCSI_AHCI_PLAT
+# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
+static int ahci_init_one(struct udevice *dev)
+# else
+static int ahci_init_one(pci_dev_t dev)
+# endif
+{
+#if !defined(CONFIG_DM_SCSI)
+       u16 vendor;
+#endif
+       int rc;
+
+       probe_ent = malloc(sizeof(struct ahci_probe_ent));
+       if (!probe_ent) {
+               printf("%s: No memory for probe_ent\n", __func__);
+               return -ENOMEM;
+       }
+
+       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+       probe_ent->dev = dev;
+
+       probe_ent->host_flags = ATA_FLAG_SATA
+                               | ATA_FLAG_NO_LEGACY
+                               | ATA_FLAG_MMIO
+                               | ATA_FLAG_PIO_DMA
+                               | ATA_FLAG_NO_ATAPI;
+       probe_ent->pio_mask = 0x1f;
+       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
+
+#if !defined(CONFIG_DM_SCSI)
+#ifdef CONFIG_DM_PCI
+       probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
+                                             PCI_REGION_MEM);
+
+       /* Take from kernel:
+        * JMicron-specific fixup:
+        * make sure we're in AHCI mode
+        */
+       dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor);
+       if (vendor == 0x197b)
+               dm_pci_write_config8(dev, 0x41, 0xa1);
+#else
+       probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
+                                          PCI_REGION_MEM);
+
+       /* Take from kernel:
+        * JMicron-specific fixup:
+        * make sure we're in AHCI mode
+        */
+       pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
+       if (vendor == 0x197b)
+               pci_write_config_byte(dev, 0x41, 0xa1);
+#endif
+#else
+       struct scsi_platdata *plat = dev_get_platdata(dev);
+       probe_ent->mmio_base = (void *)plat->base;
+#endif
+
+       debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
+       /* initialize adapter */
+       rc = ahci_host_init(probe_ent);
+       if (rc)
+               goto err_out;
+
+       ahci_print_info(probe_ent);
+
+       return 0;
+
+      err_out:
+       return rc;
+}
+#endif
+
+#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
+
+static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
+       u32 sg_count;
+       int i;
+
+       sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
+       if (sg_count > AHCI_MAX_SG) {
+               printf("Error:Too much sg!\n");
+               return -1;
+       }
+
+       for (i = 0; i < sg_count; i++) {
+               ahci_sg->addr =
+                   cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
+               ahci_sg->addr_hi = 0;
+               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
+                                         (buf_len < MAX_DATA_BYTE_COUNT
+                                          ? (buf_len - 1)
+                                          : (MAX_DATA_BYTE_COUNT - 1)));
+               ahci_sg++;
+               buf_len -= MAX_DATA_BYTE_COUNT;
+       }
+
+       return sg_count;
+}
+
+
+static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
+{
+       pp->cmd_slot->opts = cpu_to_le32(opts);
+       pp->cmd_slot->status = 0;
+       pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff);
+#ifdef CONFIG_PHYS_64BIT
+       pp->cmd_slot->tbl_addr_hi =
+           cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16));
+#endif
+}
+
+static int wait_spinup(void __iomem *port_mmio)
+{
+       ulong start;
+       u32 tf_data;
+
+       start = get_timer(0);
+       do {
+               tf_data = readl(port_mmio + PORT_TFDATA);
+               if (!(tf_data & ATA_BUSY))
+                       return 0;
+       } while (get_timer(start) < WAIT_MS_SPINUP);
+
+       return -ETIMEDOUT;
+}
+
+static int ahci_port_start(u8 port)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       void __iomem *port_mmio = pp->port_mmio;
+       u32 port_status;
+       void __iomem *mem;
+
+       debug("Enter start port: %d\n", port);
+       port_status = readl(port_mmio + PORT_SCR_STAT);
+       debug("Port %d status: %x\n", port, port_status);
+       if ((port_status & 0xf) != 0x03) {
+               printf("No Link on this port!\n");
+               return -1;
+       }
+
+       mem = malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
+       if (!mem) {
+               free(pp);
+               printf("%s: No mem for table!\n", __func__);
+               return -ENOMEM;
+       }
+
+       /* Aligned to 2048-bytes */
+       mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ);
+       memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+
+       /*
+        * First item in chunk of DMA memory: 32-slot command table,
+        * 32 bytes each in size
+        */
+       pp->cmd_slot =
+               (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
+       debug("cmd_slot = %p\n", pp->cmd_slot);
+       mem += (AHCI_CMD_SLOT_SZ + 224);
+
+       /*
+        * Second item: Received-FIS area
+        */
+       pp->rx_fis = virt_to_phys((void *)mem);
+       mem += AHCI_RX_FIS_SZ;
+
+       /*
+        * Third item: data area for storing a single command
+        * and its scatter-gather table
+        */
+       pp->cmd_tbl = virt_to_phys((void *)mem);
+       debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl);
+
+       mem += AHCI_CMD_TBL_HDR;
+       pp->cmd_tbl_sg =
+                       (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
+
+       writel_with_flush((unsigned long)pp->cmd_slot,
+                         port_mmio + PORT_LST_ADDR);
+
+       writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
+
+#ifdef CONFIG_SUNXI_AHCI
+       sunxi_dma_init(port_mmio);
+#endif
+
+       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+                         PORT_CMD_START, port_mmio + PORT_CMD);
+
+       debug("Exit start port %d\n", port);
+
+       /*
+        * Make sure interface is not busy based on error and status
+        * information from task file data register before proceeding
+        */
+       return wait_spinup(port_mmio);
+}
+
+
+static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
+                               int buf_len, u8 is_write)
+{
+
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       void __iomem *port_mmio = pp->port_mmio;
+       u32 opts;
+       u32 port_status;
+       int sg_count;
+
+       debug("Enter %s: for port %d\n", __func__, port);
+
+       if (port > probe_ent->n_ports) {
+               printf("Invalid port number %d\n", port);
+               return -1;
+       }
+
+       port_status = readl(port_mmio + PORT_SCR_STAT);
+       if ((port_status & 0xf) != 0x03) {
+               debug("No Link on port %d!\n", port);
+               return -1;
+       }
+
+       memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
+
+       sg_count = ahci_fill_sg(port, buf, buf_len);
+       opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
+       ahci_fill_cmd_slot(pp, opts);
+
+       ahci_dcache_flush_sata_cmd(pp);
+       ahci_dcache_flush_range((unsigned long)buf, (unsigned long)buf_len);
+
+       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
+
+       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
+                               WAIT_MS_DATAIO, 0x1)) {
+               printf("timeout exit!\n");
+               return -1;
+       }
+
+       ahci_dcache_invalidate_range((unsigned long)buf,
+                                    (unsigned long)buf_len);
+       debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status);
+
+       return 0;
+}
+
+
+static char *ata_id_strcpy(u16 *target, u16 *src, int len)
+{
+       int i;
+       for (i = 0; i < len / 2; i++)
+               target[i] = swab16(src[i]);
+       return (char *)target;
+}
+
+/*
+ * SCSI INQUIRY command operation.
+ */
+static int ata_scsiop_inquiry(ccb *pccb)
+{
+       static const u8 hdr[] = {
+               0,
+               0,
+               0x5,            /* claim SPC-3 version compatibility */
+               2,
+               95 - 4,
+       };
+       u8 fis[20];
+       u16 *idbuf;
+       ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
+       u8 port;
+
+       /* Clean ccb data buffer */
+       memset(pccb->pdata, 0, pccb->datalen);
+
+       memcpy(pccb->pdata, hdr, sizeof(hdr));
+
+       if (pccb->datalen <= 35)
+               return 0;
+
+       memset(fis, 0, sizeof(fis));
+       /* Construct the FIS */
+       fis[0] = 0x27;          /* Host to device FIS. */
+       fis[1] = 1 << 7;        /* Command FIS. */
+       fis[2] = ATA_CMD_ID_ATA; /* Command byte. */
+
+       /* Read id from sata */
+       port = pccb->target;
+
+       if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), (u8 *)tmpid,
+                               ATA_ID_WORDS * 2, 0)) {
+               debug("scsi_ahci: SCSI inquiry command failure.\n");
+               return -EIO;
+       }
+
+       if (!ataid[port]) {
+               ataid[port] = malloc(ATA_ID_WORDS * 2);
+               if (!ataid[port]) {
+                       printf("%s: No memory for ataid[port]\n", __func__);
+                       return -ENOMEM;
+               }
+       }
+
+       idbuf = ataid[port];
+
+       memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
+       ata_swap_buf_le16(idbuf, ATA_ID_WORDS);
+
+       memcpy(&pccb->pdata[8], "ATA     ", 8);
+       ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16);
+       ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4);
+
+#ifdef DEBUG
+       ata_dump_id(idbuf);
+#endif
+       return 0;
+}
+
+
+/*
+ * SCSI READ10/WRITE10 command operation.
+ */
+static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
+{
+       lbaint_t lba = 0;
+       u16 blocks = 0;
+       u8 fis[20];
+       u8 *user_buffer = pccb->pdata;
+       u32 user_buffer_size = pccb->datalen;
+
+       /* Retrieve the base LBA number from the ccb structure. */
+       if (pccb->cmd[0] == SCSI_READ16) {
+               memcpy(&lba, pccb->cmd + 2, 8);
+               lba = be64_to_cpu(lba);
+       } else {
+               u32 temp;
+               memcpy(&temp, pccb->cmd + 2, 4);
+               lba = be32_to_cpu(temp);
+       }
+
+       /*
+        * Retrieve the base LBA number and the block count from
+        * the ccb structure.
+        *
+        * For 10-byte and 16-byte SCSI R/W commands, transfer
+        * length 0 means transfer 0 block of data.
+        * However, for ATA R/W commands, sector count 0 means
+        * 256 or 65536 sectors, not 0 sectors as in SCSI.
+        *
+        * WARNING: one or two older ATA drives treat 0 as 0...
+        */
+       if (pccb->cmd[0] == SCSI_READ16)
+               blocks = (((u16)pccb->cmd[13]) << 8) | ((u16) pccb->cmd[14]);
+       else
+               blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);
+
+       debug("scsi_ahci: %s %u blocks starting from lba 0x" LBAFU "\n",
+             is_write ?  "write" : "read", blocks, lba);
+
+       /* Preset the FIS */
+       memset(fis, 0, sizeof(fis));
+       fis[0] = 0x27;           /* Host to device FIS. */
+       fis[1] = 1 << 7;         /* Command FIS. */
+       /* Command byte (read/write). */
+       fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
+
+       while (blocks) {
+               u16 now_blocks; /* number of blocks per iteration */
+               u32 transfer_size; /* number of bytes per iteration */
+
+               now_blocks = min((u16)MAX_SATA_BLOCKS_READ_WRITE, blocks);
+
+               transfer_size = ATA_SECT_SIZE * now_blocks;
+               if (transfer_size > user_buffer_size) {
+                       printf("scsi_ahci: Error: buffer too small.\n");
+                       return -EIO;
+               }
+
+               /*
+                * LBA48 SATA command but only use 32bit address range within
+                * that (unless we've enabled 64bit LBA support). The next
+                * smaller command range (28bit) is too small.
+                */
+               fis[4] = (lba >> 0) & 0xff;
+               fis[5] = (lba >> 8) & 0xff;
+               fis[6] = (lba >> 16) & 0xff;
+               fis[7] = 1 << 6; /* device reg: set LBA mode */
+               fis[8] = ((lba >> 24) & 0xff);
+#ifdef CONFIG_SYS_64BIT_LBA
+               if (pccb->cmd[0] == SCSI_READ16) {
+                       fis[9] = ((lba >> 32) & 0xff);
+                       fis[10] = ((lba >> 40) & 0xff);
+               }
+#endif
+
+               fis[3] = 0xe0; /* features */
+
+               /* Block (sector) count */
+               fis[12] = (now_blocks >> 0) & 0xff;
+               fis[13] = (now_blocks >> 8) & 0xff;
+
+               /* Read/Write from ahci */
+               if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
+                                       user_buffer, transfer_size,
+                                       is_write)) {
+                       debug("scsi_ahci: SCSI %s10 command failure.\n",
+                             is_write ? "WRITE" : "READ");
+                       return -EIO;
+               }
+
+               /* If this transaction is a write, do a following flush.
+                * Writes in u-boot are so rare, and the logic to know when is
+                * the last write and do a flush only there is sufficiently
+                * difficult. Just do a flush after every write. This incurs,
+                * usually, one extra flush when the rare writes do happen.
+                */
+               if (is_write) {
+                       if (-EIO == ata_io_flush(pccb->target))
+                               return -EIO;
+               }
+               user_buffer += transfer_size;
+               user_buffer_size -= transfer_size;
+               blocks -= now_blocks;
+               lba += now_blocks;
+       }
+
+       return 0;
+}
+
+
+/*
+ * SCSI READ CAPACITY10 command operation.
+ */
+static int ata_scsiop_read_capacity10(ccb *pccb)
+{
+       u32 cap;
+       u64 cap64;
+       u32 block_size;
+
+       if (!ataid[pccb->target]) {
+               printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
+                      "\tNo ATA info!\n"
+                      "\tPlease run SCSI command INQUIRY first!\n");
+               return -EPERM;
+       }
+
+       cap64 = ata_id_n_sectors(ataid[pccb->target]);
+       if (cap64 > 0x100000000ULL)
+               cap64 = 0xffffffff;
+
+       cap = cpu_to_be32(cap64);
+       memcpy(pccb->pdata, &cap, sizeof(cap));
+
+       block_size = cpu_to_be32((u32)512);
+       memcpy(&pccb->pdata[4], &block_size, 4);
+
+       return 0;
+}
+
+
+/*
+ * SCSI READ CAPACITY16 command operation.
+ */
+static int ata_scsiop_read_capacity16(ccb *pccb)
+{
+       u64 cap;
+       u64 block_size;
+
+       if (!ataid[pccb->target]) {
+               printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
+                      "\tNo ATA info!\n"
+                      "\tPlease run SCSI command INQUIRY first!\n");
+               return -EPERM;
+       }
+
+       cap = ata_id_n_sectors(ataid[pccb->target]);
+       cap = cpu_to_be64(cap);
+       memcpy(pccb->pdata, &cap, sizeof(cap));
+
+       block_size = cpu_to_be64((u64)512);
+       memcpy(&pccb->pdata[8], &block_size, 8);
+
+       return 0;
+}
+
+
+/*
+ * SCSI TEST UNIT READY command operation.
+ */
+static int ata_scsiop_test_unit_ready(ccb *pccb)
+{
+       return (ataid[pccb->target]) ? 0 : -EPERM;
+}
+
+
+int scsi_exec(ccb *pccb)
+{
+       int ret;
+
+       switch (pccb->cmd[0]) {
+       case SCSI_READ16:
+       case SCSI_READ10:
+               ret = ata_scsiop_read_write(pccb, 0);
+               break;
+       case SCSI_WRITE10:
+               ret = ata_scsiop_read_write(pccb, 1);
+               break;
+       case SCSI_RD_CAPAC10:
+               ret = ata_scsiop_read_capacity10(pccb);
+               break;
+       case SCSI_RD_CAPAC16:
+               ret = ata_scsiop_read_capacity16(pccb);
+               break;
+       case SCSI_TST_U_RDY:
+               ret = ata_scsiop_test_unit_ready(pccb);
+               break;
+       case SCSI_INQUIRY:
+               ret = ata_scsiop_inquiry(pccb);
+               break;
+       default:
+               printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
+               return false;
+       }
+
+       if (ret) {
+               debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
+               return false;
+       }
+       return true;
+
+}
+
+#if defined(CONFIG_DM_SCSI)
+void scsi_low_level_init(int busdevfunc, struct udevice *dev)
+#else
+void scsi_low_level_init(int busdevfunc)
+#endif
+{
+       int i;
+       u32 linkmap;
+
+#ifndef CONFIG_SCSI_AHCI_PLAT
+# if defined(CONFIG_DM_PCI)
+       struct udevice *dev;
+       int ret;
+
+       ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
+       if (ret)
+               return;
+       ahci_init_one(dev);
+# elif defined(CONFIG_DM_SCSI)
+       ahci_init_one(dev);
+# else
+       ahci_init_one(busdevfunc);
+# endif
+#endif
+
+       linkmap = probe_ent->link_port_map;
+
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+               if (((linkmap >> i) & 0x01)) {
+                       if (ahci_port_start((u8) i)) {
+                               printf("Can not start port %d\n", i);
+                               continue;
+                       }
+               }
+       }
+}
+
+#ifdef CONFIG_SCSI_AHCI_PLAT
+int ahci_init(void __iomem *base)
+{
+       int i, rc = 0;
+       u32 linkmap;
+
+       probe_ent = malloc(sizeof(struct ahci_probe_ent));
+       if (!probe_ent) {
+               printf("%s: No memory for probe_ent\n", __func__);
+               return -ENOMEM;
+       }
+
+       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+
+       probe_ent->host_flags = ATA_FLAG_SATA
+                               | ATA_FLAG_NO_LEGACY
+                               | ATA_FLAG_MMIO
+                               | ATA_FLAG_PIO_DMA
+                               | ATA_FLAG_NO_ATAPI;
+       probe_ent->pio_mask = 0x1f;
+       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
+
+       probe_ent->mmio_base = base;
+
+       /* initialize adapter */
+       rc = ahci_host_init(probe_ent);
+       if (rc)
+               goto err_out;
+
+       ahci_print_info(probe_ent);
+
+       linkmap = probe_ent->link_port_map;
+
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+               if (((linkmap >> i) & 0x01)) {
+                       if (ahci_port_start((u8) i)) {
+                               printf("Can not start port %d\n", i);
+                               continue;
+                       }
+               }
+       }
+err_out:
+       return rc;
+}
+
+void __weak scsi_init(void)
+{
+}
+
+#endif
+
+/*
+ * In the general case of generic rotating media it makes sense to have a
+ * flush capability. It probably even makes sense in the case of SSDs because
+ * one cannot always know for sure what kind of internal cache/flush mechanism
+ * is embodied therein. At first it was planned to invoke this after the last
+ * write to disk and before rebooting. In practice, knowing, a priori, which
+ * is the last write is difficult. Because writing to the disk in u-boot is
+ * very rare, this flush command will be invoked after every block write.
+ */
+static int ata_io_flush(u8 port)
+{
+       u8 fis[20];
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       void __iomem *port_mmio = pp->port_mmio;
+       u32 cmd_fis_len = 5;    /* five dwords */
+
+       /* Preset the FIS */
+       memset(fis, 0, 20);
+       fis[0] = 0x27;           /* Host to device FIS. */
+       fis[1] = 1 << 7;         /* Command FIS. */
+       fis[2] = ATA_CMD_FLUSH_EXT;
+
+       memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
+       ahci_fill_cmd_slot(pp, cmd_fis_len);
+       ahci_dcache_flush_sata_cmd(pp);
+       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
+
+       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
+                       WAIT_MS_FLUSH, 0x1)) {
+               debug("scsi_ahci: flush command timeout on port %d.\n", port);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+
+__weak void scsi_bus_reset(void)
+{
+       /*Not implement*/
+}
diff --git a/drivers/ata/dwc_ahci.c b/drivers/ata/dwc_ahci.c
new file mode 100644 (file)
index 0000000..3f839bf
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * DWC SATA platform driver
+ *
+ * (C) Copyright 2016
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Author: Mugunthan V N <mugunthanvnm@ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <sata.h>
+#include <asm/arch/sata.h>
+#include <asm/io.h>
+#include <generic-phy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct dwc_ahci_priv {
+       void *base;
+       void *wrapper_base;
+};
+
+static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
+{
+       struct dwc_ahci_priv *priv = dev_get_priv(dev);
+       struct scsi_platdata *plat = dev_get_platdata(dev);
+       fdt_addr_t addr;
+
+       plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+                                      "max-id", CONFIG_SYS_SCSI_MAX_SCSI_ID);
+       plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+                                       "max-lun", CONFIG_SYS_SCSI_MAX_LUN);
+
+       priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *),
+                                MAP_NOCACHE);
+
+       addr = devfdt_get_addr_index(dev, 1);
+       if (addr != FDT_ADDR_T_NONE) {
+               priv->wrapper_base = map_physmem(addr, sizeof(void *),
+                                                MAP_NOCACHE);
+       } else {
+               priv->wrapper_base = NULL;
+       }
+
+       return 0;
+}
+
+static int dwc_ahci_probe(struct udevice *dev)
+{
+       struct dwc_ahci_priv *priv = dev_get_priv(dev);
+       int ret;
+       struct phy phy;
+
+       ret = generic_phy_get_by_name(dev, "sata-phy", &phy);
+       if (ret) {
+               error("can't get the phy from DT\n");
+               return ret;
+       }
+
+       ret = generic_phy_init(&phy);
+       if (ret) {
+               error("unable to initialize the sata phy\n");
+               return ret;
+       }
+
+       ret = generic_phy_power_on(&phy);
+       if (ret) {
+               error("unable to power on the sata phy\n");
+               return ret;
+       }
+
+       if (priv->wrapper_base) {
+               u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
+
+               /* Enable SATA module, No Idle, No Standby */
+               writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
+       }
+
+       return ahci_init(priv->base);
+}
+
+static const struct udevice_id dwc_ahci_ids[] = {
+       { .compatible = "snps,dwc-ahci" },
+       { }
+};
+
+U_BOOT_DRIVER(dwc_ahci) = {
+       .name   = "dwc_ahci",
+       .id     = UCLASS_SCSI,
+       .of_match = dwc_ahci_ids,
+       .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata,
+       .probe  = dwc_ahci_probe,
+       .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
+       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
+       .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c
new file mode 100644 (file)
index 0000000..c306e92
--- /dev/null
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Terry Lv <r65388@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <libata.h>
+#include <ahci.h>
+#include <fis.h>
+#include <sata.h>
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include "dwc_ahsata.h"
+
+struct sata_port_regs {
+       u32 clb;
+       u32 clbu;
+       u32 fb;
+       u32 fbu;
+       u32 is;
+       u32 ie;
+       u32 cmd;
+       u32 res1[1];
+       u32 tfd;
+       u32 sig;
+       u32 ssts;
+       u32 sctl;
+       u32 serr;
+       u32 sact;
+       u32 ci;
+       u32 sntf;
+       u32 res2[1];
+       u32 dmacr;
+       u32 res3[1];
+       u32 phycr;
+       u32 physr;
+};
+
+struct sata_host_regs {
+       u32 cap;
+       u32 ghc;
+       u32 is;
+       u32 pi;
+       u32 vs;
+       u32 ccc_ctl;
+       u32 ccc_ports;
+       u32 res1[2];
+       u32 cap2;
+       u32 res2[30];
+       u32 bistafr;
+       u32 bistcr;
+       u32 bistfctr;
+       u32 bistsr;
+       u32 bistdecr;
+       u32 res3[2];
+       u32 oobr;
+       u32 res4[8];
+       u32 timer1ms;
+       u32 res5[1];
+       u32 gparam1r;
+       u32 gparam2r;
+       u32 pparamr;
+       u32 testr;
+       u32 versionr;
+       u32 idr;
+};
+
+#define MAX_DATA_BYTES_PER_SG  (4 * 1024 * 1024)
+#define MAX_BYTES_PER_TRANS (AHCI_MAX_SG * MAX_DATA_BYTES_PER_SG)
+
+#define writel_with_flush(a, b)        do { writel(a, b); readl(b); } while (0)
+
+static int is_ready;
+
+static inline void __iomem *ahci_port_base(void __iomem *base, u32 port)
+{
+       return base + 0x100 + (port * 0x80);
+}
+
+static int waiting_for_cmd_completed(u8 *offset,
+                                       int timeout_msec,
+                                       u32 sign)
+{
+       int i;
+       u32 status;
+
+       for (i = 0;
+               ((status = readl(offset)) & sign) && i < timeout_msec;
+               ++i)
+               mdelay(1);
+
+       return (i < timeout_msec) ? 0 : -1;
+}
+
+static int ahci_setup_oobr(struct ahci_probe_ent *probe_ent,
+                                               int clk)
+{
+       struct sata_host_regs *host_mmio =
+               (struct sata_host_regs *)probe_ent->mmio_base;
+
+       writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr));
+       writel(0x02060b14, &(host_mmio->oobr));
+
+       return 0;
+}
+
+static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+{
+       u32 tmp, cap_save, num_ports;
+       int i, j, timeout = 1000;
+       struct sata_port_regs *port_mmio = NULL;
+       struct sata_host_regs *host_mmio =
+               (struct sata_host_regs *)probe_ent->mmio_base;
+       int clk = mxc_get_clock(MXC_SATA_CLK);
+
+       cap_save = readl(&(host_mmio->cap));
+       cap_save |= SATA_HOST_CAP_SSS;
+
+       /* global controller reset */
+       tmp = readl(&(host_mmio->ghc));
+       if ((tmp & SATA_HOST_GHC_HR) == 0)
+               writel_with_flush(tmp | SATA_HOST_GHC_HR, &(host_mmio->ghc));
+
+       while ((readl(&(host_mmio->ghc)) & SATA_HOST_GHC_HR)
+               && --timeout)
+               ;
+
+       if (timeout <= 0) {
+               debug("controller reset failed (0x%x)\n", tmp);
+               return -1;
+       }
+
+       /* Set timer 1ms */
+       writel(clk / 1000, &(host_mmio->timer1ms));
+
+       ahci_setup_oobr(probe_ent, 0);
+
+       writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc));
+       writel(cap_save, &(host_mmio->cap));
+       num_ports = (cap_save & SATA_HOST_CAP_NP_MASK) + 1;
+       writel_with_flush((1 << num_ports) - 1,
+                               &(host_mmio->pi));
+
+       /*
+        * Determine which Ports are implemented by the DWC_ahsata,
+        * by reading the PI register. This bit map value aids the
+        * software to determine how many Ports are available and
+        * which Port registers need to be initialized.
+        */
+       probe_ent->cap = readl(&(host_mmio->cap));
+       probe_ent->port_map = readl(&(host_mmio->pi));
+
+       /* Determine how many command slots the HBA supports */
+       probe_ent->n_ports =
+               (probe_ent->cap & SATA_HOST_CAP_NP_MASK) + 1;
+
+       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
+               probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+
+       for (i = 0; i < probe_ent->n_ports; i++) {
+               probe_ent->port[i].port_mmio =
+                       ahci_port_base(host_mmio, i);
+               port_mmio =
+                       (struct sata_port_regs *)probe_ent->port[i].port_mmio;
+
+               /* Ensure that the DWC_ahsata is in idle state */
+               tmp = readl(&(port_mmio->cmd));
+
+               /*
+                * When P#CMD.ST, P#CMD.CR, P#CMD.FRE and P#CMD.FR
+                * are all cleared, the Port is in an idle state.
+                */
+               if (tmp & (SATA_PORT_CMD_CR | SATA_PORT_CMD_FR |
+                       SATA_PORT_CMD_FRE | SATA_PORT_CMD_ST)) {
+
+                       /*
+                        * System software places a Port into the idle state by
+                        * clearing P#CMD.ST and waiting for P#CMD.CR to return
+                        * 0 when read.
+                        */
+                       tmp &= ~SATA_PORT_CMD_ST;
+                       writel_with_flush(tmp, &(port_mmio->cmd));
+
+                       /*
+                        * spec says 500 msecs for each bit, so
+                        * this is slightly incorrect.
+                        */
+                       mdelay(500);
+
+                       timeout = 1000;
+                       while ((readl(&(port_mmio->cmd)) & SATA_PORT_CMD_CR)
+                               && --timeout)
+                               ;
+
+                       if (timeout <= 0) {
+                               debug("port reset failed (0x%x)\n", tmp);
+                               return -1;
+                       }
+               }
+
+               /* Spin-up device */
+               tmp = readl(&(port_mmio->cmd));
+               writel((tmp | SATA_PORT_CMD_SUD), &(port_mmio->cmd));
+
+               /* Wait for spin-up to finish */
+               timeout = 1000;
+               while (!(readl(&(port_mmio->cmd)) | SATA_PORT_CMD_SUD)
+                       && --timeout)
+                       ;
+               if (timeout <= 0) {
+                       debug("Spin-Up can't finish!\n");
+                       return -1;
+               }
+
+               for (j = 0; j < 100; ++j) {
+                       mdelay(10);
+                       tmp = readl(&(port_mmio->ssts));
+                       if (((tmp & SATA_PORT_SSTS_DET_MASK) == 0x3) ||
+                               ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x1))
+                               break;
+               }
+
+               /* Wait for COMINIT bit 26 (DIAG_X) in SERR */
+               timeout = 1000;
+               while (!(readl(&(port_mmio->serr)) | SATA_PORT_SERR_DIAG_X)
+                       && --timeout)
+                       ;
+               if (timeout <= 0) {
+                       debug("Can't find DIAG_X set!\n");
+                       return -1;
+               }
+
+               /*
+                * For each implemented Port, clear the P#SERR
+                * register, by writing ones to each implemented\
+                * bit location.
+                */
+               tmp = readl(&(port_mmio->serr));
+               debug("P#SERR 0x%x\n",
+                               tmp);
+               writel(tmp, &(port_mmio->serr));
+
+               /* Ack any pending irq events for this port */
+               tmp = readl(&(host_mmio->is));
+               debug("IS 0x%x\n", tmp);
+               if (tmp)
+                       writel(tmp, &(host_mmio->is));
+
+               writel(1 << i, &(host_mmio->is));
+
+               /* set irq mask (enables interrupts) */
+               writel(DEF_PORT_IRQ, &(port_mmio->ie));
+
+               /* register linkup ports */
+               tmp = readl(&(port_mmio->ssts));
+               debug("Port %d status: 0x%x\n", i, tmp);
+               if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03)
+                       probe_ent->link_port_map |= (0x01 << i);
+       }
+
+       tmp = readl(&(host_mmio->ghc));
+       debug("GHC 0x%x\n", tmp);
+       writel(tmp | SATA_HOST_GHC_IE, &(host_mmio->ghc));
+       tmp = readl(&(host_mmio->ghc));
+       debug("GHC 0x%x\n", tmp);
+
+       return 0;
+}
+
+static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+{
+       struct sata_host_regs *host_mmio =
+               (struct sata_host_regs *)probe_ent->mmio_base;
+       u32 vers, cap, impl, speed;
+       const char *speed_s;
+       const char *scc_s;
+
+       vers = readl(&(host_mmio->vs));
+       cap = probe_ent->cap;
+       impl = probe_ent->port_map;
+
+       speed = (cap & SATA_HOST_CAP_ISS_MASK)
+               >> SATA_HOST_CAP_ISS_OFFSET;
+       if (speed == 1)
+               speed_s = "1.5";
+       else if (speed == 2)
+               speed_s = "3";
+       else
+               speed_s = "?";
+
+       scc_s = "SATA";
+
+       printf("AHCI %02x%02x.%02x%02x "
+               "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
+               (vers >> 24) & 0xff,
+               (vers >> 16) & 0xff,
+               (vers >> 8) & 0xff,
+               vers & 0xff,
+               ((cap >> 8) & 0x1f) + 1,
+               (cap & 0x1f) + 1,
+               speed_s,
+               impl,
+               scc_s);
+
+       printf("flags: "
+               "%s%s%s%s%s%s"
+               "%s%s%s%s%s%s%s\n",
+               cap & (1 << 31) ? "64bit " : "",
+               cap & (1 << 30) ? "ncq " : "",
+               cap & (1 << 28) ? "ilck " : "",
+               cap & (1 << 27) ? "stag " : "",
+               cap & (1 << 26) ? "pm " : "",
+               cap & (1 << 25) ? "led " : "",
+               cap & (1 << 24) ? "clo " : "",
+               cap & (1 << 19) ? "nz " : "",
+               cap & (1 << 18) ? "only " : "",
+               cap & (1 << 17) ? "pmp " : "",
+               cap & (1 << 15) ? "pio " : "",
+               cap & (1 << 14) ? "slum " : "",
+               cap & (1 << 13) ? "part " : "");
+}
+
+static int ahci_init_one(int pdev)
+{
+       int rc;
+       struct ahci_probe_ent *probe_ent = NULL;
+
+       probe_ent = malloc(sizeof(struct ahci_probe_ent));
+       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+       probe_ent->dev = pdev;
+
+       probe_ent->host_flags = ATA_FLAG_SATA
+                               | ATA_FLAG_NO_LEGACY
+                               | ATA_FLAG_MMIO
+                               | ATA_FLAG_PIO_DMA
+                               | ATA_FLAG_NO_ATAPI;
+
+       probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR;
+
+       /* initialize adapter */
+       rc = ahci_host_init(probe_ent);
+       if (rc)
+               goto err_out;
+
+       ahci_print_info(probe_ent);
+
+       /* Save the private struct to block device struct */
+       sata_dev_desc[pdev].priv = (void *)probe_ent;
+
+       return 0;
+
+err_out:
+       return rc;
+}
+
+static int ahci_fill_sg(struct ahci_probe_ent *probe_ent,
+                       u8 port, unsigned char *buf, int buf_len)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
+       u32 sg_count, max_bytes;
+       int i;
+
+       max_bytes = MAX_DATA_BYTES_PER_SG;
+       sg_count = ((buf_len - 1) / max_bytes) + 1;
+       if (sg_count > AHCI_MAX_SG) {
+               printf("Error:Too much sg!\n");
+               return -1;
+       }
+
+       for (i = 0; i < sg_count; i++) {
+               ahci_sg->addr =
+                       cpu_to_le32((u32)buf + i * max_bytes);
+               ahci_sg->addr_hi = 0;
+               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
+                                       (buf_len < max_bytes
+                                       ? (buf_len - 1)
+                                       : (max_bytes - 1)));
+               ahci_sg++;
+               buf_len -= max_bytes;
+       }
+
+       return sg_count;
+}
+
+static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts)
+{
+       struct ahci_cmd_hdr *cmd_hdr = (struct ahci_cmd_hdr *)(pp->cmd_slot +
+                                       AHCI_CMD_SLOT_SZ * cmd_slot);
+
+       memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ);
+       cmd_hdr->opts = cpu_to_le32(opts);
+       cmd_hdr->status = 0;
+       pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff);
+#ifdef CONFIG_PHYS_64BIT
+       pp->cmd_slot->tbl_addr_hi =
+           cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16));
+#endif
+}
+
+#define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0)
+
+static int ahci_exec_ata_cmd(struct ahci_probe_ent *probe_ent,
+               u8 port, struct sata_fis_h2d *cfis,
+               u8 *buf, u32 buf_len, s32 is_write)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct sata_port_regs *port_mmio =
+                       (struct sata_port_regs *)pp->port_mmio;
+       u32 opts;
+       int sg_count = 0, cmd_slot = 0;
+
+       cmd_slot = AHCI_GET_CMD_SLOT(readl(&(port_mmio->ci)));
+       if (32 == cmd_slot) {
+               printf("Can't find empty command slot!\n");
+               return 0;
+       }
+
+       /* Check xfer length */
+       if (buf_len > MAX_BYTES_PER_TRANS) {
+               printf("Max transfer length is %dB\n\r",
+                       MAX_BYTES_PER_TRANS);
+               return 0;
+       }
+
+       memcpy((u8 *)(pp->cmd_tbl), cfis, sizeof(struct sata_fis_h2d));
+       if (buf && buf_len)
+               sg_count = ahci_fill_sg(probe_ent, port, buf, buf_len);
+       opts = (sizeof(struct sata_fis_h2d) >> 2) | (sg_count << 16);
+       if (is_write) {
+               opts |= 0x40;
+               flush_cache((ulong)buf, buf_len);
+       }
+       ahci_fill_cmd_slot(pp, cmd_slot, opts);
+
+       flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ);
+       writel_with_flush(1 << cmd_slot, &(port_mmio->ci));
+
+       if (waiting_for_cmd_completed((u8 *)&(port_mmio->ci),
+                               10000, 0x1 << cmd_slot)) {
+               printf("timeout exit!\n");
+               return -1;
+       }
+       invalidate_dcache_range((int)(pp->cmd_slot),
+                               (int)(pp->cmd_slot)+AHCI_PORT_PRIV_DMA_SZ);
+       debug("ahci_exec_ata_cmd: %d byte transferred.\n",
+             pp->cmd_slot->status);
+       if (!is_write)
+               invalidate_dcache_range((ulong)buf, (ulong)buf+buf_len);
+
+       return buf_len;
+}
+
+static void ahci_set_feature(u8 dev, u8 port)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 1 << 7;
+       cfis->command = ATA_CMD_SET_FEATURES;
+       cfis->features = SETFEATURES_XFER;
+       cfis->sector_count = ffs(probe_ent->udma_mask + 1) + 0x3e;
+
+       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD);
+}
+
+static int ahci_port_start(struct ahci_probe_ent *probe_ent,
+                                       u8 port)
+{
+       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct sata_port_regs *port_mmio =
+               (struct sata_port_regs *)pp->port_mmio;
+       u32 port_status;
+       u32 mem;
+       int timeout = 10000000;
+
+       debug("Enter start port: %d\n", port);
+       port_status = readl(&(port_mmio->ssts));
+       debug("Port %d status: %x\n", port, port_status);
+       if ((port_status & 0xf) != 0x03) {
+               printf("No Link on this port!\n");
+               return -1;
+       }
+
+       mem = (u32)malloc(AHCI_PORT_PRIV_DMA_SZ + 1024);
+       if (!mem) {
+               free(pp);
+               printf("No mem for table!\n");
+               return -ENOMEM;
+       }
+
+       mem = (mem + 0x400) & (~0x3ff); /* Aligned to 1024-bytes */
+       memset((u8 *)mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+
+       /*
+        * First item in chunk of DMA memory: 32-slot command table,
+        * 32 bytes each in size
+        */
+       pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
+       debug("cmd_slot = 0x%x\n", (unsigned int) pp->cmd_slot);
+       mem += (AHCI_CMD_SLOT_SZ * DWC_AHSATA_MAX_CMD_SLOTS);
+
+       /*
+        * Second item: Received-FIS area, 256-Byte aligned
+        */
+       pp->rx_fis = mem;
+       mem += AHCI_RX_FIS_SZ;
+
+       /*
+        * Third item: data area for storing a single command
+        * and its scatter-gather table
+        */
+       pp->cmd_tbl = mem;
+       debug("cmd_tbl_dma = 0x%lx\n", pp->cmd_tbl);
+
+       mem += AHCI_CMD_TBL_HDR;
+
+       writel_with_flush(0x00004444, &(port_mmio->dmacr));
+       pp->cmd_tbl_sg = (struct ahci_sg *)mem;
+       writel_with_flush((u32)pp->cmd_slot, &(port_mmio->clb));
+       writel_with_flush(pp->rx_fis, &(port_mmio->fb));
+
+       /* Enable FRE */
+       writel_with_flush((SATA_PORT_CMD_FRE | readl(&(port_mmio->cmd))),
+                       &(port_mmio->cmd));
+
+       /* Wait device ready */
+       while ((readl(&(port_mmio->tfd)) & (SATA_PORT_TFD_STS_ERR |
+               SATA_PORT_TFD_STS_DRQ | SATA_PORT_TFD_STS_BSY))
+               && --timeout)
+               ;
+       if (timeout <= 0) {
+               debug("Device not ready for BSY, DRQ and"
+                       "ERR in TFD!\n");
+               return -1;
+       }
+
+       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+                         PORT_CMD_START, &(port_mmio->cmd));
+
+       debug("Exit start port %d\n", port);
+
+       return 0;
+}
+
+int init_sata(int dev)
+{
+       int i;
+       u32 linkmap;
+       struct ahci_probe_ent *probe_ent = NULL;
+
+#if defined(CONFIG_MX6)
+       if (!is_mx6dq() && !is_mx6dqp())
+               return 1;
+#endif
+       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
+               printf("The sata index %d is out of ranges\n\r", dev);
+               return -1;
+       }
+
+       ahci_init_one(dev);
+
+       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       linkmap = probe_ent->link_port_map;
+
+       if (0 == linkmap) {
+               printf("No port device detected!\n");
+               return 1;
+       }
+
+       for (i = 0; i < probe_ent->n_ports; i++) {
+               if ((linkmap >> i) && ((linkmap >> i) & 0x01)) {
+                       if (ahci_port_start(probe_ent, (u8)i)) {
+                               printf("Can not start port %d\n", i);
+                               return 1;
+                       }
+                       probe_ent->hard_port_no = i;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       struct ahci_probe_ent *probe_ent;
+       struct sata_host_regs *host_mmio;
+
+       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
+               printf("The sata index %d is out of ranges\n\r", dev);
+               return -1;
+       }
+
+       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       if (NULL == probe_ent)
+               /* not initialized, so nothing to reset */
+               return 0;
+
+       host_mmio = (struct sata_host_regs *)probe_ent->mmio_base;
+       setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR);
+       while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR)
+               udelay(100);
+
+       return 0;
+}
+
+static void dwc_ahsata_print_info(int dev)
+{
+       struct blk_desc *pdev = &(sata_dev_desc[dev]);
+
+       printf("SATA Device Info:\n\r");
+#ifdef CONFIG_SYS_64BIT_LBA
+       printf("S/N: %s\n\rProduct model number: %s\n\r"
+               "Firmware version: %s\n\rCapacity: %lld sectors\n\r",
+               pdev->product, pdev->vendor, pdev->revision, pdev->lba);
+#else
+       printf("S/N: %s\n\rProduct model number: %s\n\r"
+               "Firmware version: %s\n\rCapacity: %ld sectors\n\r",
+               pdev->product, pdev->vendor, pdev->revision, pdev->lba);
+#endif
+}
+
+static void dwc_ahsata_identify(int dev, u16 *id)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_ID_ATA;
+
+       ahci_exec_ata_cmd(probe_ent, port, cfis,
+                       (u8 *)id, ATA_ID_WORDS * 2, READ_CMD);
+       ata_swap_buf_le16(id, ATA_ID_WORDS);
+}
+
+static void dwc_ahsata_xfer_mode(int dev, u16 *id)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+
+       probe_ent->pio_mask = id[ATA_ID_PIO_MODES];
+       probe_ent->udma_mask = id[ATA_ID_UDMA_MODES];
+       debug("pio %04x, udma %04x\n\r",
+               probe_ent->pio_mask, probe_ent->udma_mask);
+}
+
+static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt,
+                               u8 *buffer, int is_write)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+       u32 block;
+
+       block = start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
+       cfis->device = ATA_LBA;
+
+       cfis->device |= (block >> 24) & 0xf;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+       cfis->sector_count = (u8)(blkcnt & 0xff);
+
+       if (ahci_exec_ata_cmd(probe_ent, port, cfis,
+                       buffer, ATA_SECT_SIZE * blkcnt, is_write) > 0)
+               return blkcnt;
+       else
+               return 0;
+}
+
+void dwc_ahsata_flush_cache(int dev)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_FLUSH;
+
+       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
+}
+
+static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt,
+                               u8 *buffer, int is_write)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+       u64 block;
+
+       block = (u64)start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+
+       cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
+                                : ATA_CMD_READ_EXT;
+
+       cfis->lba_high_exp = (block >> 40) & 0xff;
+       cfis->lba_mid_exp = (block >> 32) & 0xff;
+       cfis->lba_low_exp = (block >> 24) & 0xff;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+       cfis->device = ATA_LBA;
+       cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
+       cfis->sector_count = blkcnt & 0xff;
+
+       if (ahci_exec_ata_cmd(probe_ent, port, cfis, buffer,
+                       ATA_SECT_SIZE * blkcnt, is_write) > 0)
+               return blkcnt;
+       else
+               return 0;
+}
+
+u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt,
+                               u8 *buffer, int is_write)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+       u64 block;
+
+       if (sata_dev_desc[dev].lba48 != 1) {
+               printf("execute FPDMA command on non-LBA48 hard disk\n\r");
+               return -1;
+       }
+
+       block = (u64)start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+
+       cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
+                                : ATA_CMD_FPDMA_READ;
+
+       cfis->lba_high_exp = (block >> 40) & 0xff;
+       cfis->lba_mid_exp = (block >> 32) & 0xff;
+       cfis->lba_low_exp = (block >> 24) & 0xff;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+
+       cfis->device = ATA_LBA;
+       cfis->features_exp = (blkcnt >> 8) & 0xff;
+       cfis->features = blkcnt & 0xff;
+
+       /* Use the latest queue */
+       ahci_exec_ata_cmd(probe_ent, port, cfis,
+                       buffer, ATA_SECT_SIZE * blkcnt, is_write);
+
+       return blkcnt;
+}
+
+void dwc_ahsata_flush_cache_ext(int dev)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
+       struct sata_fis_h2d *cfis = &h2d;
+       u8 port = probe_ent->hard_port_no;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_FLUSH_EXT;
+
+       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
+}
+
+static void dwc_ahsata_init_wcache(int dev, u16 *id)
+{
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+
+       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
+               probe_ent->flags |= SATA_FLAG_WCACHE;
+       if (ata_id_has_flush(id))
+               probe_ent->flags |= SATA_FLAG_FLUSH;
+       if (ata_id_has_flush_ext(id))
+               probe_ent->flags |= SATA_FLAG_FLUSH_EXT;
+}
+
+u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
+                               const void *buffer, int is_write)
+{
+       u32 start, blks;
+       u8 *addr;
+       int max_blks;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS_LBA48;
+
+       do {
+               if (blks > max_blks) {
+                       if (max_blks != dwc_ahsata_rw_cmd_ext(dev, start,
+                                               max_blks, addr, is_write))
+                               return 0;
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       if (blks != dwc_ahsata_rw_cmd_ext(dev, start,
+                                               blks, addr, is_write))
+                               return 0;
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt,
+                               const void *buffer, int is_write)
+{
+       u32 start, blks;
+       u8 *addr;
+       int max_blks;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS;
+       do {
+               if (blks > max_blks) {
+                       if (max_blks != dwc_ahsata_rw_cmd(dev, start,
+                                               max_blks, addr, is_write))
+                               return 0;
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       if (blks != dwc_ahsata_rw_cmd(dev, start,
+                                               blks, addr, is_write))
+                               return 0;
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+int sata_port_status(int dev, int port)
+{
+       struct sata_port_regs *port_mmio;
+       struct ahci_probe_ent *probe_ent = NULL;
+
+       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1))
+               return -EINVAL;
+
+       if (sata_dev_desc[dev].priv == NULL)
+               return -ENODEV;
+
+       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio;
+
+       return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       u32 rc;
+
+       if (sata_dev_desc[dev].lba48)
+               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
+                                               buffer, READ_CMD);
+       else
+               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
+                                               buffer, READ_CMD);
+       return rc;
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       u32 rc;
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       u32 flags = probe_ent->flags;
+
+       if (sata_dev_desc[dev].lba48) {
+               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
+                                               buffer, WRITE_CMD);
+               if ((flags & SATA_FLAG_WCACHE) &&
+                       (flags & SATA_FLAG_FLUSH_EXT))
+                       dwc_ahsata_flush_cache_ext(dev);
+       } else {
+               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
+                                               buffer, WRITE_CMD);
+               if ((flags & SATA_FLAG_WCACHE) &&
+                       (flags & SATA_FLAG_FLUSH))
+                       dwc_ahsata_flush_cache(dev);
+       }
+       return rc;
+}
+
+int scan_sata(int dev)
+{
+       u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 };
+       u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 };
+       u8 product[ATA_ID_PROD_LEN + 1] = { 0 };
+       u16 *id;
+       u64 n_sectors;
+       struct ahci_probe_ent *probe_ent =
+               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       u8 port = probe_ent->hard_port_no;
+       struct blk_desc *pdev = &(sata_dev_desc[dev]);
+
+       id = (u16 *)memalign(ARCH_DMA_MINALIGN,
+                               roundup(ARCH_DMA_MINALIGN,
+                                       (ATA_ID_WORDS * 2)));
+       if (!id) {
+               printf("id malloc failed\n\r");
+               return -1;
+       }
+
+       /* Identify device to get information */
+       dwc_ahsata_identify(dev, id);
+
+       /* Serial number */
+       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+       memcpy(pdev->product, serial, sizeof(serial));
+
+       /* Firmware version */
+       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+       memcpy(pdev->revision, firmware, sizeof(firmware));
+
+       /* Product model */
+       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+       memcpy(pdev->vendor, product, sizeof(product));
+
+       /* Totoal sectors */
+       n_sectors = ata_id_n_sectors(id);
+       pdev->lba = (u32)n_sectors;
+
+       pdev->type = DEV_TYPE_HARDDISK;
+       pdev->blksz = ATA_SECT_SIZE;
+       pdev->lun = 0 ;
+
+       /* Check if support LBA48 */
+       if (ata_id_has_lba48(id)) {
+               pdev->lba48 = 1;
+               debug("Device support LBA48\n\r");
+       }
+
+       /* Get the NCQ queue depth from device */
+       probe_ent->flags &= (~SATA_FLAG_Q_DEP_MASK);
+       probe_ent->flags |= ata_id_queue_depth(id);
+
+       /* Get the xfer mode from device */
+       dwc_ahsata_xfer_mode(dev, id);
+
+       /* Get the write cache status from device */
+       dwc_ahsata_init_wcache(dev, id);
+
+       /* Set the xfer mode to highest speed */
+       ahci_set_feature(dev, port);
+
+       free((void *)id);
+
+       dwc_ahsata_print_info(dev);
+
+       is_ready = 1;
+
+       return 0;
+}
diff --git a/drivers/ata/dwc_ahsata.h b/drivers/ata/dwc_ahsata.h
new file mode 100644 (file)
index 0000000..caa2e50
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ * Terry Lv <r65388@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __FSL_SATA_H__
+#define __FSL_SATA_H__
+
+#define DWC_AHSATA_MAX_CMD_SLOTS       32
+
+/* Max host controller numbers */
+#define SATA_HC_MAX_NUM                4
+/* Max command queue depth per host controller */
+#define DWC_AHSATA_HC_MAX_CMD  32
+/* Max port number per host controller */
+#define SATA_HC_MAX_PORT       16
+
+/* Generic Host Register */
+
+/* HBA Capabilities Register */
+#define SATA_HOST_CAP_S64A             0x80000000
+#define SATA_HOST_CAP_SNCQ             0x40000000
+#define SATA_HOST_CAP_SSNTF            0x20000000
+#define SATA_HOST_CAP_SMPS             0x10000000
+#define SATA_HOST_CAP_SSS              0x08000000
+#define SATA_HOST_CAP_SALP             0x04000000
+#define SATA_HOST_CAP_SAL              0x02000000
+#define SATA_HOST_CAP_SCLO             0x01000000
+#define SATA_HOST_CAP_ISS_MASK         0x00f00000
+#define SATA_HOST_CAP_ISS_OFFSET       20
+#define SATA_HOST_CAP_SNZO             0x00080000
+#define SATA_HOST_CAP_SAM              0x00040000
+#define SATA_HOST_CAP_SPM              0x00020000
+#define SATA_HOST_CAP_PMD              0x00008000
+#define SATA_HOST_CAP_SSC              0x00004000
+#define SATA_HOST_CAP_PSC              0x00002000
+#define SATA_HOST_CAP_NCS              0x00001f00
+#define SATA_HOST_CAP_CCCS             0x00000080
+#define SATA_HOST_CAP_EMS              0x00000040
+#define SATA_HOST_CAP_SXS              0x00000020
+#define SATA_HOST_CAP_NP_MASK          0x0000001f
+
+/* Global HBA Control Register */
+#define SATA_HOST_GHC_AE       0x80000000
+#define SATA_HOST_GHC_IE       0x00000002
+#define SATA_HOST_GHC_HR       0x00000001
+
+/* Interrupt Status Register */
+
+/* Ports Implemented Register */
+
+/* AHCI Version Register */
+#define SATA_HOST_VS_MJR_MASK  0xffff0000
+#define SATA_HOST_VS_MJR_OFFSET        16
+#define SATA_HOST_VS_MJR_MNR   0x0000ffff
+
+/* Command Completion Coalescing Control */
+#define SATA_HOST_CCC_CTL_TV_MASK      0xffff0000
+#define SATA_HOST_CCC_CTL_TV_OFFSET            16
+#define SATA_HOST_CCC_CTL_CC_MASK      0x0000ff00
+#define SATA_HOST_CCC_CTL_CC_OFFSET            8
+#define SATA_HOST_CCC_CTL_INT_MASK     0x000000f8
+#define SATA_HOST_CCC_CTL_INT_OFFSET   3
+#define SATA_HOST_CCC_CTL_EN   0x00000001
+
+/* Command Completion Coalescing Ports */
+
+/* HBA Capabilities Extended Register */
+#define SATA_HOST_CAP2_APST            0x00000004
+
+/* BIST Activate FIS Register */
+#define SATA_HOST_BISTAFR_NCP_MASK     0x0000ff00
+#define SATA_HOST_BISTAFR_NCP_OFFSET   8
+#define SATA_HOST_BISTAFR_PD_MASK      0x000000ff
+#define SATA_HOST_BISTAFR_PD_OFFSET            0
+
+/* BIST Control Register */
+#define SATA_HOST_BISTCR_FERLB 0x00100000
+#define SATA_HOST_BISTCR_TXO   0x00040000
+#define SATA_HOST_BISTCR_CNTCLR        0x00020000
+#define SATA_HOST_BISTCR_NEALB 0x00010000
+#define SATA_HOST_BISTCR_LLC_MASK      0x00000700
+#define SATA_HOST_BISTCR_LLC_OFFSET    8
+#define SATA_HOST_BISTCR_ERREN 0x00000040
+#define SATA_HOST_BISTCR_FLIP  0x00000020
+#define SATA_HOST_BISTCR_PV            0x00000010
+#define SATA_HOST_BISTCR_PATTERN_MASK  0x0000000f
+#define SATA_HOST_BISTCR_PATTERN_OFFSET        0
+
+/* BIST FIS Count Register */
+
+/* BIST Status Register */
+#define SATA_HOST_BISTSR_FRAMERR_MASK  0x0000ffff
+#define SATA_HOST_BISTSR_FRAMERR_OFFSET        0
+#define SATA_HOST_BISTSR_BRSTERR_MASK  0x00ff0000
+#define SATA_HOST_BISTSR_BRSTERR_OFFSET        16
+
+/* BIST DWORD Error Count Register */
+
+/* OOB Register*/
+#define SATA_HOST_OOBR_WE              0x80000000
+#define SATA_HOST_OOBR_cwMin_MASK      0x7f000000
+#define SATA_HOST_OOBR_cwMAX_MASK      0x00ff0000
+#define SATA_HOST_OOBR_ciMin_MASK      0x0000ff00
+#define SATA_HOST_OOBR_ciMax_MASK      0x000000ff
+
+/* Timer 1-ms Register */
+
+/* Global Parameter 1 Register */
+#define SATA_HOST_GPARAM1R_ALIGN_M     0x80000000
+#define SATA_HOST_GPARAM1R_RX_BUFFER   0x40000000
+#define SATA_HOST_GPARAM1R_PHY_DATA_MASK       0x30000000
+#define SATA_HOST_GPARAM1R_PHY_RST     0x08000000
+#define SATA_HOST_GPARAM1R_PHY_CTRL_MASK       0x07e00000
+#define SATA_HOST_GPARAM1R_PHY_STAT_MASK       0x001f8000
+#define SATA_HOST_GPARAM1R_LATCH_M     0x00004000
+#define SATA_HOST_GPARAM1R_BIST_M      0x00002000
+#define SATA_HOST_GPARAM1R_PHY_TYPE    0x00001000
+#define SATA_HOST_GPARAM1R_RETURN_ERR  0x00000400
+#define SATA_HOST_GPARAM1R_AHB_ENDIAN_MASK     0x00000300
+#define SATA_HOST_GPARAM1R_S_HADDR     0X00000080
+#define SATA_HOST_GPARAM1R_M_HADDR     0X00000040
+
+/* Global Parameter 2 Register */
+#define SATA_HOST_GPARAM2R_DEV_CP      0x00004000
+#define SATA_HOST_GPARAM2R_DEV_MP      0x00002000
+#define SATA_HOST_GPARAM2R_DEV_ENCODE_M        0x00001000
+#define SATA_HOST_GPARAM2R_RXOOB_CLK_M 0x00000800
+#define SATA_HOST_GPARAM2R_RXOOB_M     0x00000400
+#define SATA_HOST_GPARAM2R_TX_OOB_M    0x00000200
+#define SATA_HOST_GPARAM2R_RXOOB_CLK_MASK      0x000001ff
+
+/* Port Parameter Register */
+#define SATA_HOST_PPARAMR_TX_MEM_M     0x00000200
+#define SATA_HOST_PPARAMR_TX_MEM_S     0x00000100
+#define SATA_HOST_PPARAMR_RX_MEM_M     0x00000080
+#define SATA_HOST_PPARAMR_RX_MEM_S     0x00000040
+#define SATA_HOST_PPARAMR_TXFIFO_DEPTH_MASK    0x00000038
+#define SATA_HOST_PPARAMR_RXFIFO_DEPTH_MASK    0x00000007
+
+/* Test Register */
+#define SATA_HOST_TESTR_PSEL_MASK      0x00070000
+#define SATA_HOST_TESTR_TEST_IF                0x00000001
+
+/* Port Register Descriptions */
+/* Port# Command List Base Address Register */
+#define SATA_PORT_CLB_CLB_MASK         0xfffffc00
+
+/* Port# Command List Base Address Upper 32-Bits Register */
+
+/* Port# FIS Base Address Register */
+#define SATA_PORT_FB_FB_MASK           0xfffffff0
+
+/* Port# FIS Base Address Upper 32-Bits Register */
+
+/* Port# Interrupt Status Register */
+#define SATA_PORT_IS_CPDS              0x80000000
+#define SATA_PORT_IS_TFES              0x40000000
+#define SATA_PORT_IS_HBFS              0x20000000
+#define SATA_PORT_IS_HBDS              0x10000000
+#define SATA_PORT_IS_IFS               0x08000000
+#define SATA_PORT_IS_INFS              0x04000000
+#define SATA_PORT_IS_OFS               0x01000000
+#define SATA_PORT_IS_IPMS              0x00800000
+#define SATA_PORT_IS_PRCS              0x00400000
+#define SATA_PORT_IS_DMPS              0x00000080
+#define SATA_PORT_IS_PCS               0x00000040
+#define SATA_PORT_IS_DPS               0x00000020
+#define SATA_PORT_IS_UFS               0x00000010
+#define SATA_PORT_IS_SDBS              0x00000008
+#define SATA_PORT_IS_DSS               0x00000004
+#define SATA_PORT_IS_PSS               0x00000002
+#define SATA_PORT_IS_DHRS              0x00000001
+
+/* Port# Interrupt Enable Register */
+#define SATA_PORT_IE_CPDE              0x80000000
+#define SATA_PORT_IE_TFEE              0x40000000
+#define SATA_PORT_IE_HBFE              0x20000000
+#define SATA_PORT_IE_HBDE              0x10000000
+#define SATA_PORT_IE_IFE               0x08000000
+#define SATA_PORT_IE_INFE              0x04000000
+#define SATA_PORT_IE_OFE               0x01000000
+#define SATA_PORT_IE_IPME              0x00800000
+#define SATA_PORT_IE_PRCE              0x00400000
+#define SATA_PORT_IE_DMPE              0x00000080
+#define SATA_PORT_IE_PCE               0x00000040
+#define SATA_PORT_IE_DPE               0x00000020
+#define SATA_PORT_IE_UFE               0x00000010
+#define SATA_PORT_IE_SDBE              0x00000008
+#define SATA_PORT_IE_DSE               0x00000004
+#define SATA_PORT_IE_PSE               0x00000002
+#define SATA_PORT_IE_DHRE              0x00000001
+
+/* Port# Command Register */
+#define SATA_PORT_CMD_ICC_MASK         0xf0000000
+#define SATA_PORT_CMD_ASP              0x08000000
+#define SATA_PORT_CMD_ALPE             0x04000000
+#define SATA_PORT_CMD_DLAE             0x02000000
+#define SATA_PORT_CMD_ATAPI            0x01000000
+#define SATA_PORT_CMD_APSTE            0x00800000
+#define SATA_PORT_CMD_ESP              0x00200000
+#define SATA_PORT_CMD_CPD              0x00100000
+#define SATA_PORT_CMD_MPSP             0x00080000
+#define SATA_PORT_CMD_HPCP             0x00040000
+#define SATA_PORT_CMD_PMA              0x00020000
+#define SATA_PORT_CMD_CPS              0x00010000
+#define SATA_PORT_CMD_CR               0x00008000
+#define SATA_PORT_CMD_FR               0x00004000
+#define SATA_PORT_CMD_MPSS             0x00002000
+#define SATA_PORT_CMD_CCS_MASK         0x00001f00
+#define SATA_PORT_CMD_FRE              0x00000010
+#define SATA_PORT_CMD_CLO              0x00000008
+#define SATA_PORT_CMD_POD              0x00000004
+#define SATA_PORT_CMD_SUD              0x00000002
+#define SATA_PORT_CMD_ST               0x00000001
+
+/* Port# Task File Data Register */
+#define SATA_PORT_TFD_ERR_MASK         0x0000ff00
+#define SATA_PORT_TFD_STS_MASK         0x000000ff
+#define SATA_PORT_TFD_STS_ERR          0x00000001
+#define SATA_PORT_TFD_STS_DRQ          0x00000008
+#define SATA_PORT_TFD_STS_BSY          0x00000080
+
+/* Port# Signature Register */
+
+/* Port# Serial ATA Status {SStatus} Register */
+#define SATA_PORT_SSTS_IPM_MASK                0x00000f00
+#define SATA_PORT_SSTS_SPD_MASK                0x000000f0
+#define SATA_PORT_SSTS_DET_MASK                0x0000000f
+
+/* Port# Serial ATA Control {SControl} Register */
+#define SATA_PORT_SCTL_IPM_MASK                0x00000f00
+#define SATA_PORT_SCTL_SPD_MASK                0x000000f0
+#define SATA_PORT_SCTL_DET_MASK                0x0000000f
+
+/* Port# Serial ATA Error {SError} Register */
+#define SATA_PORT_SERR_DIAG_X          0x04000000
+#define SATA_PORT_SERR_DIAG_F          0x02000000
+#define SATA_PORT_SERR_DIAG_T          0x01000000
+#define SATA_PORT_SERR_DIAG_S          0x00800000
+#define SATA_PORT_SERR_DIAG_H          0x00400000
+#define SATA_PORT_SERR_DIAG_C          0x00200000
+#define SATA_PORT_SERR_DIAG_D          0x00100000
+#define SATA_PORT_SERR_DIAG_B          0x00080000
+#define SATA_PORT_SERR_DIAG_W          0x00040000
+#define SATA_PORT_SERR_DIAG_I          0x00020000
+#define SATA_PORT_SERR_DIAG_N          0x00010000
+#define SATA_PORT_SERR_ERR_E           0x00000800
+#define SATA_PORT_SERR_ERR_P           0x00000400
+#define SATA_PORT_SERR_ERR_C           0x00000200
+#define SATA_PORT_SERR_ERR_T           0x00000100
+#define SATA_PORT_SERR_ERR_M           0x00000002
+#define SATA_PORT_SERR_ERR_I           0x00000001
+
+/* Port# Serial ATA Active {SActive} Register */
+
+/* Port# Command Issue Register */
+
+/* Port# Serial ATA Notification Register */
+
+/* Port# DMA Control Register */
+#define SATA_PORT_DMACR_RXABL_MASK     0x0000f000
+#define SATA_PORT_DMACR_TXABL_MASK     0x00000f00
+#define SATA_PORT_DMACR_RXTS_MASK      0x000000f0
+#define SATA_PORT_DMACR_TXTS_MASK      0x0000000f
+
+/* Port# PHY Control Register */
+
+/* Port# PHY Status Register */
+
+#define SATA_HC_CMD_HDR_ENTRY_SIZE     sizeof(struct cmd_hdr_entry)
+
+/* DW0
+*/
+#define CMD_HDR_DI_CFL_MASK    0x0000001f
+#define CMD_HDR_DI_CFL_OFFSET  0
+#define CMD_HDR_DI_A                   0x00000020
+#define CMD_HDR_DI_W                   0x00000040
+#define CMD_HDR_DI_P                   0x00000080
+#define CMD_HDR_DI_R                   0x00000100
+#define CMD_HDR_DI_B                   0x00000200
+#define CMD_HDR_DI_C                   0x00000400
+#define CMD_HDR_DI_PMP_MASK    0x0000f000
+#define CMD_HDR_DI_PMP_OFFSET  12
+#define CMD_HDR_DI_PRDTL               0xffff0000
+#define CMD_HDR_DI_PRDTL_OFFSET        16
+
+/* prde_fis_len
+*/
+#define CMD_HDR_PRD_ENTRY_SHIFT        16
+#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
+#define CMD_HDR_FIS_LEN_SHIFT  2
+
+/* attribute
+*/
+#define CMD_HDR_ATTR_RES       0x00000800 /* Reserved bit, should be 1 */
+#define CMD_HDR_ATTR_VBIST     0x00000400 /* Vendor BIST */
+/* Snoop enable for all descriptor */
+#define CMD_HDR_ATTR_SNOOP     0x00000200
+#define CMD_HDR_ATTR_FPDMA     0x00000100 /* FPDMA queued command */
+#define CMD_HDR_ATTR_RESET     0x00000080 /* Reset - a SRST or device reset */
+/* BIST - require the host to enter BIST mode */
+#define CMD_HDR_ATTR_BIST      0x00000040
+#define CMD_HDR_ATTR_ATAPI     0x00000020 /* ATAPI command */
+#define CMD_HDR_ATTR_TAG       0x0000001f /* TAG mask */
+
+#define FLAGS_DMA      0x00000000
+#define FLAGS_FPDMA    0x00000001
+
+#define SATA_FLAG_Q_DEP_MASK   0x0000000f
+#define SATA_FLAG_WCACHE       0x00000100
+#define SATA_FLAG_FLUSH                0x00000200
+#define SATA_FLAG_FLUSH_EXT    0x00000400
+
+#define READ_CMD       0
+#define WRITE_CMD      1
+
+#endif /* __FSL_SATA_H__ */
diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c
new file mode 100644 (file)
index 0000000..31f7fab
--- /dev/null
@@ -0,0 +1,854 @@
+/*
+ * Copyright (C) 2008,2010 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/fsl_serdes.h>
+#include <malloc.h>
+#include <libata.h>
+#include <fis.h>
+#include <sata.h>
+#include "fsl_sata.h"
+
+#ifndef CONFIG_SYS_SATA1_FLAGS
+       #define CONFIG_SYS_SATA1_FLAGS  FLAGS_DMA
+#endif
+#ifndef CONFIG_SYS_SATA2_FLAGS
+       #define CONFIG_SYS_SATA2_FLAGS  FLAGS_DMA
+#endif
+
+static struct fsl_sata_info fsl_sata_info[] = {
+#ifdef CONFIG_SATA1
+       {CONFIG_SYS_SATA1, CONFIG_SYS_SATA1_FLAGS},
+#else
+       {0, 0},
+#endif
+#ifdef CONFIG_SATA2
+       {CONFIG_SYS_SATA2, CONFIG_SYS_SATA2_FLAGS},
+#else
+       {0, 0},
+#endif
+};
+
+static inline void sdelay(unsigned long sec)
+{
+       unsigned long i;
+       for (i = 0; i < sec; i++)
+               mdelay(1000);
+}
+
+static void fsl_sata_dump_sfis(struct sata_fis_d2h *s)
+{
+       printf("Status FIS dump:\n\r");
+       printf("fis_type:               %02x\n\r", s->fis_type);
+       printf("pm_port_i:              %02x\n\r", s->pm_port_i);
+       printf("status:                 %02x\n\r", s->status);
+       printf("error:                  %02x\n\r", s->error);
+       printf("lba_low:                %02x\n\r", s->lba_low);
+       printf("lba_mid:                %02x\n\r", s->lba_mid);
+       printf("lba_high:               %02x\n\r", s->lba_high);
+       printf("device:                 %02x\n\r", s->device);
+       printf("lba_low_exp:            %02x\n\r", s->lba_low_exp);
+       printf("lba_mid_exp:            %02x\n\r", s->lba_mid_exp);
+       printf("lba_high_exp:           %02x\n\r", s->lba_high_exp);
+       printf("res1:                   %02x\n\r", s->res1);
+       printf("sector_count:           %02x\n\r", s->sector_count);
+       printf("sector_count_exp:       %02x\n\r", s->sector_count_exp);
+}
+
+static int ata_wait_register(unsigned __iomem *addr, u32 mask,
+                        u32 val, u32 timeout_msec)
+{
+       int i;
+       u32 temp;
+
+       for (i = 0; (((temp = in_le32(addr)) & mask) != val)
+                        && i < timeout_msec; i++)
+               mdelay(1);
+       return (i < timeout_msec) ? 0 : -1;
+}
+
+int init_sata(int dev)
+{
+       u32 length, align;
+       cmd_hdr_tbl_t *cmd_hdr;
+       u32 cda;
+       u32 val32;
+       fsl_sata_reg_t __iomem *reg;
+       u32 sig;
+       int i;
+       fsl_sata_t *sata;
+
+       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
+               printf("the sata index %d is out of ranges\n\r", dev);
+               return -1;
+       }
+
+#ifdef CONFIG_MPC85xx
+       if ((dev == 0) && (!is_serdes_configured(SATA1))) {
+               printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
+               return -1;
+       }
+       if ((dev == 1) && (!is_serdes_configured(SATA2))) {
+               printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
+               return -1;
+       }
+#endif
+
+       /* Allocate SATA device driver struct */
+       sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t));
+       if (!sata) {
+               printf("alloc the sata device struct failed\n\r");
+               return -1;
+       }
+       /* Zero all of the device driver struct */
+       memset((void *)sata, 0, sizeof(fsl_sata_t));
+
+       /* Save the private struct to block device struct */
+       sata_dev_desc[dev].priv = (void *)sata;
+
+       snprintf(sata->name, 12, "SATA%d", dev);
+
+       /* Set the controller register base address to device struct */
+       reg = (fsl_sata_reg_t *)(fsl_sata_info[dev].sata_reg_base);
+       sata->reg_base = reg;
+
+       /* Allocate the command header table, 4 bytes aligned */
+       length = sizeof(struct cmd_hdr_tbl);
+       align = SATA_HC_CMD_HDR_TBL_ALIGN;
+       sata->cmd_hdr_tbl_offset = (void *)malloc(length + align);
+       if (!sata->cmd_hdr_tbl_offset) {
+               printf("alloc the command header failed\n\r");
+               return -1;
+       }
+
+       cmd_hdr = (cmd_hdr_tbl_t *)(((u32)sata->cmd_hdr_tbl_offset + align)
+                                               & ~(align - 1));
+       sata->cmd_hdr = cmd_hdr;
+
+       /* Zero all of the command header table */
+       memset((void *)sata->cmd_hdr_tbl_offset, 0, length + align);
+
+       /* Allocate command descriptor for all command */
+       length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD;
+       align = SATA_HC_CMD_DESC_ALIGN;
+       sata->cmd_desc_offset = (void *)malloc(length + align);
+       if (!sata->cmd_desc_offset) {
+               printf("alloc the command descriptor failed\n\r");
+               return -1;
+       }
+       sata->cmd_desc = (cmd_desc_t *)(((u32)sata->cmd_desc_offset + align)
+                                               & ~(align - 1));
+       /* Zero all of command descriptor */
+       memset((void *)sata->cmd_desc_offset, 0, length + align);
+
+       /* Link the command descriptor to command header */
+       for (i = 0; i < SATA_HC_MAX_CMD; i++) {
+               cda = ((u32)sata->cmd_desc + SATA_HC_CMD_DESC_SIZE * i)
+                                        & ~(CMD_HDR_CDA_ALIGN - 1);
+               cmd_hdr->cmd_slot[i].cda = cpu_to_le32(cda);
+       }
+
+       /* To have safe state, force the controller offline */
+       val32 = in_le32(&reg->hcontrol);
+       val32 &= ~HCONTROL_ONOFF;
+       val32 |= HCONTROL_FORCE_OFFLINE;
+       out_le32(&reg->hcontrol, val32);
+
+       /* Wait the controller offline */
+       ata_wait_register(&reg->hstatus, HSTATUS_ONOFF, 0, 1000);
+
+       /* Set the command header base address to CHBA register to tell DMA */
+       out_le32(&reg->chba, (u32)cmd_hdr & ~0x3);
+
+       /* Snoop for the command header */
+       val32 = in_le32(&reg->hcontrol);
+       val32 |= HCONTROL_HDR_SNOOP;
+       out_le32(&reg->hcontrol, val32);
+
+       /* Disable all of interrupts */
+       val32 = in_le32(&reg->hcontrol);
+       val32 &= ~HCONTROL_INT_EN_ALL;
+       out_le32(&reg->hcontrol, val32);
+
+       /* Clear all of interrupts */
+       val32 = in_le32(&reg->hstatus);
+       out_le32(&reg->hstatus, val32);
+
+       /* Set the ICC, no interrupt coalescing */
+       out_le32(&reg->icc, 0x01000000);
+
+       /* No PM attatched, the SATA device direct connect */
+       out_le32(&reg->cqpmp, 0);
+
+       /* Clear SError register */
+       val32 = in_le32(&reg->serror);
+       out_le32(&reg->serror, val32);
+
+       /* Clear CER register */
+       val32 = in_le32(&reg->cer);
+       out_le32(&reg->cer, val32);
+
+       /* Clear DER register */
+       val32 = in_le32(&reg->der);
+       out_le32(&reg->der, val32);
+
+       /* No device detection or initialization action requested */
+       out_le32(&reg->scontrol, 0x00000300);
+
+       /* Configure the transport layer, default value */
+       out_le32(&reg->transcfg, 0x08000016);
+
+       /* Configure the link layer, default value */
+       out_le32(&reg->linkcfg, 0x0000ff34);
+
+       /* Bring the controller online */
+       val32 = in_le32(&reg->hcontrol);
+       val32 |= HCONTROL_ONOFF;
+       out_le32(&reg->hcontrol, val32);
+
+       mdelay(100);
+
+       /* print sata device name */
+       if (!dev)
+               printf("%s ", sata->name);
+       else
+               printf("       %s ", sata->name);
+
+       /* Wait PHY RDY signal changed for 500ms */
+       ata_wait_register(&reg->hstatus, HSTATUS_PHY_RDY,
+                         HSTATUS_PHY_RDY, 500);
+
+       /* Check PHYRDY */
+       val32 = in_le32(&reg->hstatus);
+       if (val32 & HSTATUS_PHY_RDY) {
+               sata->link = 1;
+       } else {
+               sata->link = 0;
+               printf("(No RDY)\n\r");
+               return -1;
+       }
+
+       /* Wait for signature updated, which is 1st D2H */
+       ata_wait_register(&reg->hstatus, HSTATUS_SIGNATURE,
+                         HSTATUS_SIGNATURE, 10000);
+
+       if (val32 & HSTATUS_SIGNATURE) {
+               sig = in_le32(&reg->sig);
+               debug("Signature updated, the sig =%08x\n\r", sig);
+               sata->ata_device_type = ata_dev_classify(sig);
+       }
+
+       /* Check the speed */
+       val32 = in_le32(&reg->sstatus);
+       if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN1)
+               printf("(1.5 Gbps)\n\r");
+       else if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN2)
+               printf("(3 Gbps)\n\r");
+
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+static void fsl_sata_dump_regs(fsl_sata_reg_t __iomem *reg)
+{
+       printf("\n\rSATA:           %08x\n\r", (u32)reg);
+       printf("CQR:            %08x\n\r", in_le32(&reg->cqr));
+       printf("CAR:            %08x\n\r", in_le32(&reg->car));
+       printf("CCR:            %08x\n\r", in_le32(&reg->ccr));
+       printf("CER:            %08x\n\r", in_le32(&reg->cer));
+       printf("CQR:            %08x\n\r", in_le32(&reg->cqr));
+       printf("DER:            %08x\n\r", in_le32(&reg->der));
+       printf("CHBA:           %08x\n\r", in_le32(&reg->chba));
+       printf("HStatus:        %08x\n\r", in_le32(&reg->hstatus));
+       printf("HControl:       %08x\n\r", in_le32(&reg->hcontrol));
+       printf("CQPMP:          %08x\n\r", in_le32(&reg->cqpmp));
+       printf("SIG:            %08x\n\r", in_le32(&reg->sig));
+       printf("ICC:            %08x\n\r", in_le32(&reg->icc));
+       printf("SStatus:        %08x\n\r", in_le32(&reg->sstatus));
+       printf("SError:         %08x\n\r", in_le32(&reg->serror));
+       printf("SControl:       %08x\n\r", in_le32(&reg->scontrol));
+       printf("SNotification:  %08x\n\r", in_le32(&reg->snotification));
+       printf("TransCfg:       %08x\n\r", in_le32(&reg->transcfg));
+       printf("TransStatus:    %08x\n\r", in_le32(&reg->transstatus));
+       printf("LinkCfg:        %08x\n\r", in_le32(&reg->linkcfg));
+       printf("LinkCfg1:       %08x\n\r", in_le32(&reg->linkcfg1));
+       printf("LinkCfg2:       %08x\n\r", in_le32(&reg->linkcfg2));
+       printf("LinkStatus:     %08x\n\r", in_le32(&reg->linkstatus));
+       printf("LinkStatus1:    %08x\n\r", in_le32(&reg->linkstatus1));
+       printf("PhyCtrlCfg:     %08x\n\r", in_le32(&reg->phyctrlcfg));
+       printf("SYSPR:          %08x\n\r", in_be32(&reg->syspr));
+}
+
+static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
+                               int is_ncq, int tag, u8 *buffer, u32 len)
+{
+       cmd_hdr_entry_t *cmd_hdr;
+       cmd_desc_t *cmd_desc;
+       sata_fis_h2d_t *h2d;
+       prd_entry_t *prde;
+       u32 ext_c_ddc;
+       u32 prde_count;
+       u32 val32;
+       u32 ttl;
+       fsl_sata_reg_t __iomem *reg = sata->reg_base;
+       int i;
+
+       /* Check xfer length */
+       if (len > SATA_HC_MAX_XFER_LEN) {
+               printf("max transfer length is 64MB\n\r");
+               return 0;
+       }
+
+       /* Setup the command descriptor */
+       cmd_desc = sata->cmd_desc + tag;
+
+       /* Get the pointer cfis of command descriptor */
+       h2d = (sata_fis_h2d_t *)cmd_desc->cfis;
+
+       /* Zero the cfis of command descriptor */
+       memset((void *)h2d, 0, SATA_HC_CMD_DESC_CFIS_SIZE);
+
+       /* Copy the cfis from user to command descriptor */
+       h2d->fis_type = cfis->fis_type;
+       h2d->pm_port_c = cfis->pm_port_c;
+       h2d->command = cfis->command;
+
+       h2d->features = cfis->features;
+       h2d->features_exp = cfis->features_exp;
+
+       h2d->lba_low = cfis->lba_low;
+       h2d->lba_mid = cfis->lba_mid;
+       h2d->lba_high = cfis->lba_high;
+       h2d->lba_low_exp = cfis->lba_low_exp;
+       h2d->lba_mid_exp = cfis->lba_mid_exp;
+       h2d->lba_high_exp = cfis->lba_high_exp;
+
+       if (!is_ncq) {
+               h2d->sector_count = cfis->sector_count;
+               h2d->sector_count_exp = cfis->sector_count_exp;
+       } else { /* NCQ */
+               h2d->sector_count = (u8)(tag << 3);
+       }
+
+       h2d->device = cfis->device;
+       h2d->control = cfis->control;
+
+       /* Setup the PRD table */
+       prde = (prd_entry_t *)cmd_desc->prdt;
+       memset((void *)prde, 0, sizeof(struct prdt));
+
+       prde_count = 0;
+       ttl = len;
+       for (i = 0; i < SATA_HC_MAX_PRD_DIRECT; i++) {
+               if (!len)
+                       break;
+               prde->dba = cpu_to_le32((u32)buffer & ~0x3);
+               debug("dba = %08x\n\r", (u32)buffer);
+
+               if (len < PRD_ENTRY_MAX_XFER_SZ) {
+                       ext_c_ddc = PRD_ENTRY_DATA_SNOOP | len;
+                       debug("ext_c_ddc1 = %08x, len = %08x\n\r", ext_c_ddc, len);
+                       prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+                       prde_count++;
+                       prde++;
+                       break;
+               } else {
+                       ext_c_ddc = PRD_ENTRY_DATA_SNOOP; /* 4M bytes */
+                       debug("ext_c_ddc2 = %08x, len = %08x\n\r", ext_c_ddc, len);
+                       prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+                       buffer += PRD_ENTRY_MAX_XFER_SZ;
+                       len -= PRD_ENTRY_MAX_XFER_SZ;
+                       prde_count++;
+                       prde++;
+               }
+       }
+
+       /* Setup the command slot of cmd hdr */
+       cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
+
+       cmd_hdr->cda = cpu_to_le32((u32)cmd_desc & ~0x3);
+
+       val32 = prde_count << CMD_HDR_PRD_ENTRY_SHIFT;
+       val32 |= sizeof(sata_fis_h2d_t);
+       cmd_hdr->prde_fis_len = cpu_to_le32(val32);
+
+       cmd_hdr->ttl = cpu_to_le32(ttl);
+
+       if (!is_ncq) {
+               val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP;
+       } else {
+               val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP | CMD_HDR_ATTR_FPDMA;
+       }
+
+       tag &= CMD_HDR_ATTR_TAG;
+       val32 |= tag;
+
+       debug("attribute = %08x\n\r", val32);
+       cmd_hdr->attribute = cpu_to_le32(val32);
+
+       /* Make sure cmd desc and cmd slot valid before command issue */
+       sync();
+
+       /* PMP*/
+       val32 = (u32)(h2d->pm_port_c & 0x0f);
+       out_le32(&reg->cqpmp, val32);
+
+       /* Wait no active */
+       if (ata_wait_register(&reg->car, (1 << tag), 0, 10000))
+               printf("Wait no active time out\n\r");
+
+       /* Issue command */
+       if (!(in_le32(&reg->cqr) & (1 << tag))) {
+               val32 = 1 << tag;
+               out_le32(&reg->cqr, val32);
+       }
+
+       /* Wait command completed for 10s */
+       if (ata_wait_register(&reg->ccr, (1 << tag), (1 << tag), 10000)) {
+               if (!is_ncq)
+                       printf("Non-NCQ command time out\n\r");
+               else
+                       printf("NCQ command time out\n\r");
+       }
+
+       val32 = in_le32(&reg->cer);
+
+       if (val32) {
+               u32 der;
+               fsl_sata_dump_sfis((struct sata_fis_d2h *)cmd_desc->sfis);
+               printf("CE at device\n\r");
+               fsl_sata_dump_regs(reg);
+               der = in_le32(&reg->der);
+               out_le32(&reg->cer, val32);
+               out_le32(&reg->der, der);
+       }
+
+       /* Clear complete flags */
+       val32 = in_le32(&reg->ccr);
+       out_le32(&reg->ccr, val32);
+
+       return len;
+}
+
+static int fsl_ata_exec_reset_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
+                                int tag, u8 *buffer, u32 len)
+{
+       return 0;
+}
+
+static int fsl_sata_exec_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
+                enum cmd_type command_type, int tag, u8 *buffer, u32 len)
+{
+       int rc;
+
+       if (tag > SATA_HC_MAX_CMD || tag < 0) {
+               printf("tag is out of range, tag=%d\n\r", tag);
+               return -1;
+       }
+
+       switch (command_type) {
+       case CMD_ATA:
+               rc = fsl_ata_exec_ata_cmd(sata, cfis, 0, tag, buffer, len);
+               return rc;
+       case CMD_RESET:
+               rc = fsl_ata_exec_reset_cmd(sata, cfis, tag, buffer, len);
+               return rc;
+       case CMD_NCQ:
+               rc = fsl_ata_exec_ata_cmd(sata, cfis, 1, tag, buffer, len);
+               return rc;
+       case CMD_ATAPI:
+       case CMD_VENDOR_BIST:
+       case CMD_BIST:
+               printf("not support now\n\r");
+               return -1;
+       default:
+               break;
+       }
+
+       return -1;
+}
+
+static void fsl_sata_identify(int dev, u16 *id)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_ID_ATA;
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2);
+       ata_swap_buf_le16(id, ATA_ID_WORDS);
+}
+
+static void fsl_sata_xfer_mode(int dev, u16 *id)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+       sata->pio = id[ATA_ID_PIO_MODES];
+       sata->mwdma = id[ATA_ID_MWDMA_MODES];
+       sata->udma = id[ATA_ID_UDMA_MODES];
+       debug("pio %04x, mwdma %04x, udma %04x\n\r", sata->pio, sata->mwdma, sata->udma);
+}
+
+static void fsl_sata_set_features(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+       u8 udma_cap;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_SET_FEATURES;
+       cfis->features = SETFEATURES_XFER;
+
+       /* First check the device capablity */
+       udma_cap = (u8)(sata->udma & 0xff);
+       debug("udma_cap %02x\n\r", udma_cap);
+
+       if (udma_cap == ATA_UDMA6)
+               cfis->sector_count = XFER_UDMA_6;
+       if (udma_cap == ATA_UDMA5)
+               cfis->sector_count = XFER_UDMA_5;
+       if (udma_cap == ATA_UDMA4)
+               cfis->sector_count = XFER_UDMA_4;
+       if (udma_cap == ATA_UDMA3)
+               cfis->sector_count = XFER_UDMA_3;
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+       u32 block;
+
+       block = start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
+       cfis->device = ATA_LBA;
+
+       cfis->device |= (block >> 24) & 0xf;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+       cfis->sector_count = (u8)(blkcnt & 0xff);
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
+       return blkcnt;
+}
+
+static void fsl_sata_flush_cache(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_FLUSH;
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+       u64 block;
+
+       block = (u64)start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+
+       cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
+                                : ATA_CMD_READ_EXT;
+
+       cfis->lba_high_exp = (block >> 40) & 0xff;
+       cfis->lba_mid_exp = (block >> 32) & 0xff;
+       cfis->lba_low_exp = (block >> 24) & 0xff;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+       cfis->device = ATA_LBA;
+       cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
+       cfis->sector_count = blkcnt & 0xff;
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
+       return blkcnt;
+}
+
+static u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer,
+                              int is_write)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+       int ncq_channel;
+       u64 block;
+
+       if (sata->lba48 != 1) {
+               printf("execute FPDMA command on non-LBA48 hard disk\n\r");
+               return -1;
+       }
+
+       block = (u64)start;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+
+       cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
+                                : ATA_CMD_FPDMA_READ;
+
+       cfis->lba_high_exp = (block >> 40) & 0xff;
+       cfis->lba_mid_exp = (block >> 32) & 0xff;
+       cfis->lba_low_exp = (block >> 24) & 0xff;
+       cfis->lba_high = (block >> 16) & 0xff;
+       cfis->lba_mid = (block >> 8) & 0xff;
+       cfis->lba_low = block & 0xff;
+
+       cfis->device = ATA_LBA;
+       cfis->features_exp = (blkcnt >> 8) & 0xff;
+       cfis->features = blkcnt & 0xff;
+
+       if (sata->queue_depth >= SATA_HC_MAX_CMD)
+               ncq_channel = SATA_HC_MAX_CMD - 1;
+       else
+               ncq_channel = sata->queue_depth - 1;
+
+       /* Use the latest queue */
+       fsl_sata_exec_cmd(sata, cfis, CMD_NCQ, ncq_channel, buffer, ATA_SECT_SIZE * blkcnt);
+       return blkcnt;
+}
+
+static void fsl_sata_flush_cache_ext(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       struct sata_fis_h2d h2d, *cfis = &h2d;
+
+       memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis->pm_port_c = 0x80; /* is command */
+       cfis->command = ATA_CMD_FLUSH_EXT;
+
+       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static void fsl_sata_init_wcache(int dev, u16 *id)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
+               sata->wcache = 1;
+       if (ata_id_has_flush(id))
+               sata->flush = 1;
+       if (ata_id_has_flush_ext(id))
+               sata->flush_ext = 1;
+}
+
+static int fsl_sata_get_wcache(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       return sata->wcache;
+}
+
+static int fsl_sata_get_flush(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       return sata->flush;
+}
+
+static int fsl_sata_get_flush_ext(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       return sata->flush_ext;
+}
+
+static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
+               const void *buffer, int is_write)
+{
+       u32 start, blks;
+       u8 *addr;
+       int max_blks;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS_LBA48;
+       do {
+               if (blks > max_blks) {
+                       if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
+                               fsl_sata_rw_cmd_ext(dev, start, max_blks, addr, is_write);
+                       else
+                               fsl_sata_rw_ncq_cmd(dev, start, max_blks, addr, is_write);
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
+                               fsl_sata_rw_cmd_ext(dev, start, blks, addr, is_write);
+                       else
+                               fsl_sata_rw_ncq_cmd(dev, start, blks, addr, is_write);
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+static u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt,
+                                 const void *buffer, int is_write)
+{
+       u32 start, blks;
+       u8 *addr;
+       int max_blks;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS;
+       do {
+               if (blks > max_blks) {
+                       fsl_sata_rw_cmd(dev, start, max_blks, addr, is_write);
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       fsl_sata_rw_cmd(dev, start, blks, addr, is_write);
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       u32 rc;
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+       if (sata->lba48)
+               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
+       else
+               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
+       return rc;
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       u32 rc;
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+       if (sata->lba48) {
+               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
+               if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush_ext(dev))
+                       fsl_sata_flush_cache_ext(dev);
+       } else {
+               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD);
+               if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush(dev))
+                       fsl_sata_flush_cache(dev);
+       }
+       return rc;
+}
+
+int scan_sata(int dev)
+{
+       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+       unsigned char serial[ATA_ID_SERNO_LEN + 1];
+       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+       unsigned char product[ATA_ID_PROD_LEN + 1];
+       u16 *id;
+       u64 n_sectors;
+
+       /* if no detected link */
+       if (!sata->link)
+               return -1;
+
+       id = (u16 *)malloc(ATA_ID_WORDS * 2);
+       if (!id) {
+               printf("id malloc failed\n\r");
+               return -1;
+       }
+
+       /* Identify device to get information */
+       fsl_sata_identify(dev, id);
+
+       /* Serial number */
+       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+       memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
+
+       /* Firmware version */
+       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+       memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
+
+       /* Product model */
+       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+       memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
+
+       /* Totoal sectors */
+       n_sectors = ata_id_n_sectors(id);
+       sata_dev_desc[dev].lba = (u32)n_sectors;
+
+#ifdef CONFIG_LBA48
+       /* Check if support LBA48 */
+       if (ata_id_has_lba48(id)) {
+               sata->lba48 = 1;
+               debug("Device support LBA48\n\r");
+       } else
+               debug("Device supports LBA28\n\r");
+#endif
+
+       /* Get the NCQ queue depth from device */
+       sata->queue_depth = ata_id_queue_depth(id);
+
+       /* Get the xfer mode from device */
+       fsl_sata_xfer_mode(dev, id);
+
+       /* Get the write cache status from device */
+       fsl_sata_init_wcache(dev, id);
+
+       /* Set the xfer mode to highest speed */
+       fsl_sata_set_features(dev);
+#ifdef DEBUG
+       fsl_sata_identify(dev, id);
+       ata_dump_id(id);
+#endif
+       free((void *)id);
+       return 0;
+}
diff --git a/drivers/ata/fsl_sata.h b/drivers/ata/fsl_sata.h
new file mode 100644 (file)
index 0000000..18d679e
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2007-2008 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __FSL_SATA_H__
+#define __FSL_SATA_H__
+
+#define SATA_HC_MAX_NUM                4 /* Max host controller numbers */
+#define SATA_HC_MAX_CMD                16 /* Max command queue depth per host controller */
+#define SATA_HC_MAX_PORT       16 /* Max port number per host controller */
+
+/*
+* SATA Host Controller Registers
+*/
+typedef struct fsl_sata_reg {
+       /* SATA command registers */
+       u32 cqr;                /* Command queue register */
+       u8 res1[0x4];
+       u32 car;                /* Command active register */
+       u8 res2[0x4];
+       u32 ccr;                /* Command completed register */
+       u8 res3[0x4];
+       u32 cer;                /* Command error register */
+       u8 res4[0x4];
+       u32 der;                /* Device error register */
+       u32 chba;               /* Command header base address */
+       u32 hstatus;            /* Host status register */
+       u32 hcontrol;           /* Host control register */
+       u32 cqpmp;              /* Port number queue register */
+       u32 sig;                /* Signature register */
+       u32 icc;                /* Interrupt coalescing control register */
+       u8 res5[0xc4];
+
+       /* SATA supperset registers */
+       u32 sstatus;            /* SATA interface status register */
+       u32 serror;             /* SATA interface error register */
+       u32 scontrol;           /* SATA interface control register */
+       u32 snotification;      /* SATA interface notification register */
+       u8 res6[0x30];
+
+       /* SATA control status registers */
+       u32 transcfg;           /* Transport layer configuration */
+       u32 transstatus;        /* Transport layer status */
+       u32 linkcfg;            /* Link layer configuration */
+       u32 linkcfg1;           /* Link layer configuration1 */
+       u32 linkcfg2;           /* Link layer configuration2 */
+       u32 linkstatus;         /* Link layer status */
+       u32 linkstatus1;        /* Link layer status1 */
+       u32 phyctrlcfg;         /* PHY control configuration */
+       u8 res7[0x2b0];
+
+       /* SATA system control registers */
+       u32 syspr;              /* System priority register - big endian */
+       u8 res8[0xbec];
+} __attribute__ ((packed)) fsl_sata_reg_t;
+
+/* HStatus register
+*/
+#define HSTATUS_ONOFF                  0x80000000 /* Online/offline status */
+#define HSTATUS_FORCE_OFFLINE          0x40000000 /* In process going offline */
+#define HSTATUS_BIST_ERR               0x20000000
+
+/* Fatal error */
+#define HSTATUS_MASTER_ERR             0x00004000
+#define HSTATUS_DATA_UNDERRUN          0x00002000
+#define HSTATUS_DATA_OVERRUN           0x00001000
+#define HSTATUS_CRC_ERR_TX             0x00000800
+#define HSTATUS_CRC_ERR_RX             0x00000400
+#define HSTATUS_FIFO_OVERFLOW_TX       0x00000200
+#define HSTATUS_FIFO_OVERFLOW_RX       0x00000100
+#define HSTATUS_FATAL_ERR_ALL          (HSTATUS_MASTER_ERR | \
+                                       HSTATUS_DATA_UNDERRUN | \
+                                       HSTATUS_DATA_OVERRUN | \
+                                       HSTATUS_CRC_ERR_TX | \
+                                       HSTATUS_CRC_ERR_RX | \
+                                       HSTATUS_FIFO_OVERFLOW_TX | \
+                                       HSTATUS_FIFO_OVERFLOW_RX)
+/* Interrupt status */
+#define HSTATUS_FATAL_ERR              0x00000020
+#define HSTATUS_PHY_RDY                        0x00000010
+#define HSTATUS_SIGNATURE              0x00000008
+#define HSTATUS_SNOTIFY                        0x00000004
+#define HSTATUS_DEVICE_ERR             0x00000002
+#define HSTATUS_CMD_COMPLETE           0x00000001
+
+/* HControl register
+*/
+#define HCONTROL_ONOFF                 0x80000000 /* Online or offline request */
+#define HCONTROL_FORCE_OFFLINE         0x40000000 /* Force offline request */
+#define HCONTROL_ENTERPRISE_EN         0x10000000 /* Enterprise mode enabled */
+#define HCONTROL_HDR_SNOOP             0x00000400 /* Command header snoop */
+#define HCONTROL_PMP_ATTACHED          0x00000200 /* Port multiplier attached */
+
+/* Interrupt enable */
+#define HCONTROL_FATAL_ERR             0x00000020
+#define HCONTROL_PHY_RDY               0x00000010
+#define HCONTROL_SIGNATURE             0x00000008
+#define HCONTROL_SNOTIFY               0x00000004
+#define HCONTROL_DEVICE_ERR            0x00000002
+#define HCONTROL_CMD_COMPLETE          0x00000001
+
+#define HCONTROL_INT_EN_ALL            (HCONTROL_FATAL_ERR | \
+                                       HCONTROL_PHY_RDY | \
+                                       HCONTROL_SIGNATURE | \
+                                       HCONTROL_SNOTIFY | \
+                                       HCONTROL_DEVICE_ERR | \
+                                       HCONTROL_CMD_COMPLETE)
+
+/* SStatus register
+*/
+#define SSTATUS_IPM_MASK               0x00000780
+#define SSTATUS_IPM_NOPRESENT          0x00000000
+#define SSTATUS_IPM_ACTIVE             0x00000080
+#define SSTATUS_IPM_PATIAL             0x00000100
+#define SSTATUS_IPM_SLUMBER            0x00000300
+
+#define SSTATUS_SPD_MASK               0x000000f0
+#define SSTATUS_SPD_GEN1               0x00000010
+#define SSTATUS_SPD_GEN2               0x00000020
+
+#define SSTATUS_DET_MASK               0x0000000f
+#define SSTATUS_DET_NODEVICE           0x00000000
+#define SSTATUS_DET_DISCONNECT         0x00000001
+#define SSTATUS_DET_CONNECT            0x00000003
+#define SSTATUS_DET_PHY_OFFLINE                0x00000004
+
+/* SControl register
+*/
+#define SCONTROL_SPM_MASK              0x0000f000
+#define SCONTROL_SPM_GO_PARTIAL                0x00001000
+#define SCONTROL_SPM_GO_SLUMBER                0x00002000
+#define SCONTROL_SPM_GO_ACTIVE         0x00004000
+
+#define SCONTROL_IPM_MASK              0x00000f00
+#define SCONTROL_IPM_NO_RESTRICT       0x00000000
+#define SCONTROL_IPM_PARTIAL           0x00000100
+#define SCONTROL_IPM_SLUMBER           0x00000200
+#define SCONTROL_IPM_PART_SLUM         0x00000300
+
+#define SCONTROL_SPD_MASK              0x000000f0
+#define SCONTROL_SPD_NO_RESTRICT       0x00000000
+#define SCONTROL_SPD_GEN1              0x00000010
+#define SCONTROL_SPD_GEN2              0x00000020
+
+#define SCONTROL_DET_MASK              0x0000000f
+#define SCONTROL_DET_HRESET            0x00000001
+#define SCONTROL_DET_DISABLE           0x00000004
+
+/* TransCfg register
+*/
+#define TRANSCFG_DFIS_SIZE_SHIFT       16
+#define TRANSCFG_RX_WATER_MARK_MASK    0x0000001f
+
+/* PhyCtrlCfg register
+*/
+#define PHYCTRLCFG_FPRFTI_MASK         0x00000018
+#define PHYCTRLCFG_LOOPBACK_MASK       0x0000000e
+
+/*
+* Command Header Entry
+*/
+typedef struct cmd_hdr_entry {
+       __le32 cda;             /* Command Descriptor Address,
+                                  4 bytes aligned */
+       __le32 prde_fis_len;    /* Number of PRD entries and FIS length */
+       __le32 ttl;             /* Total transfer length */
+       __le32 attribute;       /* the attribute of command */
+} __attribute__ ((packed)) cmd_hdr_entry_t;
+
+#define SATA_HC_CMD_HDR_ENTRY_SIZE     sizeof(struct cmd_hdr_entry)
+
+/* cda
+*/
+#define CMD_HDR_CDA_ALIGN      4
+
+/* prde_fis_len
+*/
+#define CMD_HDR_PRD_ENTRY_SHIFT        16
+#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
+#define CMD_HDR_FIS_LEN_SHIFT  2
+
+/* attribute
+*/
+#define CMD_HDR_ATTR_RES       0x00000800 /* Reserved bit, should be 1 */
+#define CMD_HDR_ATTR_VBIST     0x00000400 /* Vendor BIST */
+#define CMD_HDR_ATTR_SNOOP     0x00000200 /* Snoop enable for all descriptor */
+#define CMD_HDR_ATTR_FPDMA     0x00000100 /* FPDMA queued command */
+#define CMD_HDR_ATTR_RESET     0x00000080 /* Reset - a SRST or device reset */
+#define CMD_HDR_ATTR_BIST      0x00000040 /* BIST - require the host to enter BIST mode */
+#define CMD_HDR_ATTR_ATAPI     0x00000020 /* ATAPI command */
+#define CMD_HDR_ATTR_TAG       0x0000001f /* TAG mask */
+
+/* command type
+*/
+enum cmd_type {
+       CMD_VENDOR_BIST,
+       CMD_BIST,
+       CMD_RESET,      /* SRST or device reset */
+       CMD_ATAPI,
+       CMD_NCQ,
+       CMD_ATA,        /* None of all above */
+};
+
+/*
+* Command Header Table
+*/
+typedef struct cmd_hdr_tbl {
+       cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD];
+} __attribute__ ((packed)) cmd_hdr_tbl_t;
+
+#define SATA_HC_CMD_HDR_TBL_SIZE       sizeof(struct cmd_hdr_tbl)
+#define SATA_HC_CMD_HDR_TBL_ALIGN      4
+
+/*
+* PRD entry - Physical Region Descriptor entry
+*/
+typedef struct prd_entry {
+       __le32 dba;     /* Data base address, 4 bytes aligned */
+       u32 res1;
+       u32 res2;
+       __le32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */
+} __attribute__ ((packed)) prd_entry_t;
+
+#define SATA_HC_CMD_DESC_PRD_SIZE      sizeof(struct prd_entry)
+
+/* dba
+*/
+#define PRD_ENTRY_DBA_ALIGN    4
+
+/* ext_c_ddc
+*/
+#define PRD_ENTRY_EXT          0x80000000 /* extension flag */
+#ifdef CONFIG_FSL_SATA_V2
+#define PRD_ENTRY_DATA_SNOOP   0x10000000 /* Data snoop enable */
+#else
+#define PRD_ENTRY_DATA_SNOOP   0x00400000 /* Data snoop enable */
+#endif
+#define PRD_ENTRY_LEN_MASK     0x003fffff /* Data word count */
+
+#define PRD_ENTRY_MAX_XFER_SZ  (PRD_ENTRY_LEN_MASK + 1)
+
+/*
+ * This SATA host controller supports a max of 16 direct PRD entries, but if use
+ * chained indirect PRD entries, then the contollers supports upto a max of 63
+ * entries including direct and indirect PRD entries.
+ * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15
+ * will be setup as an indirect descriptor, pointing to it's next (contigious)
+ * PRD entries#16.
+ */
+#define SATA_HC_MAX_PRD                63 /* Max PRD entry numbers per command */
+#define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */
+#define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1)
+#define SATA_HC_MAX_XFER_LEN   0x4000000
+
+/*
+* PRDT - Physical Region Descriptor Table
+*/
+typedef struct prdt {
+       prd_entry_t prdt[SATA_HC_MAX_PRD];
+} __attribute__ ((packed)) prdt_t;
+
+/*
+* Command Descriptor
+*/
+#define SATA_HC_CMD_DESC_CFIS_SIZE     32 /* bytes */
+#define SATA_HC_CMD_DESC_SFIS_SIZE     32 /* bytes */
+#define SATA_HC_CMD_DESC_ACMD_SIZE     16 /* bytes */
+#define SATA_HC_CMD_DESC_RES           16 /* bytes */
+
+typedef struct cmd_desc {
+       u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE];
+       u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE];
+       u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE];
+       u8 res[SATA_HC_CMD_DESC_RES];
+       prd_entry_t prdt[SATA_HC_MAX_PRD];
+} __attribute__ ((packed)) cmd_desc_t;
+
+#define SATA_HC_CMD_DESC_SIZE          sizeof(struct cmd_desc)
+#define SATA_HC_CMD_DESC_ALIGN         4
+
+/*
+ * SATA device driver info
+ */
+typedef struct fsl_sata_info {
+       u32     sata_reg_base;
+       u32     flags;
+} fsl_sata_info_t;
+
+#define FLAGS_DMA      0x00000000
+#define FLAGS_FPDMA    0x00000001
+
+/*
+ * SATA device driver struct
+ */
+typedef struct fsl_sata {
+       char            name[12];
+       fsl_sata_reg_t  *reg_base;              /* the base address of controller register */
+       void            *cmd_hdr_tbl_offset;    /* alloc address of command header table */
+       cmd_hdr_tbl_t   *cmd_hdr;               /* aligned address of command header table */
+       void            *cmd_desc_offset;       /* alloc address of command descriptor */
+       cmd_desc_t      *cmd_desc;              /* aligned address of command descriptor */
+       int             link;                   /* PHY link status */
+       /* device attribute */
+       int             ata_device_type;        /* device type */
+       int             lba48;
+       int             queue_depth;            /* Max NCQ queue depth */
+       u16             pio;
+       u16             mwdma;
+       u16             udma;
+       int             wcache;
+       int             flush;
+       int             flush_ext;
+} fsl_sata_t;
+
+#define READ_CMD       0
+#define WRITE_CMD      1
+
+#endif /* __FSL_SATA_H__ */
diff --git a/drivers/ata/libata.c b/drivers/ata/libata.c
new file mode 100644 (file)
index 0000000..d684270
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *             port from the libata of linux kernel
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <libata.h>
+
+u64 ata_id_n_sectors(u16 *id)
+{
+       if (ata_id_has_lba(id)) {
+               if (ata_id_has_lba48(id))
+                       return ata_id_u64(id, ATA_ID_LBA48_SECTORS);
+               else
+                       return ata_id_u32(id, ATA_ID_LBA_SECTORS);
+       } else {
+               return 0;
+       }
+}
+
+u32 ata_dev_classify(u32 sig)
+{
+       u8 lbam, lbah;
+
+       lbam = (sig >> 16) & 0xff;
+       lbah = (sig >> 24) & 0xff;
+
+       if (((lbam == 0) && (lbah == 0)) ||
+               ((lbam == 0x3c) && (lbah == 0xc3)))
+               return ATA_DEV_ATA;
+
+       if ((lbam == 0x14) && (lbah == 0xeb))
+               return ATA_DEV_ATAPI;
+
+       if ((lbam == 0x69) && (lbah == 0x96))
+               return ATA_DEV_PMP;
+
+       return ATA_DEV_UNKNOWN;
+}
+
+static void ata_id_string(const u16 *id, unsigned char *s,
+                        unsigned int ofs, unsigned int len)
+{
+       unsigned int c;
+
+       while (len > 0) {
+               c = id[ofs] >> 8;
+               *s = c;
+               s++;
+
+               c = id[ofs] & 0xff;
+               *s = c;
+               s++;
+
+               ofs++;
+               len -= 2;
+       }
+}
+
+void ata_id_c_string(const u16 *id, unsigned char *s,
+                        unsigned int ofs, unsigned int len)
+{
+       unsigned char *p;
+
+       ata_id_string(id, s, ofs, len - 1);
+
+       p = s + strnlen((char *)s, len - 1);
+       while (p > s && p[-1] == ' ')
+               p--;
+       *p = '\0';
+}
+
+void ata_dump_id(u16 *id)
+{
+       unsigned char serial[ATA_ID_SERNO_LEN + 1];
+       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+       unsigned char product[ATA_ID_PROD_LEN + 1];
+       u64 n_sectors;
+
+       /* Serial number */
+       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+       printf("S/N: %s\n\r", serial);
+
+       /* Firmware version */
+       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+       printf("Firmware version: %s\n\r", firmware);
+
+       /* Product model */
+       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+       printf("Product model number: %s\n\r", product);
+
+       /* Total sectors of device  */
+       n_sectors = ata_id_n_sectors(id);
+       printf("Capablity: %lld sectors\n\r", n_sectors);
+
+       printf ("id[49]: capabilities = 0x%04x\n"
+               "id[53]: field valid = 0x%04x\n"
+               "id[63]: mwdma = 0x%04x\n"
+               "id[64]: pio = 0x%04x\n"
+               "id[75]: queue depth = 0x%04x\n",
+               id[49],
+               id[53],
+               id[63],
+               id[64],
+               id[75]);
+
+       printf ("id[76]: sata capablity = 0x%04x\n"
+               "id[78]: sata features supported = 0x%04x\n"
+               "id[79]: sata features enable = 0x%04x\n",
+               id[76],
+               id[78],
+               id[79]);
+
+       printf ("id[80]: major version = 0x%04x\n"
+               "id[81]: minor version = 0x%04x\n"
+               "id[82]: command set supported 1 = 0x%04x\n"
+               "id[83]: command set supported 2 = 0x%04x\n"
+               "id[84]: command set extension = 0x%04x\n",
+               id[80],
+               id[81],
+               id[82],
+               id[83],
+               id[84]);
+       printf ("id[85]: command set enable 1 = 0x%04x\n"
+               "id[86]: command set enable 2 = 0x%04x\n"
+               "id[87]: command set default = 0x%04x\n"
+               "id[88]: udma = 0x%04x\n"
+               "id[93]: hardware reset result = 0x%04x\n",
+               id[85],
+               id[86],
+               id[87],
+               id[88],
+               id[93]);
+}
+
+void ata_swap_buf_le16(u16 *buf, unsigned int buf_words)
+{
+       unsigned int i;
+
+       for (i = 0; i < buf_words; i++)
+               buf[i] = le16_to_cpu(buf[i]);
+}
diff --git a/drivers/ata/mvsata_ide.c b/drivers/ata/mvsata_ide.c
new file mode 100644 (file)
index 0000000..7b6a155
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ * Written-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_ORION5X)
+#include <asm/arch/orion5x.h>
+#elif defined(CONFIG_KIRKWOOD)
+#include <asm/arch/soc.h>
+#elif defined(CONFIG_ARCH_MVEBU)
+#include <linux/mbus.h>
+#endif
+
+/* SATA port registers */
+struct mvsata_port_registers {
+       u32 reserved0[10];
+       u32 edma_cmd;
+       u32 reserved1[181];
+       /* offset 0x300 : ATA Interface registers */
+       u32 sstatus;
+       u32 serror;
+       u32 scontrol;
+       u32 ltmode;
+       u32 phymode3;
+       u32 phymode4;
+       u32 reserved2[5];
+       u32 phymode1;
+       u32 phymode2;
+       u32 bist_cr;
+       u32 bist_dw1;
+       u32 bist_dw2;
+       u32 serrorintrmask;
+};
+
+/*
+ * Sanity checks:
+ * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR.
+ * - for ide_preinit to make sense, we need at least one of
+ *   CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET;
+ * - for ide_preinit to be called, we need CONFIG_IDE_PREINIT.
+ * Fail with an explanation message if these conditions are not met.
+ * This is particularly important for CONFIG_IDE_PREINIT, because
+ * its lack would not cause a build error.
+ */
+
+#if !defined(CONFIG_SYS_ATA_BASE_ADDR)
+#error CONFIG_SYS_ATA_BASE_ADDR must be defined
+#elif !defined(CONFIG_SYS_ATA_IDE0_OFFSET) \
+   && !defined(CONFIG_SYS_ATA_IDE1_OFFSET)
+#error CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET \
+   must be defined
+#elif !defined(CONFIG_IDE_PREINIT)
+#error CONFIG_IDE_PREINIT must be defined
+#endif
+
+/*
+ * Masks and values for SControl DETection and Interface Power Management,
+ * and for SStatus DETection.
+ */
+
+#define MVSATA_EDMA_CMD_ATA_RST                0x00000004
+#define MVSATA_SCONTROL_DET_MASK               0x0000000F
+#define MVSATA_SCONTROL_DET_NONE               0x00000000
+#define MVSATA_SCONTROL_DET_INIT               0x00000001
+#define MVSATA_SCONTROL_IPM_MASK               0x00000F00
+#define MVSATA_SCONTROL_IPM_NO_LP_ALLOWED      0x00000300
+#define MVSATA_SCONTROL_MASK \
+       (MVSATA_SCONTROL_DET_MASK|MVSATA_SCONTROL_IPM_MASK)
+#define MVSATA_PORT_INIT \
+       (MVSATA_SCONTROL_DET_INIT|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
+#define MVSATA_PORT_USE \
+       (MVSATA_SCONTROL_DET_NONE|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
+#define MVSATA_SSTATUS_DET_MASK                        0x0000000F
+#define MVSATA_SSTATUS_DET_DEVCOMM             0x00000003
+
+/*
+ * Status codes to return to client callers. Currently, callers ignore
+ * exact value and only care for zero or nonzero, so no need to make this
+ * public, it is only #define'd for clarity.
+ * If/when standard negative codes are implemented in U-Boot, then these
+ * #defines should be moved to, or replaced by ones from, the common list
+ * of status codes.
+ */
+
+#define MVSATA_STATUS_OK       0
+#define MVSATA_STATUS_TIMEOUT  -1
+
+/*
+ * Registers for SATA MBUS memory windows
+ */
+
+#define MVSATA_WIN_CONTROL(w)  (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
+#define MVSATA_WIN_BASE(w)     (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
+
+/*
+ * Initialize SATA memory windows for Armada XP
+ */
+
+#ifdef CONFIG_ARCH_MVEBU
+static void mvsata_ide_conf_mbus_windows(void)
+{
+       const struct mbus_dram_target_info *dram;
+       int i;
+
+       dram = mvebu_mbus_dram_info();
+
+       /* Disable windows, Set Size/Base to 0  */
+       for (i = 0; i < 4; i++) {
+               writel(0, MVSATA_WIN_CONTROL(i));
+               writel(0, MVSATA_WIN_BASE(i));
+       }
+
+       for (i = 0; i < dram->num_cs; i++) {
+               const struct mbus_dram_window *cs = dram->cs + i;
+               writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+                               (dram->mbus_dram_target_id << 4) | 1,
+                               MVSATA_WIN_CONTROL(i));
+               writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
+       }
+}
+#endif
+
+/*
+ * Initialize one MVSATAHC port: set SControl's IPM to "always active"
+ * and DET to "reset", then wait for SStatus's DET to become "device and
+ * comm ok" (or time out after 50 us if no device), then set SControl's
+ * DET back to "no action".
+ */
+
+static int mvsata_ide_initialize_port(struct mvsata_port_registers *port)
+{
+       u32 control;
+       u32 status;
+       u32 timeleft = 10000; /* wait at most 10 ms for SATA reset to complete */
+
+       /* Hard reset */
+       writel(MVSATA_EDMA_CMD_ATA_RST, &port->edma_cmd);
+       udelay(25); /* taken from original marvell port */
+       writel(0, &port->edma_cmd);
+
+       /* Set control IPM to 3 (no low power) and DET to 1 (initialize) */
+       control = readl(&port->scontrol);
+       control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT;
+       writel(control, &port->scontrol);
+       /* Toggle control DET back to 0 (normal operation) */
+       control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE;
+       writel(control, &port->scontrol);
+       /* wait for status DET to become 3 (device and communication OK) */
+       while (--timeleft) {
+               status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK;
+               if (status == MVSATA_SSTATUS_DET_DEVCOMM)
+                       break;
+               udelay(1);
+       }
+       /* return success or time-out error depending on time left */
+       if (!timeleft)
+               return MVSATA_STATUS_TIMEOUT;
+       return MVSATA_STATUS_OK;
+}
+
+/*
+ * ide_preinit() will be called by ide_init in cmd_ide.c and will
+ * reset the MVSTATHC ports needed by the board.
+ */
+
+int ide_preinit(void)
+{
+       int ret = MVSATA_STATUS_TIMEOUT;
+       int status;
+
+#ifdef CONFIG_ARCH_MVEBU
+       mvsata_ide_conf_mbus_windows();
+#endif
+
+       /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */
+#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
+       status = mvsata_ide_initialize_port(
+               (struct mvsata_port_registers *)
+               (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET));
+       if (status == MVSATA_STATUS_OK)
+               ret = MVSATA_STATUS_OK;
+#endif
+       /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */
+#if defined(CONFIG_SYS_ATA_IDE1_OFFSET)
+       status = mvsata_ide_initialize_port(
+               (struct mvsata_port_registers *)
+               (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET));
+       if (status == MVSATA_STATUS_OK)
+               ret = MVSATA_STATUS_OK;
+#endif
+       /* Return success if at least one port initialization succeeded */
+       return ret;
+}
diff --git a/drivers/ata/mxc_ata.c b/drivers/ata/mxc_ata.c
new file mode 100644 (file)
index 0000000..44bb406
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Freescale iMX51 ATA driver
+ *
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on code by:
+ *     Mahesh Mahadevan <mahesh.mahadevan@freescale.com>
+ *
+ * Based on code from original FSL ATA driver, which is
+ * part of eCos, the Embedded Configurable Operating System.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <ide.h>
+
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+/* MXC ATA register offsets */
+struct mxc_ata_config_regs {
+       u8      time_off;       /* 0x00 */
+       u8      time_on;
+       u8      time_1;
+       u8      time_2w;
+       u8      time_2r;
+       u8      time_ax;
+       u8      time_pio_rdx;
+       u8      time_4;
+       u8      time_9;
+       u8      time_m;
+       u8      time_jn;
+       u8      time_d;
+       u8      time_k;
+       u8      time_ack;
+       u8      time_env;
+       u8      time_udma_rdx;
+       u8      time_zah;       /* 0x10 */
+       u8      time_mlix;
+       u8      time_dvh;
+       u8      time_dzfs;
+       u8      time_dvs;
+       u8      time_cvh;
+       u8      time_ss;
+       u8      time_cyc;
+       u32     fifo_data_32;   /* 0x18 */
+       u32     fifo_data_16;
+       u32     fifo_fill;
+       u32     ata_control;
+       u32     interrupt_pending;
+       u32     interrupt_enable;
+       u32     interrupt_clear;
+       u32     fifo_alarm;
+};
+
+struct mxc_data_hdd_regs {
+       u32     drive_data;     /* 0xa0 */
+       u32     drive_features;
+       u32     drive_sector_count;
+       u32     drive_sector_num;
+       u32     drive_cyl_low;
+       u32     drive_cyl_high;
+       u32     drive_dev_head;
+       u32     command;
+       u32     status;
+       u32     alt_status;
+};
+
+/* PIO timing table */
+#define        NR_PIO_SPECS    5
+static uint16_t pio_t1[NR_PIO_SPECS]   = { 70,  50,  30,  30,  25 };
+static uint16_t pio_t2_8[NR_PIO_SPECS] = { 290, 290, 290, 80,  70 };
+static uint16_t pio_t4[NR_PIO_SPECS]   = { 30,  20,  15,  10,  10 };
+static uint16_t pio_t9[NR_PIO_SPECS]   = { 20,  15,  10,  10,  10 };
+static uint16_t pio_tA[NR_PIO_SPECS]   = { 50,  50,  50,  50,  50 };
+
+#define        REG2OFF(reg)    ((((uint32_t)reg) & 0x3) * 8)
+static void set_ata_bus_timing(unsigned char mode)
+{
+       uint32_t T = 1000000000 / mxc_get_clock(MXC_IPG_CLK);
+
+       struct mxc_ata_config_regs *ata_regs;
+       ata_regs = (struct mxc_ata_config_regs *)CONFIG_SYS_ATA_BASE_ADDR;
+
+       if (mode >= NR_PIO_SPECS)
+               return;
+
+       /* Write TIME_OFF/ON/1/2W */
+       writeb(3, &ata_regs->time_off);
+       writeb(3, &ata_regs->time_on);
+       writeb((pio_t1[mode] + T) / T, &ata_regs->time_1);
+       writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2w);
+
+       /* Write TIME_2R/AX/RDX/4 */
+       writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2r);
+       writeb((pio_tA[mode] + T) / T + 2, &ata_regs->time_ax);
+       writeb(1, &ata_regs->time_pio_rdx);
+       writeb((pio_t4[mode] + T) / T, &ata_regs->time_4);
+
+       /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */
+       writeb((pio_t9[mode] + T) / T, &ata_regs->time_9);
+}
+
+int ide_preinit(void)
+{
+       struct mxc_ata_config_regs *ata_regs;
+       ata_regs = (struct mxc_ata_config_regs *)CONFIG_SYS_ATA_BASE_ADDR;
+
+       /* 46.3.3.4 @ FSL iMX51 manual */
+       /* FIFO normal op., drive reset */
+       writel(0x80, &ata_regs->ata_control);
+       /* FIFO normal op., drive not reset */
+       writel(0xc0, &ata_regs->ata_control);
+
+       /* Configure the PIO timing */
+       set_ata_bus_timing(CONFIG_MXC_ATA_PIO_MODE);
+
+       /* 46.3.3.4 @ FSL iMX51 manual */
+       /* Drive not reset, IORDY handshake */
+       writel(0x41, &ata_regs->ata_control);
+
+       return 0;
+}
diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c
new file mode 100644 (file)
index 0000000..42ff5c7
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2000-2005, DENX Software Engineering
+ *             Wolfgang Denk <wd@denx.de>
+ * Copyright (C) Procsys. All rights reserved.
+ *             Mushtaq Khan <mushtaq_k@procsys.com>
+ *                     <mushtaqk_921@yahoo.co.in>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sata.h>
+
+struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
+
+#ifdef CONFIG_PARTITIONS
+struct blk_desc *sata_get_dev(int dev)
+{
+       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
+static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return -ENOSYS;
+}
+
+static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return -ENOSYS;
+}
+#else
+static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return sata_read(block_dev->devnum, start, blkcnt, dst);
+}
+
+static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return sata_write(block_dev->devnum, start, blkcnt, buffer);
+}
+#endif
+
+int __sata_initialize(void)
+{
+       int rc, ret = -1;
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
+               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
+               sata_dev_desc[i].if_type = IF_TYPE_SATA;
+               sata_dev_desc[i].devnum = i;
+               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
+               sata_dev_desc[i].lba = 0;
+               sata_dev_desc[i].blksz = 512;
+               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
+#ifndef CONFIG_BLK
+               sata_dev_desc[i].block_read = sata_bread;
+               sata_dev_desc[i].block_write = sata_bwrite;
+#endif
+               rc = init_sata(i);
+               if (!rc) {
+                       rc = scan_sata(i);
+                       if (!rc && sata_dev_desc[i].lba > 0 &&
+                           sata_dev_desc[i].blksz > 0) {
+                               part_init(&sata_dev_desc[i]);
+                               ret = i;
+                       }
+               }
+       }
+
+       return ret;
+}
+int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
+
+__weak int __sata_stop(void)
+{
+       int i, err = 0;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
+               err |= reset_sata(i);
+
+       if (err)
+               printf("Could not reset some SATA devices\n");
+
+       return err;
+}
+int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
+
+#ifdef CONFIG_BLK
+static const struct blk_ops sata_blk_ops = {
+       .read   = sata_bread,
+       .write  = sata_bwrite,
+};
+
+U_BOOT_DRIVER(sata_blk) = {
+       .name           = "sata_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &sata_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(sata) = {
+       .if_typename    = "sata",
+       .if_type        = IF_TYPE_SATA,
+       .max_devs       = CONFIG_SYS_SATA_MAX_DEVICE,
+       .desc           = sata_dev_desc,
+};
+#endif
diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c
new file mode 100644 (file)
index 0000000..0c24fce
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2015 - 2016 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/io.h>
+
+/* Vendor Specific Register Offsets */
+#define AHCI_VEND_PCFG  0xA4
+#define AHCI_VEND_PPCFG 0xA8
+#define AHCI_VEND_PP2C  0xAC
+#define AHCI_VEND_PP3C  0xB0
+#define AHCI_VEND_PP4C  0xB4
+#define AHCI_VEND_PP5C  0xB8
+#define AHCI_VEND_PAXIC 0xC0
+#define AHCI_VEND_PTC   0xC8
+
+/* Vendor Specific Register bit definitions */
+#define PAXIC_ADBW_BW64 0x1
+#define PAXIC_MAWIDD   (1 << 8)
+#define PAXIC_MARIDD   (1 << 16)
+#define PAXIC_OTL      (0x4 << 20)
+
+#define PCFG_TPSS_VAL  (0x32 << 16)
+#define PCFG_TPRS_VAL  (0x2 << 12)
+#define PCFG_PAD_VAL   0x2
+
+#define PPCFG_TTA      0x1FFFE
+#define PPCFG_PSSO_EN  (1 << 28)
+#define PPCFG_PSS_EN   (1 << 29)
+#define PPCFG_ESDF_EN  (1 << 31)
+
+#define PP2C_CIBGMN    0x0F
+#define PP2C_CIBGMX    (0x25 << 8)
+#define PP2C_CIBGN     (0x18 << 16)
+#define PP2C_CINMP     (0x29 << 24)
+
+#define PP3C_CWBGMN    0x04
+#define PP3C_CWBGMX    (0x0B << 8)
+#define PP3C_CWBGN     (0x08 << 16)
+#define PP3C_CWNMP     (0x0F << 24)
+
+#define PP4C_BMX       0x0a
+#define PP4C_BNM       (0x08 << 8)
+#define PP4C_SFD       (0x4a << 16)
+#define PP4C_PTST      (0x06 << 24)
+
+#define PP5C_RIT       0x60216
+#define PP5C_RCT       (0x7f0 << 20)
+
+#define PTC_RX_WM_VAL  0x40
+#define PTC_RSVD       (1 << 27)
+
+#define PORT0_BASE     0x100
+#define PORT1_BASE     0x180
+
+/* Port Control Register Bit Definitions */
+#define PORT_SCTL_SPD_GEN3     (0x3 << 4)
+#define PORT_SCTL_SPD_GEN2     (0x2 << 4)
+#define PORT_SCTL_SPD_GEN1     (0x1 << 4)
+#define PORT_SCTL_IPM          (0x3 << 8)
+
+#define PORT_BASE      0x100
+#define PORT_OFFSET    0x80
+#define NR_PORTS       2
+#define DRV_NAME       "ahci-ceva"
+#define CEVA_FLAG_BROKEN_GEN2  1
+
+static int ceva_init_sata(ulong mmio)
+{
+       ulong tmp;
+       int i;
+
+       /*
+        * AXI Data bus width to 64
+        * Set Mem Addr Read, Write ID for data transfers
+        * Transfer limit to 72 DWord
+        */
+       tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL;
+       writel(tmp, mmio + AHCI_VEND_PAXIC);
+
+       /* Set AHCI Enable */
+       tmp = readl(mmio + HOST_CTL);
+       tmp |= HOST_AHCI_EN;
+       writel(tmp, mmio + HOST_CTL);
+
+       for (i = 0; i < NR_PORTS; i++) {
+               /* TPSS TPRS scalars, CISE and Port Addr */
+               tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i);
+               writel(tmp, mmio + AHCI_VEND_PCFG);
+
+               /* Port Phy Cfg register enables */
+               tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN;
+               writel(tmp, mmio + AHCI_VEND_PPCFG);
+
+               /* Rx Watermark setting  */
+               tmp = PTC_RX_WM_VAL | PTC_RSVD;
+               writel(tmp, mmio + AHCI_VEND_PTC);
+
+               /* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */
+               tmp = PORT_SCTL_SPD_GEN3 | PORT_SCTL_IPM;
+               writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i);
+       }
+       return 0;
+}
+
+static int sata_ceva_probe(struct udevice *dev)
+{
+       struct scsi_platdata *plat = dev_get_platdata(dev);
+
+       ceva_init_sata(plat->base);
+       return 0;
+}
+
+static const struct udevice_id sata_ceva_ids[] = {
+       { .compatible = "ceva,ahci-1v84" },
+       { }
+};
+
+static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
+{
+       struct scsi_platdata *plat = dev_get_platdata(dev);
+
+       plat->base = devfdt_get_addr(dev);
+       if (plat->base == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       /* Hardcode number for ceva sata controller */
+       plat->max_lun = 1; /* Actually two but untested */
+       plat->max_id = 2;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(ceva_host_blk) = {
+       .name = "ceva_sata",
+       .id = UCLASS_SCSI,
+       .of_match = sata_ceva_ids,
+       .probe = sata_ceva_probe,
+       .ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
+};
diff --git a/drivers/ata/sata_dwc.c b/drivers/ata/sata_dwc.c
new file mode 100644 (file)
index 0000000..a226ca2
--- /dev/null
@@ -0,0 +1,2076 @@
+/*
+ * sata_dwc.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
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+/*
+ * SATA support based on the chip canyonlands.
+ *
+ * 04-17-2009
+ *             The local version of this driver for the canyonlands board
+ *             does not use interrupts but polls the chip instead.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <ata.h>
+#include <sata.h>
+#include <linux/ctype.h>
+
+#include "sata_dwc.h"
+
+#define DMA_NUM_CHANS                  1
+#define DMA_NUM_CHAN_REGS              8
+
+#define AHB_DMA_BRST_DFLT              16
+
+struct dmareg {
+       u32 low;
+       u32 high;
+};
+
+struct dma_chan_regs {
+       struct dmareg sar;
+       struct dmareg dar;
+       struct dmareg llp;
+       struct dmareg ctl;
+       struct dmareg sstat;
+       struct dmareg dstat;
+       struct dmareg sstatar;
+       struct dmareg dstatar;
+       struct dmareg cfg;
+       struct dmareg sgr;
+       struct dmareg dsr;
+};
+
+struct dma_interrupt_regs {
+       struct dmareg tfr;
+       struct dmareg block;
+       struct dmareg srctran;
+       struct dmareg dsttran;
+       struct dmareg error;
+};
+
+struct ahb_dma_regs {
+       struct dma_chan_regs    chan_regs[DMA_NUM_CHAN_REGS];
+       struct dma_interrupt_regs       interrupt_raw;
+       struct dma_interrupt_regs       interrupt_status;
+       struct dma_interrupt_regs       interrupt_mask;
+       struct dma_interrupt_regs       interrupt_clear;
+       struct dmareg                   statusInt;
+       struct dmareg                   rq_srcreg;
+       struct dmareg                   rq_dstreg;
+       struct dmareg                   rq_sgl_srcreg;
+       struct dmareg                   rq_sgl_dstreg;
+       struct dmareg                   rq_lst_srcreg;
+       struct dmareg                   rq_lst_dstreg;
+       struct dmareg                   dma_cfg;
+       struct dmareg                   dma_chan_en;
+       struct dmareg                   dma_id;
+       struct dmareg                   dma_test;
+       struct dmareg                   res1;
+       struct dmareg                   res2;
+       /* DMA Comp Params
+        * Param 6 = dma_param[0], Param 5 = dma_param[1],
+        * Param 4 = dma_param[2] ...
+        */
+       struct dmareg                   dma_params[6];
+};
+
+#define DMA_EN                 0x00000001
+#define DMA_DI                 0x00000000
+#define DMA_CHANNEL(ch)                (0x00000001 << (ch))
+#define DMA_ENABLE_CHAN(ch)    ((0x00000001 << (ch)) | \
+                               ((0x000000001 << (ch)) << 8))
+#define DMA_DISABLE_CHAN(ch)   (0x00000000 |   \
+                               ((0x000000001 << (ch)) << 8))
+
+#define SATA_DWC_MAX_PORTS     1
+#define SATA_DWC_SCR_OFFSET    0x24
+#define SATA_DWC_REG_OFFSET    0x64
+
+struct sata_dwc_regs {
+       u32 fptagr;
+       u32 fpbor;
+       u32 fptcr;
+       u32 dmacr;
+       u32 dbtsr;
+       u32 intpr;
+       u32 intmr;
+       u32 errmr;
+       u32 llcr;
+       u32 phycr;
+       u32 physr;
+       u32 rxbistpd;
+       u32 rxbistpd1;
+       u32 rxbistpd2;
+       u32 txbistpd;
+       u32 txbistpd1;
+       u32 txbistpd2;
+       u32 bistcr;
+       u32 bistfctr;
+       u32 bistsr;
+       u32 bistdecr;
+       u32 res[15];
+       u32 testr;
+       u32 versionr;
+       u32 idr;
+       u32 unimpl[192];
+       u32 dmadr[256];
+};
+
+#define SATA_DWC_TXFIFO_DEPTH          0x01FF
+#define SATA_DWC_RXFIFO_DEPTH          0x01FF
+
+#define SATA_DWC_DBTSR_MWR(size)       ((size / 4) & SATA_DWC_TXFIFO_DEPTH)
+#define SATA_DWC_DBTSR_MRD(size)       (((size / 4) &  \
+                                       SATA_DWC_RXFIFO_DEPTH) << 16)
+#define SATA_DWC_INTPR_DMAT            0x00000001
+#define SATA_DWC_INTPR_NEWFP           0x00000002
+#define SATA_DWC_INTPR_PMABRT          0x00000004
+#define SATA_DWC_INTPR_ERR             0x00000008
+#define SATA_DWC_INTPR_NEWBIST         0x00000010
+#define SATA_DWC_INTPR_IPF             0x10000000
+#define SATA_DWC_INTMR_DMATM           0x00000001
+#define SATA_DWC_INTMR_NEWFPM          0x00000002
+#define SATA_DWC_INTMR_PMABRTM         0x00000004
+#define SATA_DWC_INTMR_ERRM            0x00000008
+#define SATA_DWC_INTMR_NEWBISTM                0x00000010
+
+#define SATA_DWC_DMACR_TMOD_TXCHEN     0x00000004
+#define SATA_DWC_DMACR_TXRXCH_CLEAR    SATA_DWC_DMACR_TMOD_TXCHEN
+
+#define SATA_DWC_QCMD_MAX      32
+
+#define SATA_DWC_SERROR_ERR_BITS       0x0FFF0F03
+
+#define HSDEVP_FROM_AP(ap)     (struct sata_dwc_device_port*)  \
+                               (ap)->private_data
+
+struct sata_dwc_device {
+       struct device           *dev;
+       struct ata_probe_ent    *pe;
+       struct ata_host         *host;
+       u8                      *reg_base;
+       struct sata_dwc_regs    *sata_dwc_regs;
+       int                     irq_dma;
+};
+
+struct sata_dwc_device_port {
+       struct sata_dwc_device  *hsdev;
+       int                     cmd_issued[SATA_DWC_QCMD_MAX];
+       u32                     dma_chan[SATA_DWC_QCMD_MAX];
+       int                     dma_pending[SATA_DWC_QCMD_MAX];
+};
+
+enum {
+       SATA_DWC_CMD_ISSUED_NOT         = 0,
+       SATA_DWC_CMD_ISSUED_PEND        = 1,
+       SATA_DWC_CMD_ISSUED_EXEC        = 2,
+       SATA_DWC_CMD_ISSUED_NODATA      = 3,
+
+       SATA_DWC_DMA_PENDING_NONE       = 0,
+       SATA_DWC_DMA_PENDING_TX         = 1,
+       SATA_DWC_DMA_PENDING_RX         = 2,
+};
+
+#define msleep(a)      udelay(a * 1000)
+#define ssleep(a)      msleep(a * 1000)
+
+static int ata_probe_timeout = (ATA_TMOUT_INTERNAL / 100);
+
+enum sata_dev_state {
+       SATA_INIT = 0,
+       SATA_READY = 1,
+       SATA_NODEVICE = 2,
+       SATA_ERROR = 3,
+};
+enum sata_dev_state dev_state = SATA_INIT;
+
+static struct ahb_dma_regs             *sata_dma_regs = 0;
+static struct ata_host                 *phost;
+static struct ata_port                 ap;
+static struct ata_port                 *pap = &ap;
+static struct ata_device               ata_device;
+static struct sata_dwc_device_port     dwc_devp;
+
+static void    *scr_addr_sstatus;
+static u32     temp_n_block = 0;
+
+static unsigned ata_exec_internal(struct ata_device *dev,
+                       struct ata_taskfile *tf, const u8 *cdb,
+                       int dma_dir, unsigned int buflen,
+                       unsigned long timeout);
+static unsigned int ata_dev_set_feature(struct ata_device *dev,
+                       u8 enable,u8 feature);
+static unsigned int ata_dev_init_params(struct ata_device *dev,
+                       u16 heads, u16 sectors);
+static u8 ata_irq_on(struct ata_port *ap);
+static struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
+                       unsigned int tag);
+static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+                       u8 status, int in_wq);
+static void ata_tf_to_host(struct ata_port *ap,
+                       const struct ata_taskfile *tf);
+static void ata_exec_command(struct ata_port *ap,
+                       const struct ata_taskfile *tf);
+static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
+static u8 ata_check_altstatus(struct ata_port *ap);
+static u8 ata_check_status(struct ata_port *ap);
+static void ata_dev_select(struct ata_port *ap, unsigned int device,
+                       unsigned int wait, unsigned int can_sleep);
+static void ata_qc_issue(struct ata_queued_cmd *qc);
+static void ata_tf_load(struct ata_port *ap,
+                       const struct ata_taskfile *tf);
+static int ata_dev_read_sectors(unsigned char* pdata,
+                       unsigned long datalen, u32 block, u32 n_block);
+static int ata_dev_write_sectors(unsigned char* pdata,
+                       unsigned long datalen , u32 block, u32 n_block);
+static void ata_std_dev_select(struct ata_port *ap, unsigned int device);
+static void ata_qc_complete(struct ata_queued_cmd *qc);
+static void __ata_qc_complete(struct ata_queued_cmd *qc);
+static void fill_result_tf(struct ata_queued_cmd *qc);
+static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+static void ata_mmio_data_xfer(struct ata_device *dev,
+                       unsigned char *buf,
+                       unsigned int buflen,int do_write);
+static void ata_pio_task(struct ata_port *arg_ap);
+static void __ata_port_freeze(struct ata_port *ap);
+static int ata_port_freeze(struct ata_port *ap);
+static void ata_qc_free(struct ata_queued_cmd *qc);
+static void ata_pio_sectors(struct ata_queued_cmd *qc);
+static void ata_pio_sector(struct ata_queued_cmd *qc);
+static void ata_pio_queue_task(struct ata_port *ap,
+                       void *data,unsigned long delay);
+static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq);
+static int sata_dwc_softreset(struct ata_port *ap);
+static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
+               unsigned int flags, u16 *id);
+static int check_sata_dev_state(void);
+
+static const struct ata_port_info sata_dwc_port_info[] = {
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                               ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING |
+                               ATA_FLAG_SRST | ATA_FLAG_NCQ,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+       },
+};
+
+int init_sata(int dev)
+{
+       struct sata_dwc_device hsdev;
+       struct ata_host host;
+       struct ata_port_info pi = sata_dwc_port_info[0];
+       struct ata_link *link;
+       struct sata_dwc_device_port hsdevp = dwc_devp;
+       u8 *base = 0;
+       u8 *sata_dma_regs_addr = 0;
+       u8 status;
+       unsigned long base_addr = 0;
+       int chan = 0;
+       int rc;
+       int i;
+
+       phost = &host;
+
+       base = (u8*)SATA_BASE_ADDR;
+
+       hsdev.sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);
+
+       host.n_ports = SATA_DWC_MAX_PORTS;
+
+       for (i = 0; i < SATA_DWC_MAX_PORTS; i++) {
+               ap.pflags |= ATA_PFLAG_INITIALIZING;
+               ap.flags = ATA_FLAG_DISABLED;
+               ap.print_id = -1;
+               ap.ctl = ATA_DEVCTL_OBS;
+               ap.host = &host;
+               ap.last_ctl = 0xFF;
+
+               link = &ap.link;
+               link->ap = &ap;
+               link->pmp = 0;
+               link->active_tag = ATA_TAG_POISON;
+               link->hw_sata_spd_limit = 0;
+
+               ap.port_no = i;
+               host.ports[i] = &ap;
+       }
+
+       ap.pio_mask = pi.pio_mask;
+       ap.mwdma_mask = pi.mwdma_mask;
+       ap.udma_mask = pi.udma_mask;
+       ap.flags |= pi.flags;
+       ap.link.flags |= pi.link_flags;
+
+       host.ports[0]->ioaddr.cmd_addr = base;
+       host.ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET;
+       scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET;
+
+       base_addr = (unsigned long)base;
+
+       host.ports[0]->ioaddr.cmd_addr = (void *)base_addr + 0x00;
+       host.ports[0]->ioaddr.data_addr = (void *)base_addr + 0x00;
+
+       host.ports[0]->ioaddr.error_addr = (void *)base_addr + 0x04;
+       host.ports[0]->ioaddr.feature_addr = (void *)base_addr + 0x04;
+
+       host.ports[0]->ioaddr.nsect_addr = (void *)base_addr + 0x08;
+
+       host.ports[0]->ioaddr.lbal_addr = (void *)base_addr + 0x0c;
+       host.ports[0]->ioaddr.lbam_addr = (void *)base_addr + 0x10;
+       host.ports[0]->ioaddr.lbah_addr = (void *)base_addr + 0x14;
+
+       host.ports[0]->ioaddr.device_addr = (void *)base_addr + 0x18;
+       host.ports[0]->ioaddr.command_addr = (void *)base_addr + 0x1c;
+       host.ports[0]->ioaddr.status_addr = (void *)base_addr + 0x1c;
+
+       host.ports[0]->ioaddr.altstatus_addr = (void *)base_addr + 0x20;
+       host.ports[0]->ioaddr.ctl_addr = (void *)base_addr + 0x20;
+
+       sata_dma_regs_addr = (u8*)SATA_DMA_REG_ADDR;
+       sata_dma_regs = (void *__iomem)sata_dma_regs_addr;
+
+       status = ata_check_altstatus(&ap);
+
+       if (status == 0x7f) {
+               printf("Hard Disk not found.\n");
+               dev_state = SATA_NODEVICE;
+               rc = false;
+               return rc;
+       }
+
+       printf("Waiting for device...");
+       i = 0;
+       while (1) {
+               udelay(10000);
+
+               status = ata_check_altstatus(&ap);
+
+               if ((status & ATA_BUSY) == 0) {
+                       printf("\n");
+                       break;
+               }
+
+               i++;
+               if (i > (ATA_RESET_TIME * 100)) {
+                       printf("** TimeOUT **\n");
+
+                       dev_state = SATA_NODEVICE;
+                       rc = false;
+                       return rc;
+               }
+               if ((i >= 100) && ((i % 100) == 0))
+                       printf(".");
+       }
+
+       rc = sata_dwc_softreset(&ap);
+
+       if (rc) {
+               printf("sata_dwc : error. soft reset failed\n");
+               return rc;
+       }
+
+       for (chan = 0; chan < DMA_NUM_CHANS; chan++) {
+               out_le32(&(sata_dma_regs->interrupt_mask.error.low),
+                               DMA_DISABLE_CHAN(chan));
+
+               out_le32(&(sata_dma_regs->interrupt_mask.tfr.low),
+                               DMA_DISABLE_CHAN(chan));
+       }
+
+       out_le32(&(sata_dma_regs->dma_cfg.low), DMA_DI);
+
+       out_le32(&hsdev.sata_dwc_regs->intmr,
+               SATA_DWC_INTMR_ERRM |
+               SATA_DWC_INTMR_PMABRTM);
+
+       /* Unmask the error bits that should trigger
+        * an error interrupt by setting the error mask register.
+        */
+       out_le32(&hsdev.sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS);
+
+       hsdev.host = ap.host;
+       memset(&hsdevp, 0, sizeof(hsdevp));
+       hsdevp.hsdev = &hsdev;
+
+       for (i = 0; i < SATA_DWC_QCMD_MAX; i++)
+               hsdevp.cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT;
+
+       out_le32((void __iomem *)scr_addr_sstatus + 4,
+               in_le32((void __iomem *)scr_addr_sstatus + 4));
+
+       rc = 0;
+       return rc;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+static u8 ata_check_altstatus(struct ata_port *ap)
+{
+       u8 val = 0;
+       val = readb(ap->ioaddr.altstatus_addr);
+       return val;
+}
+
+static int sata_dwc_softreset(struct ata_port *ap)
+{
+       u8 nsect,lbal = 0;
+       u8 tmp = 0;
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       in_le32((void *)ap->ioaddr.scr_addr + (SCR_ERROR * 4));
+
+       writeb(0x55, ioaddr->nsect_addr);
+       writeb(0xaa, ioaddr->lbal_addr);
+       writeb(0xaa, ioaddr->nsect_addr);
+       writeb(0x55, ioaddr->lbal_addr);
+       writeb(0x55, ioaddr->nsect_addr);
+       writeb(0xaa, ioaddr->lbal_addr);
+
+       nsect = readb(ioaddr->nsect_addr);
+       lbal = readb(ioaddr->lbal_addr);
+
+       if ((nsect == 0x55) && (lbal == 0xaa)) {
+               printf("Device found\n");
+       } else {
+               printf("No device found\n");
+               dev_state = SATA_NODEVICE;
+               return false;
+       }
+
+       tmp = ATA_DEVICE_OBS;
+       writeb(tmp, ioaddr->device_addr);
+       writeb(ap->ctl, ioaddr->ctl_addr);
+
+       udelay(200);
+
+       writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+
+       udelay(200);
+       writeb(ap->ctl, ioaddr->ctl_addr);
+
+       msleep(150);
+       ata_check_status(ap);
+
+       msleep(50);
+       ata_check_status(ap);
+
+       while (1) {
+               u8 status = ata_check_status(ap);
+
+               if (!(status & ATA_BUSY))
+                       break;
+
+               printf("Hard Disk status is BUSY.\n");
+               msleep(50);
+       }
+
+       tmp = ATA_DEVICE_OBS;
+       writeb(tmp, ioaddr->device_addr);
+
+       nsect = readb(ioaddr->nsect_addr);
+       lbal = readb(ioaddr->lbal_addr);
+
+       return 0;
+}
+
+static u8 ata_check_status(struct ata_port *ap)
+{
+       u8 val = 0;
+       val = readb(ap->ioaddr.status_addr);
+       return val;
+}
+
+static int ata_id_has_hipm(const u16 *id)
+{
+       u16 val = id[76];
+
+       if (val == 0 || val == 0xffff)
+               return -1;
+
+       return val & (1 << 9);
+}
+
+static int ata_id_has_dipm(const u16 *id)
+{
+       u16 val = id[78];
+
+       if (val == 0 || val == 0xffff)
+               return -1;
+
+       return val & (1 << 3);
+}
+
+int scan_sata(int dev)
+{
+       int i;
+       int rc;
+       u8 status;
+       const u16 *id;
+       struct ata_device *ata_dev = &ata_device;
+       unsigned long pio_mask, mwdma_mask;
+       char revbuf[7];
+       u16 iobuf[ATA_SECTOR_WORDS];
+
+       memset(iobuf, 0, sizeof(iobuf));
+
+       if (dev_state == SATA_NODEVICE)
+               return 1;
+
+       printf("Waiting for device...");
+       i = 0;
+       while (1) {
+               udelay(10000);
+
+               status = ata_check_altstatus(&ap);
+
+               if ((status & ATA_BUSY) == 0) {
+                       printf("\n");
+                       break;
+               }
+
+               i++;
+               if (i > (ATA_RESET_TIME * 100)) {
+                       printf("** TimeOUT **\n");
+
+                       dev_state = SATA_NODEVICE;
+                       return 1;
+               }
+               if ((i >= 100) && ((i % 100) == 0))
+                       printf(".");
+       }
+
+       udelay(1000);
+
+       rc = ata_dev_read_id(ata_dev, &ata_dev->class,
+                       ATA_READID_POSTRESET,ata_dev->id);
+       if (rc) {
+               printf("sata_dwc : error. failed sata scan\n");
+               return 1;
+       }
+
+       /* SATA drives indicate we have a bridge. We don't know which
+        * end of the link the bridge is which is a problem
+        */
+       if (ata_id_is_sata(ata_dev->id))
+               ap.cbl = ATA_CBL_SATA;
+
+       id = ata_dev->id;
+
+       ata_dev->flags &= ~ATA_DFLAG_CFG_MASK;
+       ata_dev->max_sectors = 0;
+       ata_dev->cdb_len = 0;
+       ata_dev->n_sectors = 0;
+       ata_dev->cylinders = 0;
+       ata_dev->heads = 0;
+       ata_dev->sectors = 0;
+
+       if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
+               pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
+               pio_mask <<= 3;
+               pio_mask |= 0x7;
+       } else {
+               /* If word 64 isn't valid then Word 51 high byte holds
+                * the PIO timing number for the maximum. Turn it into
+                * a mask.
+                */
+               u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF;
+               if (mode < 5) {
+                       pio_mask = (2 << mode) - 1;
+               } else {
+                       pio_mask = 1;
+               }
+       }
+
+       mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
+
+       if (ata_id_is_cfa(id)) {
+               int pio = id[163] & 0x7;
+               int dma = (id[163] >> 3) & 7;
+
+               if (pio)
+                       pio_mask |= (1 << 5);
+               if (pio > 1)
+                       pio_mask |= (1 << 6);
+               if (dma)
+                       mwdma_mask |= (1 << 3);
+               if (dma > 1)
+                       mwdma_mask |= (1 << 4);
+       }
+
+       if (ata_dev->class == ATA_DEV_ATA) {
+               if (ata_id_is_cfa(id)) {
+                       if (id[162] & 1)
+                               printf("supports DRM functions and may "
+                                       "not be fully accessable.\n");
+                       strcpy(revbuf, "CFA");
+               } else {
+                       if (ata_id_has_tpm(id))
+                               printf("supports DRM functions and may "
+                                               "not be fully accessable.\n");
+               }
+
+               ata_dev->n_sectors = ata_id_n_sectors((u16*)id);
+
+               if (ata_dev->id[59] & 0x100)
+                       ata_dev->multi_count = ata_dev->id[59] & 0xff;
+
+               if (ata_id_has_lba(id)) {
+                       char ncq_desc[20];
+
+                       ata_dev->flags |= ATA_DFLAG_LBA;
+                       if (ata_id_has_lba48(id)) {
+                               ata_dev->flags |= ATA_DFLAG_LBA48;
+
+                               if (ata_dev->n_sectors >= (1UL << 28) &&
+                                       ata_id_has_flush_ext(id))
+                                       ata_dev->flags |= ATA_DFLAG_FLUSH_EXT;
+                       }
+                       if (!ata_id_has_ncq(ata_dev->id))
+                               ncq_desc[0] = '\0';
+
+                       if (ata_dev->horkage & ATA_HORKAGE_NONCQ)
+                               strcpy(ncq_desc, "NCQ (not used)");
+
+                       if (ap.flags & ATA_FLAG_NCQ)
+                               ata_dev->flags |= ATA_DFLAG_NCQ;
+               }
+               ata_dev->cdb_len = 16;
+       }
+       ata_dev->max_sectors = ATA_MAX_SECTORS;
+       if (ata_dev->flags & ATA_DFLAG_LBA48)
+               ata_dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
+       if (!(ata_dev->horkage & ATA_HORKAGE_IPM)) {
+               if (ata_id_has_hipm(ata_dev->id))
+                       ata_dev->flags |= ATA_DFLAG_HIPM;
+               if (ata_id_has_dipm(ata_dev->id))
+                       ata_dev->flags |= ATA_DFLAG_DIPM;
+       }
+
+       if ((ap.cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ata_dev->id))) {
+               ata_dev->udma_mask &= ATA_UDMA5;
+               ata_dev->max_sectors = ATA_MAX_SECTORS;
+       }
+
+       if (ata_dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
+               printf("Drive reports diagnostics failure."
+                               "This may indicate a drive\n");
+               printf("fault or invalid emulation."
+                               "Contact drive vendor for information.\n");
+       }
+
+       rc = check_sata_dev_state();
+
+       ata_id_c_string(ata_dev->id,
+                       (unsigned char *)sata_dev_desc[dev].revision,
+                        ATA_ID_FW_REV, sizeof(sata_dev_desc[dev].revision));
+       ata_id_c_string(ata_dev->id,
+                       (unsigned char *)sata_dev_desc[dev].vendor,
+                        ATA_ID_PROD, sizeof(sata_dev_desc[dev].vendor));
+       ata_id_c_string(ata_dev->id,
+                       (unsigned char *)sata_dev_desc[dev].product,
+                        ATA_ID_SERNO, sizeof(sata_dev_desc[dev].product));
+
+       sata_dev_desc[dev].lba = (u32) ata_dev->n_sectors;
+
+#ifdef CONFIG_LBA48
+       if (ata_dev->id[83] & (1 << 10)) {
+               sata_dev_desc[dev].lba48 = 1;
+       } else {
+               sata_dev_desc[dev].lba48 = 0;
+       }
+#endif
+
+       return 0;
+}
+
+static u8 ata_busy_wait(struct ata_port *ap,
+               unsigned int bits,unsigned int max)
+{
+       u8 status;
+
+       do {
+               udelay(10);
+               status = ata_check_status(ap);
+               max--;
+       } while (status != 0xff && (status & bits) && (max > 0));
+
+       return status;
+}
+
+static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
+               unsigned int flags, u16 *id)
+{
+       struct ata_port *ap = pap;
+       unsigned int class = *p_class;
+       struct ata_taskfile tf;
+       unsigned int err_mask = 0;
+       const char *reason;
+       int may_fallback = 1, tried_spinup = 0;
+       u8 status;
+       int rc;
+
+       status = ata_busy_wait(ap, ATA_BUSY, 30000);
+       if (status & ATA_BUSY) {
+               printf("BSY = 0 check. timeout.\n");
+               rc = false;
+               return rc;
+       }
+
+       ata_dev_select(ap, dev->devno, 1, 1);
+
+retry:
+       memset(&tf, 0, sizeof(tf));
+       ap->print_id = 1;
+       ap->flags &= ~ATA_FLAG_DISABLED;
+       tf.ctl = ap->ctl;
+       tf.device = ATA_DEVICE_OBS;
+       tf.command = ATA_CMD_ID_ATA;
+       tf.protocol = ATA_PROT_PIO;
+
+       /* Some devices choke if TF registers contain garbage.  Make
+        * sure those are properly initialized.
+        */
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+
+       /* Device presence detection is unreliable on some
+        * controllers.  Always poll IDENTIFY if available.
+        */
+       tf.flags |= ATA_TFLAG_POLLING;
+
+       temp_n_block = 1;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
+                                       sizeof(id[0]) * ATA_ID_WORDS, 0);
+
+       if (err_mask) {
+               if (err_mask & AC_ERR_NODEV_HINT) {
+                       printf("NODEV after polling detection\n");
+                       return -ENOENT;
+               }
+
+               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       /* Device or controller might have reported
+                        * the wrong device class.  Give a shot at the
+                        * other IDENTIFY if the current one is
+                        * aborted by the device.
+                        */
+                       if (may_fallback) {
+                               may_fallback = 0;
+
+                               if (class == ATA_DEV_ATA) {
+                                       class = ATA_DEV_ATAPI;
+                               } else {
+                                       class = ATA_DEV_ATA;
+                               }
+                               goto retry;
+                       }
+                       /* Control reaches here iff the device aborted
+                        * both flavors of IDENTIFYs which happens
+                        * sometimes with phantom devices.
+                        */
+                       printf("both IDENTIFYs aborted, assuming NODEV\n");
+                       return -ENOENT;
+               }
+               rc = -EIO;
+               reason = "I/O error";
+               goto err_out;
+       }
+
+       /* Falling back doesn't make sense if ID data was read
+        * successfully at least once.
+        */
+       may_fallback = 0;
+
+       unsigned int id_cnt;
+
+       for (id_cnt = 0; id_cnt < ATA_ID_WORDS; id_cnt++)
+               id[id_cnt] = le16_to_cpu(id[id_cnt]);
+
+
+       rc = -EINVAL;
+       reason = "device reports invalid type";
+
+       if (class == ATA_DEV_ATA) {
+               if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
+                       goto err_out;
+       } else {
+               if (ata_id_is_ata(id))
+                       goto err_out;
+       }
+       if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
+               tried_spinup = 1;
+               /*
+                * Drive powered-up in standby mode, and requires a specific
+                * SET_FEATURES spin-up subcommand before it will accept
+                * anything other than the original IDENTIFY command.
+                */
+               err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
+               if (err_mask && id[2] != 0x738c) {
+                       rc = -EIO;
+                       reason = "SPINUP failed";
+                       goto err_out;
+               }
+               /*
+                * If the drive initially returned incomplete IDENTIFY info,
+                * we now must reissue the IDENTIFY command.
+                */
+               if (id[2] == 0x37c8)
+                       goto retry;
+       }
+
+       if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
+               /*
+                * The exact sequence expected by certain pre-ATA4 drives is:
+                * SRST RESET
+                * IDENTIFY (optional in early ATA)
+                * INITIALIZE DEVICE PARAMETERS (later IDE and ATA)
+                * anything else..
+                * Some drives were very specific about that exact sequence.
+                *
+                * Note that ATA4 says lba is mandatory so the second check
+                * shoud never trigger.
+                */
+               if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
+                       err_mask = ata_dev_init_params(dev, id[3], id[6]);
+                       if (err_mask) {
+                               rc = -EIO;
+                               reason = "INIT_DEV_PARAMS failed";
+                               goto err_out;
+                       }
+
+                       /* current CHS translation info (id[53-58]) might be
+                        * changed. reread the identify device info.
+                        */
+                       flags &= ~ATA_READID_POSTRESET;
+                       goto retry;
+               }
+       }
+
+       *p_class = class;
+       return 0;
+
+err_out:
+       printf("failed to READ ID (%s, err_mask=0x%x)\n", reason, err_mask);
+       return rc;
+}
+
+static u8 ata_wait_idle(struct ata_port *ap)
+{
+       u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+       return status;
+}
+
+static void ata_dev_select(struct ata_port *ap, unsigned int device,
+               unsigned int wait, unsigned int can_sleep)
+{
+       if (wait)
+               ata_wait_idle(ap);
+
+       ata_std_dev_select(ap, device);
+
+       if (wait)
+               ata_wait_idle(ap);
+}
+
+static void ata_std_dev_select(struct ata_port *ap, unsigned int device)
+{
+       u8 tmp;
+
+       if (device == 0) {
+               tmp = ATA_DEVICE_OBS;
+       } else {
+               tmp = ATA_DEVICE_OBS | ATA_DEV1;
+       }
+
+       writeb(tmp, ap->ioaddr.device_addr);
+
+       readb(ap->ioaddr.altstatus_addr);
+
+       udelay(1);
+}
+
+static int waiting_for_reg_state(volatile u8 *offset,
+                               int timeout_msec,
+                               u32 sign)
+{
+       int i;
+       u32 status;
+
+       for (i = 0; i < timeout_msec; i++) {
+               status = readl(offset);
+               if ((status & sign) != 0)
+                       break;
+               msleep(1);
+       }
+
+       return (i < timeout_msec) ? 0 : -1;
+}
+
+static void ata_qc_reinit(struct ata_queued_cmd *qc)
+{
+       qc->dma_dir = DMA_NONE;
+       qc->flags = 0;
+       qc->nbytes = qc->extrabytes = qc->curbytes = 0;
+       qc->n_elem = 0;
+       qc->err_mask = 0;
+       qc->sect_size = ATA_SECT_SIZE;
+       qc->nbytes = ATA_SECT_SIZE * temp_n_block;
+
+       memset(&qc->tf, 0, sizeof(qc->tf));
+       qc->tf.ctl = 0;
+       qc->tf.device = ATA_DEVICE_OBS;
+
+       qc->result_tf.command = ATA_DRDY;
+       qc->result_tf.feature = 0;
+}
+
+struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
+                                       unsigned int tag)
+{
+       if (tag < ATA_MAX_QUEUE)
+               return &ap->qcmd[tag];
+       return NULL;
+}
+
+static void __ata_port_freeze(struct ata_port *ap)
+{
+       printf("set port freeze.\n");
+       ap->pflags |= ATA_PFLAG_FROZEN;
+}
+
+static int ata_port_freeze(struct ata_port *ap)
+{
+       __ata_port_freeze(ap);
+       return 0;
+}
+
+unsigned ata_exec_internal(struct ata_device *dev,
+                       struct ata_taskfile *tf, const u8 *cdb,
+                       int dma_dir, unsigned int buflen,
+                       unsigned long timeout)
+{
+       struct ata_link *link = dev->link;
+       struct ata_port *ap = pap;
+       struct ata_queued_cmd *qc;
+       unsigned int tag, preempted_tag;
+       u32 preempted_sactive, preempted_qc_active;
+       int preempted_nr_active_links;
+       unsigned int err_mask;
+       int rc = 0;
+       u8 status;
+
+       status = ata_busy_wait(ap, ATA_BUSY, 300000);
+       if (status & ATA_BUSY) {
+               printf("BSY = 0 check. timeout.\n");
+               rc = false;
+               return rc;
+       }
+
+       if (ap->pflags & ATA_PFLAG_FROZEN)
+               return AC_ERR_SYSTEM;
+
+       tag = ATA_TAG_INTERNAL;
+
+       if (test_and_set_bit(tag, &ap->qc_allocated)) {
+               rc = false;
+               return rc;
+       }
+
+       qc = __ata_qc_from_tag(ap, tag);
+       qc->tag = tag;
+       qc->ap = ap;
+       qc->dev = dev;
+
+       ata_qc_reinit(qc);
+
+       preempted_tag = link->active_tag;
+       preempted_sactive = link->sactive;
+       preempted_qc_active = ap->qc_active;
+       preempted_nr_active_links = ap->nr_active_links;
+       link->active_tag = ATA_TAG_POISON;
+       link->sactive = 0;
+       ap->qc_active = 0;
+       ap->nr_active_links = 0;
+
+       qc->tf = *tf;
+       if (cdb)
+               memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+       qc->flags |= ATA_QCFLAG_RESULT_TF;
+       qc->dma_dir = dma_dir;
+       qc->private_data = 0;
+
+       ata_qc_issue(qc);
+
+       if (!timeout)
+               timeout = ata_probe_timeout * 1000 / HZ;
+
+       status = ata_busy_wait(ap, ATA_BUSY, 30000);
+       if (status & ATA_BUSY) {
+               printf("BSY = 0 check. timeout.\n");
+               printf("altstatus = 0x%x.\n", status);
+               qc->err_mask |= AC_ERR_OTHER;
+               return qc->err_mask;
+       }
+
+       if (waiting_for_reg_state(ap->ioaddr.altstatus_addr, 1000, 0x8)) {
+               u8 status = 0;
+               u8 errorStatus = 0;
+
+               status = readb(ap->ioaddr.altstatus_addr);
+               if ((status & 0x01) != 0) {
+                       errorStatus = readb(ap->ioaddr.feature_addr);
+                       if (errorStatus == 0x04 &&
+                               qc->tf.command == ATA_CMD_PIO_READ_EXT){
+                               printf("Hard Disk doesn't support LBA48\n");
+                               dev_state = SATA_ERROR;
+                               qc->err_mask |= AC_ERR_OTHER;
+                               return qc->err_mask;
+                       }
+               }
+               qc->err_mask |= AC_ERR_OTHER;
+               return qc->err_mask;
+       }
+
+       status = ata_busy_wait(ap, ATA_BUSY, 10);
+       if (status & ATA_BUSY) {
+               printf("BSY = 0 check. timeout.\n");
+               qc->err_mask |= AC_ERR_OTHER;
+               return qc->err_mask;
+       }
+
+       ata_pio_task(ap);
+
+       if (!rc) {
+               if (qc->flags & ATA_QCFLAG_ACTIVE) {
+                       qc->err_mask |= AC_ERR_TIMEOUT;
+                       ata_port_freeze(ap);
+               }
+       }
+
+       if (qc->flags & ATA_QCFLAG_FAILED) {
+               if (qc->result_tf.command & (ATA_ERR | ATA_DF))
+                       qc->err_mask |= AC_ERR_DEV;
+
+               if (!qc->err_mask)
+                       qc->err_mask |= AC_ERR_OTHER;
+
+               if (qc->err_mask & ~AC_ERR_OTHER)
+                       qc->err_mask &= ~AC_ERR_OTHER;
+       }
+
+       *tf = qc->result_tf;
+       err_mask = qc->err_mask;
+       ata_qc_free(qc);
+       link->active_tag = preempted_tag;
+       link->sactive = preempted_sactive;
+       ap->qc_active = preempted_qc_active;
+       ap->nr_active_links = preempted_nr_active_links;
+
+       if (ap->flags & ATA_FLAG_DISABLED) {
+               err_mask |= AC_ERR_SYSTEM;
+               ap->flags &= ~ATA_FLAG_DISABLED;
+       }
+
+       return err_mask;
+}
+
+static void ata_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_link *link = qc->dev->link;
+       u8 prot = qc->tf.protocol;
+
+       if (ata_is_ncq(prot)) {
+               if (!link->sactive)
+                       ap->nr_active_links++;
+               link->sactive |= 1 << qc->tag;
+       } else {
+               ap->nr_active_links++;
+               link->active_tag = qc->tag;
+       }
+
+       qc->flags |= ATA_QCFLAG_ACTIVE;
+       ap->qc_active |= 1 << qc->tag;
+
+       if (qc->dev->flags & ATA_DFLAG_SLEEPING) {
+               msleep(1);
+               return;
+       }
+
+       qc->err_mask |= ata_qc_issue_prot(qc);
+       if (qc->err_mask)
+               goto err;
+
+       return;
+err:
+       ata_qc_complete(qc);
+}
+
+static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       if (ap->flags & ATA_FLAG_PIO_POLLING) {
+               switch (qc->tf.protocol) {
+               case ATA_PROT_PIO:
+               case ATA_PROT_NODATA:
+               case ATAPI_PROT_PIO:
+               case ATAPI_PROT_NODATA:
+                       qc->tf.flags |= ATA_TFLAG_POLLING;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ata_dev_select(ap, qc->dev->devno, 1, 0);
+
+       switch (qc->tf.protocol) {
+       case ATA_PROT_PIO:
+               if (qc->tf.flags & ATA_TFLAG_POLLING)
+                       qc->tf.ctl |= ATA_NIEN;
+
+               ata_tf_to_host(ap, &qc->tf);
+
+               ap->hsm_task_state = HSM_ST;
+
+               if (qc->tf.flags & ATA_TFLAG_POLLING)
+                       ata_pio_queue_task(ap, qc, 0);
+
+               break;
+
+       default:
+               return AC_ERR_SYSTEM;
+       }
+
+       return 0;
+}
+
+static void ata_tf_to_host(struct ata_port *ap,
+                       const struct ata_taskfile *tf)
+{
+       ata_tf_load(ap, tf);
+       ata_exec_command(ap, tf);
+}
+
+static void ata_tf_load(struct ata_port *ap,
+                       const struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+       if (tf->ctl != ap->last_ctl) {
+               if (ioaddr->ctl_addr)
+                       writeb(tf->ctl, ioaddr->ctl_addr);
+               ap->last_ctl = tf->ctl;
+               ata_wait_idle(ap);
+       }
+
+       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+               writeb(tf->hob_feature, ioaddr->feature_addr);
+               writeb(tf->hob_nsect, ioaddr->nsect_addr);
+               writeb(tf->hob_lbal, ioaddr->lbal_addr);
+               writeb(tf->hob_lbam, ioaddr->lbam_addr);
+               writeb(tf->hob_lbah, ioaddr->lbah_addr);
+       }
+
+       if (is_addr) {
+               writeb(tf->feature, ioaddr->feature_addr);
+               writeb(tf->nsect, ioaddr->nsect_addr);
+               writeb(tf->lbal, ioaddr->lbal_addr);
+               writeb(tf->lbam, ioaddr->lbam_addr);
+               writeb(tf->lbah, ioaddr->lbah_addr);
+       }
+
+       if (tf->flags & ATA_TFLAG_DEVICE)
+               writeb(tf->device, ioaddr->device_addr);
+
+       ata_wait_idle(ap);
+}
+
+static void ata_exec_command(struct ata_port *ap,
+                       const struct ata_taskfile *tf)
+{
+       writeb(tf->command, ap->ioaddr.command_addr);
+
+       readb(ap->ioaddr.altstatus_addr);
+
+       udelay(1);
+}
+
+static void ata_pio_queue_task(struct ata_port *ap,
+                       void *data,unsigned long delay)
+{
+       ap->port_task_data = data;
+}
+
+static unsigned int ac_err_mask(u8 status)
+{
+       if (status & (ATA_BUSY | ATA_DRQ))
+               return AC_ERR_HSM;
+       if (status & (ATA_ERR | ATA_DF))
+               return AC_ERR_DEV;
+       return 0;
+}
+
+static unsigned int __ac_err_mask(u8 status)
+{
+       unsigned int mask = ac_err_mask(status);
+       if (mask == 0)
+               return AC_ERR_OTHER;
+       return mask;
+}
+
+static void ata_pio_task(struct ata_port *arg_ap)
+{
+       struct ata_port *ap = arg_ap;
+       struct ata_queued_cmd *qc = ap->port_task_data;
+       u8 status;
+       int poll_next;
+
+fsm_start:
+       /*
+        * This is purely heuristic.  This is a fast path.
+        * Sometimes when we enter, BSY will be cleared in
+        * a chk-status or two.  If not, the drive is probably seeking
+        * or something.  Snooze for a couple msecs, then
+        * chk-status again.  If still busy, queue delayed work.
+        */
+       status = ata_busy_wait(ap, ATA_BUSY, 5);
+       if (status & ATA_BUSY) {
+               msleep(2);
+               status = ata_busy_wait(ap, ATA_BUSY, 10);
+               if (status & ATA_BUSY) {
+                       ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
+                       return;
+               }
+       }
+
+       poll_next = ata_hsm_move(ap, qc, status, 1);
+
+       /* another command or interrupt handler
+        * may be running at this point.
+        */
+       if (poll_next)
+               goto fsm_start;
+}
+
+static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+                       u8 status, int in_wq)
+{
+       int poll_next;
+
+fsm_start:
+       switch (ap->hsm_task_state) {
+       case HSM_ST_FIRST:
+               poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
+
+               if ((status & ATA_DRQ) == 0) {
+                       if (status & (ATA_ERR | ATA_DF)) {
+                               qc->err_mask |= AC_ERR_DEV;
+                       } else {
+                               qc->err_mask |= AC_ERR_HSM;
+                       }
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+
+               /* Device should not ask for data transfer (DRQ=1)
+                * when it finds something wrong.
+                * We ignore DRQ here and stop the HSM by
+                * changing hsm_task_state to HSM_ST_ERR and
+                * let the EH abort the command or reset the device.
+                */
+               if (status & (ATA_ERR | ATA_DF)) {
+                       if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
+                               printf("DRQ=1 with device error, "
+                                       "dev_stat 0x%X\n", status);
+                               qc->err_mask |= AC_ERR_HSM;
+                               ap->hsm_task_state = HSM_ST_ERR;
+                               goto fsm_start;
+                       }
+               }
+
+               if (qc->tf.protocol == ATA_PROT_PIO) {
+                       /* PIO data out protocol.
+                        * send first data block.
+                        */
+                       /* ata_pio_sectors() might change the state
+                        * to HSM_ST_LAST. so, the state is changed here
+                        * before ata_pio_sectors().
+                        */
+                       ap->hsm_task_state = HSM_ST;
+                       ata_pio_sectors(qc);
+               } else {
+                       printf("protocol is not ATA_PROT_PIO \n");
+               }
+               break;
+
+       case HSM_ST:
+               if ((status & ATA_DRQ) == 0) {
+                       if (status & (ATA_ERR | ATA_DF)) {
+                               qc->err_mask |= AC_ERR_DEV;
+                       } else {
+                               /* HSM violation. Let EH handle this.
+                                * Phantom devices also trigger this
+                                * condition.  Mark hint.
+                                */
+                               qc->err_mask |= AC_ERR_HSM | AC_ERR_NODEV_HINT;
+                       }
+
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+               /* For PIO reads, some devices may ask for
+                * data transfer (DRQ=1) alone with ERR=1.
+                * We respect DRQ here and transfer one
+                * block of junk data before changing the
+                * hsm_task_state to HSM_ST_ERR.
+                *
+                * For PIO writes, ERR=1 DRQ=1 doesn't make
+                * sense since the data block has been
+                * transferred to the device.
+                */
+               if (status & (ATA_ERR | ATA_DF)) {
+                       qc->err_mask |= AC_ERR_DEV;
+
+                       if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+                               ata_pio_sectors(qc);
+                               status = ata_wait_idle(ap);
+                       }
+
+                       if (status & (ATA_BUSY | ATA_DRQ))
+                               qc->err_mask |= AC_ERR_HSM;
+
+                       /* ata_pio_sectors() might change the
+                        * state to HSM_ST_LAST. so, the state
+                        * is changed after ata_pio_sectors().
+                        */
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+
+               ata_pio_sectors(qc);
+               if (ap->hsm_task_state == HSM_ST_LAST &&
+                       (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
+                       status = ata_wait_idle(ap);
+                       goto fsm_start;
+               }
+
+               poll_next = 1;
+               break;
+
+       case HSM_ST_LAST:
+               if (!ata_ok(status)) {
+                       qc->err_mask |= __ac_err_mask(status);
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+
+               ap->hsm_task_state = HSM_ST_IDLE;
+
+               ata_hsm_qc_complete(qc, in_wq);
+
+               poll_next = 0;
+               break;
+
+       case HSM_ST_ERR:
+               /* make sure qc->err_mask is available to
+                * know what's wrong and recover
+                */
+               ap->hsm_task_state = HSM_ST_IDLE;
+
+               ata_hsm_qc_complete(qc, in_wq);
+
+               poll_next = 0;
+               break;
+       default:
+               poll_next = 0;
+       }
+
+       return poll_next;
+}
+
+static void ata_pio_sectors(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap;
+       ap = pap;
+       qc->pdata = ap->pdata;
+
+       ata_pio_sector(qc);
+
+       readb(qc->ap->ioaddr.altstatus_addr);
+       udelay(1);
+}
+
+static void ata_pio_sector(struct ata_queued_cmd *qc)
+{
+       int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
+       struct ata_port *ap = qc->ap;
+       unsigned int offset;
+       unsigned char *buf;
+       char temp_data_buf[512];
+
+       if (qc->curbytes == qc->nbytes - qc->sect_size)
+               ap->hsm_task_state = HSM_ST_LAST;
+
+       offset = qc->curbytes;
+
+       switch (qc->tf.command) {
+       case ATA_CMD_ID_ATA:
+               buf = (unsigned char *)&ata_device.id[0];
+               break;
+       case ATA_CMD_PIO_READ_EXT:
+       case ATA_CMD_PIO_READ:
+       case ATA_CMD_PIO_WRITE_EXT:
+       case ATA_CMD_PIO_WRITE:
+               buf = qc->pdata + offset;
+               break;
+       default:
+               buf = (unsigned char *)&temp_data_buf[0];
+       }
+
+       ata_mmio_data_xfer(qc->dev, buf, qc->sect_size, do_write);
+
+       qc->curbytes += qc->sect_size;
+
+}
+
+static void ata_mmio_data_xfer(struct ata_device *dev, unsigned char *buf,
+                               unsigned int buflen, int do_write)
+{
+       struct ata_port *ap = pap;
+       void __iomem *data_addr = ap->ioaddr.data_addr;
+       unsigned int words = buflen >> 1;
+       u16 *buf16 = (u16 *)buf;
+       unsigned int i = 0;
+
+       udelay(100);
+       if (do_write) {
+               for (i = 0; i < words; i++)
+                       writew(le16_to_cpu(buf16[i]), data_addr);
+       } else {
+               for (i = 0; i < words; i++)
+                       buf16[i] = cpu_to_le16(readw(data_addr));
+       }
+
+       if (buflen & 0x01) {
+               __le16 align_buf[1] = { 0 };
+               unsigned char *trailing_buf = buf + buflen - 1;
+
+               if (do_write) {
+                       memcpy(align_buf, trailing_buf, 1);
+                       writew(le16_to_cpu(align_buf[0]), data_addr);
+               } else {
+                       align_buf[0] = cpu_to_le16(readw(data_addr));
+                       memcpy(trailing_buf, align_buf, 1);
+               }
+       }
+}
+
+static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
+{
+       struct ata_port *ap = qc->ap;
+
+       if (in_wq) {
+               /* EH might have kicked in while host lock is
+                * released.
+                */
+               qc = &ap->qcmd[qc->tag];
+               if (qc) {
+                       if (!(qc->err_mask & AC_ERR_HSM)) {
+                               ata_irq_on(ap);
+                               ata_qc_complete(qc);
+                       } else {
+                               ata_port_freeze(ap);
+                       }
+               }
+       } else {
+               if (!(qc->err_mask & AC_ERR_HSM)) {
+                       ata_qc_complete(qc);
+               } else {
+                       ata_port_freeze(ap);
+               }
+       }
+}
+
+static u8 ata_irq_on(struct ata_port *ap)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       u8 tmp;
+
+       ap->ctl &= ~ATA_NIEN;
+       ap->last_ctl = ap->ctl;
+
+       if (ioaddr->ctl_addr)
+               writeb(ap->ctl, ioaddr->ctl_addr);
+
+       tmp = ata_wait_idle(ap);
+
+       return tmp;
+}
+
+static unsigned int ata_tag_internal(unsigned int tag)
+{
+       return tag == ATA_MAX_QUEUE - 1;
+}
+
+static void ata_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct ata_device *dev = qc->dev;
+       if (qc->err_mask)
+               qc->flags |= ATA_QCFLAG_FAILED;
+
+       if (qc->flags & ATA_QCFLAG_FAILED) {
+               if (!ata_tag_internal(qc->tag)) {
+                       fill_result_tf(qc);
+                       return;
+               }
+       }
+       if (qc->flags & ATA_QCFLAG_RESULT_TF)
+               fill_result_tf(qc);
+
+       /* Some commands need post-processing after successful
+        * completion.
+        */
+       switch (qc->tf.command) {
+       case ATA_CMD_SET_FEATURES:
+               if (qc->tf.feature != SETFEATURES_WC_ON &&
+                               qc->tf.feature != SETFEATURES_WC_OFF)
+                       break;
+       case ATA_CMD_INIT_DEV_PARAMS:
+       case ATA_CMD_SET_MULTI:
+               break;
+
+       case ATA_CMD_SLEEP:
+               dev->flags |= ATA_DFLAG_SLEEPING;
+               break;
+       }
+
+       __ata_qc_complete(qc);
+}
+
+static void fill_result_tf(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       qc->result_tf.flags = qc->tf.flags;
+       ata_tf_read(ap, &qc->result_tf);
+}
+
+static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       tf->command = ata_check_status(ap);
+       tf->feature = readb(ioaddr->error_addr);
+       tf->nsect = readb(ioaddr->nsect_addr);
+       tf->lbal = readb(ioaddr->lbal_addr);
+       tf->lbam = readb(ioaddr->lbam_addr);
+       tf->lbah = readb(ioaddr->lbah_addr);
+       tf->device = readb(ioaddr->device_addr);
+
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               if (ioaddr->ctl_addr) {
+                       writeb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
+
+                       tf->hob_feature = readb(ioaddr->error_addr);
+                       tf->hob_nsect = readb(ioaddr->nsect_addr);
+                       tf->hob_lbal = readb(ioaddr->lbal_addr);
+                       tf->hob_lbam = readb(ioaddr->lbam_addr);
+                       tf->hob_lbah = readb(ioaddr->lbah_addr);
+
+                       writeb(tf->ctl, ioaddr->ctl_addr);
+                       ap->last_ctl = tf->ctl;
+               } else {
+                       printf("sata_dwc warnning register read.\n");
+               }
+       }
+}
+
+static void __ata_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_link *link = qc->dev->link;
+
+       link->active_tag = ATA_TAG_POISON;
+       ap->nr_active_links--;
+
+       if (qc->flags & ATA_QCFLAG_CLEAR_EXCL && ap->excl_link == link)
+               ap->excl_link = NULL;
+
+       qc->flags &= ~ATA_QCFLAG_ACTIVE;
+       ap->qc_active &= ~(1 << qc->tag);
+}
+
+static void ata_qc_free(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       unsigned int tag;
+       qc->flags = 0;
+       tag = qc->tag;
+       if (tag < ATA_MAX_QUEUE) {
+               qc->tag = ATA_TAG_POISON;
+               clear_bit(tag, &ap->qc_allocated);
+       }
+}
+
+static int check_sata_dev_state(void)
+{
+       unsigned long datalen;
+       unsigned char *pdata;
+       int ret = 0;
+       int i = 0;
+       char temp_data_buf[512];
+
+       while (1) {
+               udelay(10000);
+
+               pdata = (unsigned char*)&temp_data_buf[0];
+               datalen = 512;
+
+               ret = ata_dev_read_sectors(pdata, datalen, 0, 1);
+
+               if (ret == true)
+                       break;
+
+               i++;
+               if (i > (ATA_RESET_TIME * 100)) {
+                       printf("** TimeOUT **\n");
+                       dev_state = SATA_NODEVICE;
+                       return false;
+               }
+
+               if ((i >= 100) && ((i % 100) == 0))
+                       printf(".");
+       }
+
+       dev_state = SATA_READY;
+
+       return true;
+}
+
+static unsigned int ata_dev_set_feature(struct ata_device *dev,
+                               u8 enable, u8 feature)
+{
+       struct ata_taskfile tf;
+       struct ata_port *ap;
+       ap = pap;
+       unsigned int err_mask;
+
+       memset(&tf, 0, sizeof(tf));
+       tf.ctl = ap->ctl;
+
+       tf.device = ATA_DEVICE_OBS;
+       tf.command = ATA_CMD_SET_FEATURES;
+       tf.feature = enable;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = feature;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
+
+       return err_mask;
+}
+
+static unsigned int ata_dev_init_params(struct ata_device *dev,
+                               u16 heads, u16 sectors)
+{
+       struct ata_taskfile tf;
+       struct ata_port *ap;
+       ap = pap;
+       unsigned int err_mask;
+
+       if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
+               return AC_ERR_INVALID;
+
+       memset(&tf, 0, sizeof(tf));
+       tf.ctl = ap->ctl;
+       tf.device = ATA_DEVICE_OBS;
+       tf.command = ATA_CMD_INIT_DEV_PARAMS;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = sectors;
+       tf.device |= (heads - 1) & 0x0f;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
+
+       if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
+               err_mask = 0;
+
+       return err_mask;
+}
+
+#if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
+#define SATA_MAX_READ_BLK 0xFF
+#else
+#define SATA_MAX_READ_BLK 0xFFFF
+#endif
+
+ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       ulong start,blks, buf_addr;
+       unsigned short smallblks;
+       unsigned long datalen;
+       unsigned char *pdata;
+       device &= 0xff;
+
+       u32 block = 0;
+       u32 n_block = 0;
+
+       if (dev_state != SATA_READY)
+               return 0;
+
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       do {
+               pdata = (unsigned char *)buf_addr;
+               if (blks > SATA_MAX_READ_BLK) {
+                       datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
+                       smallblks = SATA_MAX_READ_BLK;
+
+                       block = (u32)start;
+                       n_block = (u32)smallblks;
+
+                       start += SATA_MAX_READ_BLK;
+                       blks -= SATA_MAX_READ_BLK;
+               } else {
+                       datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
+                       datalen = sata_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+
+                       block = (u32)start;
+                       n_block = (u32)smallblks;
+
+                       start += blks;
+                       blks = 0;
+               }
+
+               if (ata_dev_read_sectors(pdata, datalen, block, n_block) != true) {
+                       printf("sata_dwc : Hard disk read error.\n");
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += datalen;
+       } while (blks != 0);
+
+       return (blkcnt);
+}
+
+static int ata_dev_read_sectors(unsigned char *pdata, unsigned long datalen,
+                                               u32 block, u32 n_block)
+{
+       struct ata_port *ap = pap;
+       struct ata_device *dev = &ata_device;
+       struct ata_taskfile tf;
+       unsigned int class = ATA_DEV_ATA;
+       unsigned int err_mask = 0;
+       const char *reason;
+       int may_fallback = 1;
+
+       if (dev_state == SATA_ERROR)
+               return false;
+
+       ata_dev_select(ap, dev->devno, 1, 1);
+
+retry:
+       memset(&tf, 0, sizeof(tf));
+       tf.ctl = ap->ctl;
+       ap->print_id = 1;
+       ap->flags &= ~ATA_FLAG_DISABLED;
+
+       ap->pdata = pdata;
+
+       tf.device = ATA_DEVICE_OBS;
+
+       temp_n_block = n_block;
+
+#ifdef CONFIG_LBA48
+       tf.command = ATA_CMD_PIO_READ_EXT;
+       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
+
+       tf.hob_feature = 31;
+       tf.feature = 31;
+       tf.hob_nsect = (n_block >> 8) & 0xff;
+       tf.nsect = n_block & 0xff;
+
+       tf.hob_lbah = 0x0;
+       tf.hob_lbam = 0x0;
+       tf.hob_lbal = (block >> 24) & 0xff;
+       tf.lbah = (block >> 16) & 0xff;
+       tf.lbam = (block >> 8) & 0xff;
+       tf.lbal = block & 0xff;
+
+       tf.device = 1 << 6;
+       if (tf.flags & ATA_TFLAG_FUA)
+               tf.device |= 1 << 7;
+#else
+       tf.command = ATA_CMD_PIO_READ;
+       tf.flags |= ATA_TFLAG_LBA ;
+
+       tf.feature = 31;
+       tf.nsect = n_block & 0xff;
+
+       tf.lbah = (block >> 16) & 0xff;
+       tf.lbam = (block >> 8) & 0xff;
+       tf.lbal = block & 0xff;
+
+       tf.device = (block >> 24) & 0xf;
+
+       tf.device |= 1 << 6;
+       if (tf.flags & ATA_TFLAG_FUA)
+               tf.device |= 1 << 7;
+
+#endif
+
+       tf.protocol = ATA_PROT_PIO;
+
+       /* Some devices choke if TF registers contain garbage.  Make
+        * sure those are properly initialized.
+        */
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.flags |= ATA_TFLAG_POLLING;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
+
+       if (err_mask) {
+               if (err_mask & AC_ERR_NODEV_HINT) {
+                       printf("READ_SECTORS NODEV after polling detection\n");
+                       return -ENOENT;
+               }
+
+               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       /* Device or controller might have reported
+                        * the wrong device class.  Give a shot at the
+                        * other IDENTIFY if the current one is
+                        * aborted by the device.
+                        */
+                       if (may_fallback) {
+                               may_fallback = 0;
+
+                               if (class == ATA_DEV_ATA) {
+                                       class = ATA_DEV_ATAPI;
+                               } else {
+                                       class = ATA_DEV_ATA;
+                               }
+                               goto retry;
+                       }
+                       /* Control reaches here iff the device aborted
+                        * both flavors of IDENTIFYs which happens
+                        * sometimes with phantom devices.
+                        */
+                       printf("both IDENTIFYs aborted, assuming NODEV\n");
+                       return -ENOENT;
+               }
+
+               reason = "I/O error";
+               goto err_out;
+       }
+
+       return true;
+
+err_out:
+       printf("failed to READ SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
+       return false;
+}
+
+#if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
+#define SATA_MAX_WRITE_BLK 0xFF
+#else
+#define SATA_MAX_WRITE_BLK 0xFFFF
+#endif
+
+ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       ulong start,blks, buf_addr;
+       unsigned short smallblks;
+       unsigned long datalen;
+       unsigned char *pdata;
+       device &= 0xff;
+
+
+       u32 block = 0;
+       u32 n_block = 0;
+
+       if (dev_state != SATA_READY)
+               return 0;
+
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       do {
+               pdata = (unsigned char *)buf_addr;
+               if (blks > SATA_MAX_WRITE_BLK) {
+                       datalen = sata_dev_desc[device].blksz * SATA_MAX_WRITE_BLK;
+                       smallblks = SATA_MAX_WRITE_BLK;
+
+                       block = (u32)start;
+                       n_block = (u32)smallblks;
+
+                       start += SATA_MAX_WRITE_BLK;
+                       blks -= SATA_MAX_WRITE_BLK;
+               } else {
+                       datalen = sata_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+
+                       block = (u32)start;
+                       n_block = (u32)smallblks;
+
+                       start += blks;
+                       blks = 0;
+               }
+
+               if (ata_dev_write_sectors(pdata, datalen, block, n_block) != true) {
+                       printf("sata_dwc : Hard disk read error.\n");
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += datalen;
+       } while (blks != 0);
+
+       return (blkcnt);
+}
+
+static int ata_dev_write_sectors(unsigned char* pdata, unsigned long datalen,
+                                               u32 block, u32 n_block)
+{
+       struct ata_port *ap = pap;
+       struct ata_device *dev = &ata_device;
+       struct ata_taskfile tf;
+       unsigned int class = ATA_DEV_ATA;
+       unsigned int err_mask = 0;
+       const char *reason;
+       int may_fallback = 1;
+
+       if (dev_state == SATA_ERROR)
+               return false;
+
+       ata_dev_select(ap, dev->devno, 1, 1);
+
+retry:
+       memset(&tf, 0, sizeof(tf));
+       tf.ctl = ap->ctl;
+       ap->print_id = 1;
+       ap->flags &= ~ATA_FLAG_DISABLED;
+
+       ap->pdata = pdata;
+
+       tf.device = ATA_DEVICE_OBS;
+
+       temp_n_block = n_block;
+
+
+#ifdef CONFIG_LBA48
+       tf.command = ATA_CMD_PIO_WRITE_EXT;
+       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48 | ATA_TFLAG_WRITE;
+
+       tf.hob_feature = 31;
+       tf.feature = 31;
+       tf.hob_nsect = (n_block >> 8) & 0xff;
+       tf.nsect = n_block & 0xff;
+
+       tf.hob_lbah = 0x0;
+       tf.hob_lbam = 0x0;
+       tf.hob_lbal = (block >> 24) & 0xff;
+       tf.lbah = (block >> 16) & 0xff;
+       tf.lbam = (block >> 8) & 0xff;
+       tf.lbal = block & 0xff;
+
+       tf.device = 1 << 6;
+       if (tf.flags & ATA_TFLAG_FUA)
+               tf.device |= 1 << 7;
+#else
+       tf.command = ATA_CMD_PIO_WRITE;
+       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_WRITE;
+
+       tf.feature = 31;
+       tf.nsect = n_block & 0xff;
+
+       tf.lbah = (block >> 16) & 0xff;
+       tf.lbam = (block >> 8) & 0xff;
+       tf.lbal = block & 0xff;
+
+       tf.device = (block >> 24) & 0xf;
+
+       tf.device |= 1 << 6;
+       if (tf.flags & ATA_TFLAG_FUA)
+               tf.device |= 1 << 7;
+
+#endif
+
+       tf.protocol = ATA_PROT_PIO;
+
+       /* Some devices choke if TF registers contain garbage.  Make
+        * sure those are properly initialized.
+        */
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.flags |= ATA_TFLAG_POLLING;
+
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
+
+       if (err_mask) {
+               if (err_mask & AC_ERR_NODEV_HINT) {
+                       printf("READ_SECTORS NODEV after polling detection\n");
+                       return -ENOENT;
+               }
+
+               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       /* Device or controller might have reported
+                        * the wrong device class.  Give a shot at the
+                        * other IDENTIFY if the current one is
+                        * aborted by the device.
+                        */
+                       if (may_fallback) {
+                               may_fallback = 0;
+
+                               if (class == ATA_DEV_ATA) {
+                                       class = ATA_DEV_ATAPI;
+                               } else {
+                                       class = ATA_DEV_ATA;
+                               }
+                               goto retry;
+                       }
+                       /* Control reaches here iff the device aborted
+                        * both flavors of IDENTIFYs which happens
+                        * sometimes with phantom devices.
+                        */
+                       printf("both IDENTIFYs aborted, assuming NODEV\n");
+                       return -ENOENT;
+               }
+
+               reason = "I/O error";
+               goto err_out;
+       }
+
+       return true;
+
+err_out:
+       printf("failed to WRITE SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
+       return false;
+}
diff --git a/drivers/ata/sata_dwc.h b/drivers/ata/sata_dwc.h
new file mode 100644 (file)
index 0000000..e2d9e0c
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * sata_dwc.h
+ *
+ * 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
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+/*
+ * SATA support based on the chip canyonlands.
+ *
+ * 04-17-2009
+ *             The local version of this driver for the canyonlands board
+ *             does not use interrupts but polls the chip instead.
+ */
+
+
+#ifndef _SATA_DWC_H_
+#define _SATA_DWC_H_
+
+#define __U_BOOT__
+
+#define HZ 100
+#define READ 0
+#define WRITE 1
+
+enum {
+       ATA_READID_POSTRESET    = (1 << 0),
+
+       ATA_DNXFER_PIO          = 0,
+       ATA_DNXFER_DMA          = 1,
+       ATA_DNXFER_40C          = 2,
+       ATA_DNXFER_FORCE_PIO    = 3,
+       ATA_DNXFER_FORCE_PIO0   = 4,
+
+       ATA_DNXFER_QUIET        = (1 << 31),
+};
+
+enum hsm_task_states {
+       HSM_ST_IDLE,
+       HSM_ST_FIRST,
+       HSM_ST,
+       HSM_ST_LAST,
+       HSM_ST_ERR,
+};
+
+#define        ATA_SHORT_PAUSE         ((HZ >> 6) + 1)
+
+struct ata_queued_cmd {
+       struct ata_port         *ap;
+       struct ata_device       *dev;
+
+       struct ata_taskfile     tf;
+       u8                      cdb[ATAPI_CDB_LEN];
+       unsigned long           flags;
+       unsigned int            tag;
+       unsigned int            n_elem;
+
+       int                     dma_dir;
+       unsigned int            sect_size;
+
+       unsigned int            nbytes;
+       unsigned int            extrabytes;
+       unsigned int            curbytes;
+
+       unsigned int            err_mask;
+       struct ata_taskfile     result_tf;
+
+       void                    *private_data;
+#ifndef __U_BOOT__
+       void                    *lldd_task;
+#endif
+       unsigned char           *pdata;
+};
+
+typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+
+#define ATA_TAG_POISON 0xfafbfcfdU
+
+enum {
+       LIBATA_MAX_PRD          = ATA_MAX_PRD / 2,
+       LIBATA_DUMB_MAX_PRD     = ATA_MAX_PRD / 4,
+       ATA_MAX_PORTS           = 8,
+       ATA_DEF_QUEUE           = 1,
+       ATA_MAX_QUEUE           = 32,
+       ATA_TAG_INTERNAL        = ATA_MAX_QUEUE - 1,
+       ATA_MAX_BUS             = 2,
+       ATA_DEF_BUSY_WAIT       = 10000,
+
+       ATAPI_MAX_DRAIN         = 16 << 10,
+
+       ATA_SHT_EMULATED        = 1,
+       ATA_SHT_CMD_PER_LUN     = 1,
+       ATA_SHT_THIS_ID         = -1,
+       ATA_SHT_USE_CLUSTERING  = 1,
+
+       ATA_DFLAG_LBA           = (1 << 0),
+       ATA_DFLAG_LBA48         = (1 << 1),
+       ATA_DFLAG_CDB_INTR      = (1 << 2),
+       ATA_DFLAG_NCQ           = (1 << 3),
+       ATA_DFLAG_FLUSH_EXT     = (1 << 4),
+       ATA_DFLAG_ACPI_PENDING  = (1 << 5),
+       ATA_DFLAG_ACPI_FAILED   = (1 << 6),
+       ATA_DFLAG_AN            = (1 << 7),
+       ATA_DFLAG_HIPM          = (1 << 8),
+       ATA_DFLAG_DIPM          = (1 << 9),
+       ATA_DFLAG_DMADIR        = (1 << 10),
+       ATA_DFLAG_CFG_MASK      = (1 << 12) - 1,
+
+       ATA_DFLAG_PIO           = (1 << 12),
+       ATA_DFLAG_NCQ_OFF       = (1 << 13),
+       ATA_DFLAG_SPUNDOWN      = (1 << 14),
+       ATA_DFLAG_SLEEPING      = (1 << 15),
+       ATA_DFLAG_DUBIOUS_XFER  = (1 << 16),
+       ATA_DFLAG_INIT_MASK     = (1 << 24) - 1,
+
+       ATA_DFLAG_DETACH        = (1 << 24),
+       ATA_DFLAG_DETACHED      = (1 << 25),
+
+       ATA_LFLAG_HRST_TO_RESUME        = (1 << 0),
+       ATA_LFLAG_SKIP_D2H_BSY          = (1 << 1),
+       ATA_LFLAG_NO_SRST               = (1 << 2),
+       ATA_LFLAG_ASSUME_ATA            = (1 << 3),
+       ATA_LFLAG_ASSUME_SEMB           = (1 << 4),
+       ATA_LFLAG_ASSUME_CLASS = ATA_LFLAG_ASSUME_ATA | ATA_LFLAG_ASSUME_SEMB,
+       ATA_LFLAG_NO_RETRY              = (1 << 5),
+       ATA_LFLAG_DISABLED              = (1 << 6),
+
+       ATA_FLAG_SLAVE_POSS     = (1 << 0),
+       ATA_FLAG_SATA           = (1 << 1),
+       ATA_FLAG_NO_LEGACY      = (1 << 2),
+       ATA_FLAG_MMIO           = (1 << 3),
+       ATA_FLAG_SRST           = (1 << 4),
+       ATA_FLAG_SATA_RESET     = (1 << 5),
+       ATA_FLAG_NO_ATAPI       = (1 << 6),
+       ATA_FLAG_PIO_DMA        = (1 << 7),
+       ATA_FLAG_PIO_LBA48      = (1 << 8),
+       ATA_FLAG_PIO_POLLING    = (1 << 9),
+       ATA_FLAG_NCQ            = (1 << 10),
+       ATA_FLAG_DEBUGMSG       = (1 << 13),
+       ATA_FLAG_IGN_SIMPLEX    = (1 << 15),
+       ATA_FLAG_NO_IORDY       = (1 << 16),
+       ATA_FLAG_ACPI_SATA      = (1 << 17),
+       ATA_FLAG_AN             = (1 << 18),
+       ATA_FLAG_PMP            = (1 << 19),
+       ATA_FLAG_IPM            = (1 << 20),
+
+       ATA_FLAG_DISABLED       = (1 << 23),
+
+       ATA_PFLAG_EH_PENDING            = (1 << 0),
+       ATA_PFLAG_EH_IN_PROGRESS        = (1 << 1),
+       ATA_PFLAG_FROZEN                = (1 << 2),
+       ATA_PFLAG_RECOVERED             = (1 << 3),
+       ATA_PFLAG_LOADING               = (1 << 4),
+       ATA_PFLAG_UNLOADING             = (1 << 5),
+       ATA_PFLAG_SCSI_HOTPLUG          = (1 << 6),
+       ATA_PFLAG_INITIALIZING          = (1 << 7),
+       ATA_PFLAG_RESETTING             = (1 << 8),
+       ATA_PFLAG_SUSPENDED             = (1 << 17),
+       ATA_PFLAG_PM_PENDING            = (1 << 18),
+
+       ATA_QCFLAG_ACTIVE       = (1 << 0),
+       ATA_QCFLAG_DMAMAP       = (1 << 1),
+       ATA_QCFLAG_IO           = (1 << 3),
+       ATA_QCFLAG_RESULT_TF    = (1 << 4),
+       ATA_QCFLAG_CLEAR_EXCL   = (1 << 5),
+       ATA_QCFLAG_QUIET        = (1 << 6),
+
+       ATA_QCFLAG_FAILED       = (1 << 16),
+       ATA_QCFLAG_SENSE_VALID  = (1 << 17),
+       ATA_QCFLAG_EH_SCHEDULED = (1 << 18),
+
+       ATA_HOST_SIMPLEX        = (1 << 0),
+       ATA_HOST_STARTED        = (1 << 1),
+
+       ATA_TMOUT_BOOT                  = 30 * 100,
+       ATA_TMOUT_BOOT_QUICK            = 7 * 100,
+       ATA_TMOUT_INTERNAL              = 30 * 100,
+       ATA_TMOUT_INTERNAL_QUICK        = 5 * 100,
+
+       /* FIXME: GoVault needs 2s but we can't afford that without
+        * parallel probing.  800ms is enough for iVDR disk
+        * HHD424020F7SV00.  Increase to 2secs when parallel probing
+        * is in place.
+        */
+       ATA_TMOUT_FF_WAIT       = 4 * 100 / 5,
+
+       BUS_UNKNOWN             = 0,
+       BUS_DMA                 = 1,
+       BUS_IDLE                = 2,
+       BUS_NOINTR              = 3,
+       BUS_NODATA              = 4,
+       BUS_TIMER               = 5,
+       BUS_PIO                 = 6,
+       BUS_EDD                 = 7,
+       BUS_IDENTIFY            = 8,
+       BUS_PACKET              = 9,
+
+       PORT_UNKNOWN            = 0,
+       PORT_ENABLED            = 1,
+       PORT_DISABLED           = 2,
+
+       /* encoding various smaller bitmaps into a single
+        * unsigned long bitmap
+        */
+       ATA_NR_PIO_MODES        = 7,
+       ATA_NR_MWDMA_MODES      = 5,
+       ATA_NR_UDMA_MODES       = 8,
+
+       ATA_SHIFT_PIO           = 0,
+       ATA_SHIFT_MWDMA         = ATA_SHIFT_PIO + ATA_NR_PIO_MODES,
+       ATA_SHIFT_UDMA          = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES,
+
+       ATA_DMA_PAD_SZ          = 4,
+
+       ATA_ERING_SIZE          = 32,
+
+       ATA_DEFER_LINK          = 1,
+       ATA_DEFER_PORT          = 2,
+
+       ATA_EH_DESC_LEN         = 80,
+
+       ATA_EH_REVALIDATE       = (1 << 0),
+       ATA_EH_SOFTRESET        = (1 << 1),
+       ATA_EH_HARDRESET        = (1 << 2),
+       ATA_EH_ENABLE_LINK      = (1 << 3),
+       ATA_EH_LPM              = (1 << 4),
+
+       ATA_EH_RESET_MASK       = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
+       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
+
+       ATA_EHI_HOTPLUGGED      = (1 << 0),
+       ATA_EHI_RESUME_LINK     = (1 << 1),
+       ATA_EHI_NO_AUTOPSY      = (1 << 2),
+       ATA_EHI_QUIET           = (1 << 3),
+
+       ATA_EHI_DID_SOFTRESET   = (1 << 16),
+       ATA_EHI_DID_HARDRESET   = (1 << 17),
+       ATA_EHI_PRINTINFO       = (1 << 18),
+       ATA_EHI_SETMODE         = (1 << 19),
+       ATA_EHI_POST_SETMODE    = (1 << 20),
+
+       ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
+       ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
+
+       ATA_EH_MAX_TRIES        = 5,
+
+       ATA_PROBE_MAX_TRIES     = 3,
+       ATA_EH_DEV_TRIES        = 3,
+       ATA_EH_PMP_TRIES        = 5,
+       ATA_EH_PMP_LINK_TRIES   = 3,
+
+       SATA_PMP_SCR_TIMEOUT    = 250,
+
+       /* Horkage types. May be set by libata or controller on drives
+       (some horkage may be drive/controller pair dependant */
+
+       ATA_HORKAGE_DIAGNOSTIC  = (1 << 0),
+       ATA_HORKAGE_NODMA       = (1 << 1),
+       ATA_HORKAGE_NONCQ       = (1 << 2),
+       ATA_HORKAGE_MAX_SEC_128 = (1 << 3),
+       ATA_HORKAGE_BROKEN_HPA  = (1 << 4),
+       ATA_HORKAGE_SKIP_PM     = (1 << 5),
+       ATA_HORKAGE_HPA_SIZE    = (1 << 6),
+       ATA_HORKAGE_IPM         = (1 << 7),
+       ATA_HORKAGE_IVB         = (1 << 8),
+       ATA_HORKAGE_STUCK_ERR   = (1 << 9),
+
+       ATA_DMA_MASK_ATA        = (1 << 0),
+       ATA_DMA_MASK_ATAPI      = (1 << 1),
+       ATA_DMA_MASK_CFA        = (1 << 2),
+
+       ATAPI_READ              = 0,
+       ATAPI_WRITE             = 1,
+       ATAPI_READ_CD           = 2,
+       ATAPI_PASS_THRU         = 3,
+       ATAPI_MISC              = 4,
+};
+
+enum ata_completion_errors {
+       AC_ERR_DEV              = (1 << 0),
+       AC_ERR_HSM              = (1 << 1),
+       AC_ERR_TIMEOUT          = (1 << 2),
+       AC_ERR_MEDIA            = (1 << 3),
+       AC_ERR_ATA_BUS          = (1 << 4),
+       AC_ERR_HOST_BUS         = (1 << 5),
+       AC_ERR_SYSTEM           = (1 << 6),
+       AC_ERR_INVALID          = (1 << 7),
+       AC_ERR_OTHER            = (1 << 8),
+       AC_ERR_NODEV_HINT       = (1 << 9),
+       AC_ERR_NCQ              = (1 << 10),
+};
+
+enum ata_xfer_mask {
+       ATA_MASK_PIO    = ((1LU << ATA_NR_PIO_MODES) - 1) << ATA_SHIFT_PIO,
+       ATA_MASK_MWDMA  = ((1LU << ATA_NR_MWDMA_MODES) - 1) << ATA_SHIFT_MWDMA,
+       ATA_MASK_UDMA   = ((1LU << ATA_NR_UDMA_MODES) - 1) << ATA_SHIFT_UDMA,
+};
+
+struct ata_port_info {
+#ifndef __U_BOOT__
+       struct scsi_host_template       *sht;
+#endif
+       unsigned long                   flags;
+       unsigned long                   link_flags;
+       unsigned long                   pio_mask;
+       unsigned long                   mwdma_mask;
+       unsigned long                   udma_mask;
+#ifndef __U_BOOT__
+       const struct ata_port_operations *port_ops;
+       void                            *private_data;
+#endif
+};
+
+struct ata_ioports {
+       void __iomem            *cmd_addr;
+       void __iomem            *data_addr;
+       void __iomem            *error_addr;
+       void __iomem            *feature_addr;
+       void __iomem            *nsect_addr;
+       void __iomem            *lbal_addr;
+       void __iomem            *lbam_addr;
+       void __iomem            *lbah_addr;
+       void __iomem            *device_addr;
+       void __iomem            *status_addr;
+       void __iomem            *command_addr;
+       void __iomem            *altstatus_addr;
+       void __iomem            *ctl_addr;
+#ifndef __U_BOOT__
+       void __iomem            *bmdma_addr;
+#endif
+       void __iomem            *scr_addr;
+};
+
+struct ata_host {
+#ifndef __U_BOOT__
+       void __iomem * const    *iomap;
+       void                    *private_data;
+       const struct ata_port_operations *ops;
+       unsigned long           flags;
+       struct ata_port         *simplex_claimed;
+#endif
+       unsigned int            n_ports;
+       struct ata_port         *ports[0];
+};
+
+#ifndef __U_BOOT__
+struct ata_port_stats {
+       unsigned long           unhandled_irq;
+       unsigned long           idle_irq;
+       unsigned long           rw_reqbuf;
+};
+#endif
+
+struct ata_device {
+       struct ata_link         *link;
+       unsigned int            devno;
+       unsigned long           flags;
+       unsigned int            horkage;
+#ifndef __U_BOOT__
+       struct scsi_device      *sdev;
+#ifdef CONFIG_ATA_ACPI
+       acpi_handle             acpi_handle;
+       union acpi_object       *gtf_cache;
+#endif
+#endif
+       u64                     n_sectors;
+       unsigned int            class;
+
+       union {
+               u16             id[ATA_ID_WORDS];
+               u32             gscr[SATA_PMP_GSCR_DWORDS];
+       };
+#ifndef __U_BOOT__
+       u8                      pio_mode;
+       u8                      dma_mode;
+       u8                      xfer_mode;
+       unsigned int            xfer_shift;
+#endif
+       unsigned int            multi_count;
+       unsigned int            max_sectors;
+       unsigned int            cdb_len;
+#ifndef __U_BOOT__
+       unsigned long           pio_mask;
+       unsigned long           mwdma_mask;
+#endif
+       unsigned long           udma_mask;
+       u16                     cylinders;
+       u16                     heads;
+       u16                     sectors;
+#ifndef __U_BOOT__
+       int                     spdn_cnt;
+#endif
+};
+
+enum dma_data_direction {
+       DMA_BIDIRECTIONAL = 0,
+       DMA_TO_DEVICE = 1,
+       DMA_FROM_DEVICE = 2,
+       DMA_NONE = 3,
+};
+
+struct ata_link {
+       struct ata_port         *ap;
+       int                     pmp;
+       unsigned int            active_tag;
+       u32                     sactive;
+       unsigned int            flags;
+       unsigned int            hw_sata_spd_limit;
+#ifndef __U_BOOT__
+       unsigned int            sata_spd_limit;
+       unsigned int            sata_spd;
+       struct ata_device       device[2];
+#endif
+};
+
+struct ata_port {
+       unsigned long           flags;
+       unsigned int            pflags;
+       unsigned int            print_id;
+       unsigned int            port_no;
+
+       struct ata_ioports      ioaddr;
+
+       u8                      ctl;
+       u8                      last_ctl;
+       unsigned int            pio_mask;
+       unsigned int            mwdma_mask;
+       unsigned int            udma_mask;
+       unsigned int            cbl;
+
+       struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE];
+       unsigned long           qc_allocated;
+       unsigned int            qc_active;
+       int                     nr_active_links;
+
+       struct ata_link         link;
+#ifndef __U_BOOT__
+       int                     nr_pmp_links;
+       struct ata_link         *pmp_link;
+#endif
+       struct ata_link         *excl_link;
+       int                     nr_pmp_links;
+#ifndef __U_BOOT__
+       struct ata_port_stats   stats;
+       struct device           *dev;
+       u32                     msg_enable;
+#endif
+       struct ata_host         *host;
+       void                    *port_task_data;
+
+       unsigned int            hsm_task_state;
+       void                    *private_data;
+       unsigned char           *pdata;
+};
+
+#endif
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
new file mode 100644 (file)
index 0000000..78e3da4
--- /dev/null
@@ -0,0 +1,1051 @@
+/*
+ * Copyright (C) Excito Elektronik i Skåne AB, 2010.
+ * Author: Tor Krill <tor@excito.com>
+ *
+ * Copyright (C) 2015 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/*
+ * This driver supports the SATA controller of some Mavell SoC's.
+ * Here a (most likely incomplete) list of the supported SoC's:
+ * - Kirkwood
+ * - Armada 370
+ * - Armada XP
+ *
+ * This driver implementation is an alternative to the already available
+ * driver via the "ide" commands interface (drivers/block/mvsata_ide.c).
+ * But this driver only supports PIO mode and as this new driver also
+ * supports transfer via DMA, its much faster.
+ *
+ * Please note, that the newer SoC's (e.g. Armada 38x) are not supported
+ * by this driver. As they have an AHCI compatible SATA controller
+ * integrated.
+ */
+
+/*
+ * TODO:
+ * Better error recovery
+ * No support for using PRDs (Thus max 64KB transfers)
+ * No NCQ support
+ * No port multiplier support
+ */
+
+#include <common.h>
+#include <fis.h>
+#include <libata.h>
+#include <malloc.h>
+#include <sata.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <linux/mbus.h>
+
+#if defined(CONFIG_KIRKWOOD)
+#include <asm/arch/kirkwood.h>
+#define SATAHC_BASE            KW_SATA_BASE
+#else
+#include <asm/arch/soc.h>
+#define SATAHC_BASE            MVEBU_AXP_SATA_BASE
+#endif
+
+#define SATA0_BASE             (SATAHC_BASE + 0x2000)
+#define SATA1_BASE             (SATAHC_BASE + 0x4000)
+
+/* EDMA registers */
+#define EDMA_CFG               0x000
+#define EDMA_CFG_NCQ           (1 << 5)
+#define EDMA_CFG_EQUE          (1 << 9)
+#define EDMA_TIMER             0x004
+#define EDMA_IECR              0x008
+#define EDMA_IEMR              0x00c
+#define EDMA_RQBA_HI           0x010
+#define EDMA_RQIPR             0x014
+#define EDMA_RQIPR_IPMASK      (0x1f << 5)
+#define EDMA_RQIPR_IPSHIFT     5
+#define EDMA_RQOPR             0x018
+#define EDMA_RQOPR_OPMASK      (0x1f << 5)
+#define EDMA_RQOPR_OPSHIFT     5
+#define EDMA_RSBA_HI           0x01c
+#define EDMA_RSIPR             0x020
+#define EDMA_RSIPR_IPMASK      (0x1f << 3)
+#define EDMA_RSIPR_IPSHIFT     3
+#define        EDMA_RSOPR              0x024
+#define EDMA_RSOPR_OPMASK      (0x1f << 3)
+#define EDMA_RSOPR_OPSHIFT     3
+#define EDMA_CMD               0x028
+#define EDMA_CMD_ENEDMA                (0x01 << 0)
+#define EDMA_CMD_DISEDMA       (0x01 << 1)
+#define EDMA_CMD_ATARST                (0x01 << 2)
+#define EDMA_CMD_FREEZE                (0x01 << 4)
+#define EDMA_TEST_CTL          0x02c
+#define EDMA_STATUS            0x030
+#define EDMA_IORTO             0x034
+#define EDMA_CDTR              0x040
+#define EDMA_HLTCND            0x060
+#define EDMA_NTSR              0x094
+
+/* Basic DMA registers */
+#define BDMA_CMD               0x224
+#define BDMA_STATUS            0x228
+#define BDMA_DTLB              0x22c
+#define BDMA_DTHB              0x230
+#define BDMA_DRL               0x234
+#define BDMA_DRH               0x238
+
+/* SATA Interface registers */
+#define SIR_ICFG               0x050
+#define SIR_CFG_GEN2EN         (0x1 << 7)
+#define SIR_PLL_CFG            0x054
+#define SIR_SSTATUS            0x300
+#define SSTATUS_DET_MASK       (0x0f << 0)
+#define SIR_SERROR             0x304
+#define SIR_SCONTROL           0x308
+#define SIR_SCONTROL_DETEN     (0x01 << 0)
+#define SIR_LTMODE             0x30c
+#define SIR_LTMODE_NELBE       (0x01 << 7)
+#define SIR_PHYMODE3           0x310
+#define SIR_PHYMODE4           0x314
+#define SIR_PHYMODE1           0x32c
+#define SIR_PHYMODE2           0x330
+#define SIR_BIST_CTRL          0x334
+#define SIR_BIST_DW1           0x338
+#define SIR_BIST_DW2           0x33c
+#define SIR_SERR_IRQ_MASK      0x340
+#define SIR_SATA_IFCTRL                0x344
+#define SIR_SATA_TESTCTRL      0x348
+#define SIR_SATA_IFSTATUS      0x34c
+#define SIR_VEND_UNIQ          0x35c
+#define SIR_FIS_CFG            0x360
+#define SIR_FIS_IRQ_CAUSE      0x364
+#define SIR_FIS_IRQ_MASK       0x368
+#define SIR_FIS_DWORD0         0x370
+#define SIR_FIS_DWORD1         0x374
+#define SIR_FIS_DWORD2         0x378
+#define SIR_FIS_DWORD3         0x37c
+#define SIR_FIS_DWORD4         0x380
+#define SIR_FIS_DWORD5         0x384
+#define SIR_FIS_DWORD6         0x388
+#define SIR_PHYM9_GEN2         0x398
+#define SIR_PHYM9_GEN1         0x39c
+#define SIR_PHY_CFG            0x3a0
+#define SIR_PHYCTL             0x3a4
+#define SIR_PHYM10             0x3a8
+#define SIR_PHYM12             0x3b0
+
+/* Shadow registers */
+#define        PIO_DATA                0x100
+#define PIO_ERR_FEATURES       0x104
+#define PIO_SECTOR_COUNT       0x108
+#define PIO_LBA_LOW            0x10c
+#define PIO_LBA_MID            0x110
+#define PIO_LBA_HI             0x114
+#define PIO_DEVICE             0x118
+#define PIO_CMD_STATUS         0x11c
+#define PIO_STATUS_ERR         (0x01 << 0)
+#define PIO_STATUS_DRQ         (0x01 << 3)
+#define PIO_STATUS_DF          (0x01 << 5)
+#define PIO_STATUS_DRDY                (0x01 << 6)
+#define PIO_STATUS_BSY         (0x01 << 7)
+#define PIO_CTRL_ALTSTAT       0x120
+
+/* SATAHC arbiter registers */
+#define SATAHC_CFG             0x000
+#define SATAHC_RQOP            0x004
+#define SATAHC_RQIP            0x008
+#define SATAHC_ICT             0x00c
+#define SATAHC_ITT             0x010
+#define SATAHC_ICR             0x014
+#define SATAHC_ICR_PORT0       (0x01 << 0)
+#define SATAHC_ICR_PORT1       (0x01 << 1)
+#define SATAHC_MIC             0x020
+#define SATAHC_MIM             0x024
+#define SATAHC_LED_CFG         0x02c
+
+#define REQUEST_QUEUE_SIZE     32
+#define RESPONSE_QUEUE_SIZE    REQUEST_QUEUE_SIZE
+
+struct crqb {
+       u32 dtb_low;            /* DW0 */
+       u32 dtb_high;           /* DW1 */
+       u32 control_flags;      /* DW2 */
+       u32 drb_count;          /* DW3 */
+       u32 ata_cmd_feat;       /* DW4 */
+       u32 ata_addr;           /* DW5 */
+       u32 ata_addr_exp;       /* DW6 */
+       u32 ata_sect_count;     /* DW7 */
+};
+
+#define CRQB_ALIGN                     0x400
+
+#define CRQB_CNTRLFLAGS_DIR            (0x01 << 0)
+#define CRQB_CNTRLFLAGS_DQTAGMASK      (0x1f << 1)
+#define CRQB_CNTRLFLAGS_DQTAGSHIFT     1
+#define CRQB_CNTRLFLAGS_PMPORTMASK     (0x0f << 12)
+#define CRQB_CNTRLFLAGS_PMPORTSHIFT    12
+#define CRQB_CNTRLFLAGS_PRDMODE                (0x01 << 16)
+#define CRQB_CNTRLFLAGS_HQTAGMASK      (0x1f << 17)
+#define CRQB_CNTRLFLAGS_HQTAGSHIFT     17
+
+#define CRQB_CMDFEAT_CMDMASK           (0xff << 16)
+#define CRQB_CMDFEAT_CMDSHIFT          16
+#define CRQB_CMDFEAT_FEATMASK          (0xff << 16)
+#define CRQB_CMDFEAT_FEATSHIFT         24
+
+#define CRQB_ADDR_LBA_LOWMASK          (0xff << 0)
+#define CRQB_ADDR_LBA_LOWSHIFT         0
+#define CRQB_ADDR_LBA_MIDMASK          (0xff << 8)
+#define CRQB_ADDR_LBA_MIDSHIFT         8
+#define CRQB_ADDR_LBA_HIGHMASK         (0xff << 16)
+#define CRQB_ADDR_LBA_HIGHSHIFT                16
+#define CRQB_ADDR_DEVICE_MASK          (0xff << 24)
+#define CRQB_ADDR_DEVICE_SHIFT         24
+
+#define CRQB_ADDR_LBA_LOW_EXP_MASK     (0xff << 0)
+#define CRQB_ADDR_LBA_LOW_EXP_SHIFT    0
+#define CRQB_ADDR_LBA_MID_EXP_MASK     (0xff << 8)
+#define CRQB_ADDR_LBA_MID_EXP_SHIFT    8
+#define CRQB_ADDR_LBA_HIGH_EXP_MASK    (0xff << 16)
+#define CRQB_ADDR_LBA_HIGH_EXP_SHIFT   16
+#define CRQB_ADDR_FEATURE_EXP_MASK     (0xff << 24)
+#define CRQB_ADDR_FEATURE_EXP_SHIFT    24
+
+#define CRQB_SECTCOUNT_COUNT_MASK      (0xff << 0)
+#define CRQB_SECTCOUNT_COUNT_SHIFT     0
+#define CRQB_SECTCOUNT_COUNT_EXP_MASK  (0xff << 8)
+#define CRQB_SECTCOUNT_COUNT_EXP_SHIFT 8
+
+#define MVSATA_WIN_CONTROL(w)  (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
+#define MVSATA_WIN_BASE(w)     (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
+
+struct eprd {
+       u32 phyaddr_low;
+       u32 bytecount_eot;
+       u32 phyaddr_hi;
+       u32 reserved;
+};
+
+#define EPRD_PHYADDR_MASK      0xfffffffe
+#define EPRD_BYTECOUNT_MASK    0x0000ffff
+#define EPRD_EOT               (0x01 << 31)
+
+struct crpb {
+       u32 id;
+       u32 flags;
+       u32 timestamp;
+};
+
+#define CRPB_ALIGN             0x100
+
+#define READ_CMD               0
+#define WRITE_CMD              1
+
+/*
+ * Since we don't use PRDs yet max transfer size
+ * is 64KB
+ */
+#define MV_ATA_MAX_SECTORS     (65535 / ATA_SECT_SIZE)
+
+/* Keep track if hw is initialized or not */
+static u32 hw_init;
+
+struct mv_priv {
+       char name[12];
+       u32 link;
+       u32 regbase;
+       u32 queue_depth;
+       u16 pio;
+       u16 mwdma;
+       u16 udma;
+
+       void *crqb_alloc;
+       struct crqb *request;
+
+       void *crpb_alloc;
+       struct crpb *response;
+};
+
+static int ata_wait_register(u32 *addr, u32 mask, u32 val, u32 timeout_msec)
+{
+       ulong start;
+
+       start = get_timer(0);
+       do {
+               if ((in_le32(addr) & mask) == val)
+                       return 0;
+       } while (get_timer(start) < timeout_msec);
+
+       return -ETIMEDOUT;
+}
+
+/* Cut from sata_mv in linux kernel */
+static int mv_stop_edma_engine(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       int i;
+
+       /* Disable eDMA. The disable bit auto clears. */
+       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_DISEDMA);
+
+       /* Wait for the chip to confirm eDMA is off. */
+       for (i = 10000; i > 0; i--) {
+               u32 reg = in_le32(priv->regbase + EDMA_CMD);
+               if (!(reg & EDMA_CMD_ENEDMA)) {
+                       debug("EDMA stop on port %d succesful\n", port);
+                       return 0;
+               }
+               udelay(10);
+       }
+       debug("EDMA stop on port %d failed\n", port);
+       return -1;
+}
+
+static int mv_start_edma_engine(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       /* Check preconditions */
+       tmp = in_le32(priv->regbase + SIR_SSTATUS);
+       if ((tmp & SSTATUS_DET_MASK) != 0x03) {
+               printf("Device error on port: %d\n", port);
+               return -1;
+       }
+
+       tmp = in_le32(priv->regbase + PIO_CMD_STATUS);
+       if (tmp & (ATA_BUSY | ATA_DRQ)) {
+               printf("Device not ready on port: %d\n", port);
+               return -1;
+       }
+
+       /* Clear interrupt cause */
+       out_le32(priv->regbase + EDMA_IECR, 0x0);
+
+       tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
+       tmp &= ~(port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1);
+       out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
+
+       /* Configure edma operation */
+       tmp = in_le32(priv->regbase + EDMA_CFG);
+       tmp &= ~EDMA_CFG_NCQ;   /* No NCQ */
+       tmp &= ~EDMA_CFG_EQUE;  /* Dont queue operations */
+       out_le32(priv->regbase + EDMA_CFG, tmp);
+
+       out_le32(priv->regbase + SIR_FIS_IRQ_CAUSE, 0x0);
+
+       /* Configure fis, set all to no-wait for now */
+       out_le32(priv->regbase + SIR_FIS_CFG, 0x0);
+
+       /* Setup request queue */
+       out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
+       out_le32(priv->regbase + EDMA_RQIPR, priv->request);
+       out_le32(priv->regbase + EDMA_RQOPR, 0x0);
+
+       /* Setup response queue */
+       out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
+       out_le32(priv->regbase + EDMA_RSOPR, priv->response);
+       out_le32(priv->regbase + EDMA_RSIPR, 0x0);
+
+       /* Start edma */
+       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ENEDMA);
+
+       return 0;
+}
+
+static int mv_reset_channel(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+
+       /* Make sure edma is stopped  */
+       mv_stop_edma_engine(port);
+
+       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ATARST);
+       udelay(25);             /* allow reset propagation */
+       out_le32(priv->regbase + EDMA_CMD, 0);
+       mdelay(10);
+
+       return 0;
+}
+
+static void mv_reset_port(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+
+       mv_reset_channel(port);
+
+       out_le32(priv->regbase + EDMA_CMD, 0x0);
+       out_le32(priv->regbase + EDMA_CFG, 0x101f);
+       out_le32(priv->regbase + EDMA_IECR, 0x0);
+       out_le32(priv->regbase + EDMA_IEMR, 0x0);
+       out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
+       out_le32(priv->regbase + EDMA_RQIPR, 0x0);
+       out_le32(priv->regbase + EDMA_RQOPR, 0x0);
+       out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
+       out_le32(priv->regbase + EDMA_RSIPR, 0x0);
+       out_le32(priv->regbase + EDMA_RSOPR, 0x0);
+       out_le32(priv->regbase + EDMA_IORTO, 0xfa);
+}
+
+static void mv_reset_one_hc(void)
+{
+       out_le32(SATAHC_BASE + SATAHC_ICT, 0x00);
+       out_le32(SATAHC_BASE + SATAHC_ITT, 0x00);
+       out_le32(SATAHC_BASE + SATAHC_ICR, 0x00);
+}
+
+static int probe_port(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       int tries, tries2, set15 = 0;
+       u32 tmp;
+
+       debug("Probe port: %d\n", port);
+
+       for (tries = 0; tries < 2; tries++) {
+               /* Clear SError */
+               out_le32(priv->regbase + SIR_SERROR, 0x0);
+
+               /* trigger com-init */
+               tmp = in_le32(priv->regbase + SIR_SCONTROL);
+               tmp = (tmp & 0x0f0) | 0x300 | SIR_SCONTROL_DETEN;
+               out_le32(priv->regbase + SIR_SCONTROL, tmp);
+
+               mdelay(1);
+
+               tmp = in_le32(priv->regbase + SIR_SCONTROL);
+               tries2 = 5;
+               do {
+                       tmp = (tmp & 0x0f0) | 0x300;
+                       out_le32(priv->regbase + SIR_SCONTROL, tmp);
+                       mdelay(10);
+                       tmp = in_le32(priv->regbase + SIR_SCONTROL);
+               } while ((tmp & 0xf0f) != 0x300 && tries2--);
+
+               mdelay(10);
+
+               for (tries2 = 0; tries2 < 200; tries2++) {
+                       tmp = in_le32(priv->regbase + SIR_SSTATUS);
+                       if ((tmp & SSTATUS_DET_MASK) == 0x03) {
+                               debug("Found device on port\n");
+                               return 0;
+                       }
+                       mdelay(1);
+               }
+
+               if ((tmp & SSTATUS_DET_MASK) == 0) {
+                       debug("No device attached on port %d\n", port);
+                       return -ENODEV;
+               }
+
+               if (!set15) {
+                       /* Try on 1.5Gb/S */
+                       debug("Try 1.5Gb link\n");
+                       set15 = 1;
+                       out_le32(priv->regbase + SIR_SCONTROL, 0x304);
+
+                       tmp = in_le32(priv->regbase + SIR_ICFG);
+                       tmp &= ~SIR_CFG_GEN2EN;
+                       out_le32(priv->regbase + SIR_ICFG, tmp);
+
+                       mv_reset_channel(port);
+               }
+       }
+
+       debug("Failed to probe port\n");
+       return -1;
+}
+
+/* Get request queue in pointer */
+static int get_reqip(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       tmp = in_le32(priv->regbase + EDMA_RQIPR) & EDMA_RQIPR_IPMASK;
+       tmp = tmp >> EDMA_RQIPR_IPSHIFT;
+
+       return tmp;
+}
+
+static void set_reqip(int port, int reqin)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       tmp = in_le32(priv->regbase + EDMA_RQIPR) & ~EDMA_RQIPR_IPMASK;
+       tmp |= ((reqin << EDMA_RQIPR_IPSHIFT) & EDMA_RQIPR_IPMASK);
+       out_le32(priv->regbase + EDMA_RQIPR, tmp);
+}
+
+/* Get next available slot, ignoring possible overwrite */
+static int get_next_reqip(int port)
+{
+       int slot = get_reqip(port);
+       slot = (slot + 1) % REQUEST_QUEUE_SIZE;
+       return slot;
+}
+
+/* Get response queue in pointer */
+static int get_rspip(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       tmp = in_le32(priv->regbase + EDMA_RSIPR) & EDMA_RSIPR_IPMASK;
+       tmp = tmp >> EDMA_RSIPR_IPSHIFT;
+
+       return tmp;
+}
+
+/* Get response queue out pointer */
+static int get_rspop(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       tmp = in_le32(priv->regbase + EDMA_RSOPR) & EDMA_RSOPR_OPMASK;
+       tmp = tmp >> EDMA_RSOPR_OPSHIFT;
+       return tmp;
+}
+
+/* Get next response queue pointer  */
+static int get_next_rspop(int port)
+{
+       return (get_rspop(port) + 1) % RESPONSE_QUEUE_SIZE;
+}
+
+/* Set response queue pointer */
+static void set_rspop(int port, int reqin)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       u32 tmp;
+
+       tmp = in_le32(priv->regbase + EDMA_RSOPR) & ~EDMA_RSOPR_OPMASK;
+       tmp |= ((reqin << EDMA_RSOPR_OPSHIFT) & EDMA_RSOPR_OPMASK);
+
+       out_le32(priv->regbase + EDMA_RSOPR, tmp);
+}
+
+static int wait_dma_completion(int port, int index, u32 timeout_msec)
+{
+       u32 tmp, res;
+
+       tmp = port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1;
+       res = ata_wait_register((u32 *)(SATAHC_BASE + SATAHC_ICR), tmp,
+                               tmp, timeout_msec);
+       if (res)
+               printf("Failed to wait for completion on port %d\n", port);
+
+       return res;
+}
+
+static void process_responses(int port)
+{
+#ifdef DEBUG
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+#endif
+       u32 tmp;
+       u32 outind = get_rspop(port);
+
+       /* Ack interrupts */
+       tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
+       if (port == 0)
+               tmp &= ~(BIT(0) | BIT(8));
+       else
+               tmp &= ~(BIT(1) | BIT(9));
+       tmp &= ~(BIT(4));
+       out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
+
+       while (get_rspip(port) != outind) {
+#ifdef DEBUG
+               debug("Response index %d flags %08x on port %d\n", outind,
+                     priv->response[outind].flags, port);
+#endif
+               outind = get_next_rspop(port);
+               set_rspop(port, outind);
+       }
+}
+
+static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
+                              u8 *buffer, u32 len, u32 iswrite)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       struct crqb *req;
+       int slot;
+       u32 start;
+
+       if (len >= 64 * 1024) {
+               printf("We only support <64K transfers for now\n");
+               return -1;
+       }
+
+       /* Initialize request */
+       slot = get_reqip(port);
+       memset(&priv->request[slot], 0, sizeof(struct crqb));
+       req = &priv->request[slot];
+
+       req->dtb_low = (u32)buffer;
+
+       /* Dont use PRDs */
+       req->control_flags = CRQB_CNTRLFLAGS_PRDMODE;
+       req->control_flags |= iswrite ? 0 : CRQB_CNTRLFLAGS_DIR;
+       req->control_flags |=
+           ((cfis->pm_port_c << CRQB_CNTRLFLAGS_PMPORTSHIFT)
+            & CRQB_CNTRLFLAGS_PMPORTMASK);
+
+       req->drb_count = len;
+
+       req->ata_cmd_feat = (cfis->command << CRQB_CMDFEAT_CMDSHIFT) &
+               CRQB_CMDFEAT_CMDMASK;
+       req->ata_cmd_feat |= (cfis->features << CRQB_CMDFEAT_FEATSHIFT) &
+               CRQB_CMDFEAT_FEATMASK;
+
+       req->ata_addr = (cfis->lba_low << CRQB_ADDR_LBA_LOWSHIFT) &
+               CRQB_ADDR_LBA_LOWMASK;
+       req->ata_addr |= (cfis->lba_mid << CRQB_ADDR_LBA_MIDSHIFT) &
+               CRQB_ADDR_LBA_MIDMASK;
+       req->ata_addr |= (cfis->lba_high << CRQB_ADDR_LBA_HIGHSHIFT) &
+               CRQB_ADDR_LBA_HIGHMASK;
+       req->ata_addr |= (cfis->device << CRQB_ADDR_DEVICE_SHIFT) &
+               CRQB_ADDR_DEVICE_MASK;
+
+       req->ata_addr_exp = (cfis->lba_low_exp << CRQB_ADDR_LBA_LOW_EXP_SHIFT) &
+               CRQB_ADDR_LBA_LOW_EXP_MASK;
+       req->ata_addr_exp |=
+               (cfis->lba_mid_exp << CRQB_ADDR_LBA_MID_EXP_SHIFT) &
+               CRQB_ADDR_LBA_MID_EXP_MASK;
+       req->ata_addr_exp |=
+               (cfis->lba_high_exp << CRQB_ADDR_LBA_HIGH_EXP_SHIFT) &
+               CRQB_ADDR_LBA_HIGH_EXP_MASK;
+       req->ata_addr_exp |=
+               (cfis->features_exp << CRQB_ADDR_FEATURE_EXP_SHIFT) &
+               CRQB_ADDR_FEATURE_EXP_MASK;
+
+       req->ata_sect_count =
+               (cfis->sector_count << CRQB_SECTCOUNT_COUNT_SHIFT) &
+               CRQB_SECTCOUNT_COUNT_MASK;
+       req->ata_sect_count |=
+               (cfis->sector_count_exp << CRQB_SECTCOUNT_COUNT_EXP_SHIFT) &
+               CRQB_SECTCOUNT_COUNT_EXP_MASK;
+
+       /* Flush data */
+       start = (u32)req & ~(ARCH_DMA_MINALIGN - 1);
+       flush_dcache_range(start,
+                          start + ALIGN(sizeof(*req), ARCH_DMA_MINALIGN));
+
+       /* Trigger operation */
+       slot = get_next_reqip(port);
+       set_reqip(port, slot);
+
+       /* Wait for completion */
+       if (wait_dma_completion(port, slot, 10000)) {
+               printf("ATA operation timed out\n");
+               return -1;
+       }
+
+       process_responses(port);
+
+       /* Invalidate data on read */
+       if (buffer && len) {
+               start = (u32)buffer & ~(ARCH_DMA_MINALIGN - 1);
+               invalidate_dcache_range(start,
+                                       start + ALIGN(len, ARCH_DMA_MINALIGN));
+       }
+
+       return len;
+}
+
+static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt,
+                             u8 *buffer, int is_write)
+{
+       struct sata_fis_h2d cfis;
+       u32 res;
+       u64 block;
+
+       block = (u64)start;
+
+       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis.command = (is_write) ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
+
+       cfis.lba_high_exp = (block >> 40) & 0xff;
+       cfis.lba_mid_exp = (block >> 32) & 0xff;
+       cfis.lba_low_exp = (block >> 24) & 0xff;
+       cfis.lba_high = (block >> 16) & 0xff;
+       cfis.lba_mid = (block >> 8) & 0xff;
+       cfis.lba_low = block & 0xff;
+       cfis.device = ATA_LBA;
+       cfis.sector_count_exp = (blkcnt >> 8) & 0xff;
+       cfis.sector_count = blkcnt & 0xff;
+
+       res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
+                                 is_write);
+
+       return res >= 0 ? blkcnt : res;
+}
+
+static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer,
+                         int is_write)
+{
+       struct sata_fis_h2d cfis;
+       lbaint_t block;
+       u32 res;
+
+       block = start;
+
+       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis.command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
+       cfis.device = ATA_LBA;
+
+       cfis.device |= (block >> 24) & 0xf;
+       cfis.lba_high = (block >> 16) & 0xff;
+       cfis.lba_mid = (block >> 8) & 0xff;
+       cfis.lba_low = block & 0xff;
+       cfis.sector_count = (u8)(blkcnt & 0xff);
+
+       res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
+                                 is_write);
+
+       return res >= 0 ? blkcnt : res;
+}
+
+static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt,
+                           void *buffer, int is_write)
+{
+       lbaint_t start, blks;
+       u8 *addr;
+       int max_blks;
+
+       debug("%s: %ld %ld\n", __func__, blknr, blkcnt);
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = MV_ATA_MAX_SECTORS;
+       do {
+               if (blks > max_blks) {
+                       if (sata_dev_desc[dev].lba48) {
+                               mv_sata_rw_cmd_ext(dev, start, max_blks, addr,
+                                                  is_write);
+                       } else {
+                               mv_sata_rw_cmd(dev, start, max_blks, addr,
+                                              is_write);
+                       }
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       if (sata_dev_desc[dev].lba48) {
+                               mv_sata_rw_cmd_ext(dev, start, blks, addr,
+                                                  is_write);
+                       } else {
+                               mv_sata_rw_cmd(dev, start, blks, addr,
+                                              is_write);
+                       }
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+static int mv_ata_exec_ata_cmd_nondma(int port,
+                                     struct sata_fis_h2d *cfis, u8 *buffer,
+                                     u32 len, u32 iswrite)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       int i;
+       u16 *tp;
+
+       debug("%s\n", __func__);
+
+       out_le32(priv->regbase + PIO_SECTOR_COUNT, cfis->sector_count);
+       out_le32(priv->regbase + PIO_LBA_HI, cfis->lba_high);
+       out_le32(priv->regbase + PIO_LBA_MID, cfis->lba_mid);
+       out_le32(priv->regbase + PIO_LBA_LOW, cfis->lba_low);
+       out_le32(priv->regbase + PIO_ERR_FEATURES, cfis->features);
+       out_le32(priv->regbase + PIO_DEVICE, cfis->device);
+       out_le32(priv->regbase + PIO_CMD_STATUS, cfis->command);
+
+       if (ata_wait_register((u32 *)(priv->regbase + PIO_CMD_STATUS),
+                             ATA_BUSY, 0x0, 10000)) {
+               debug("Failed to wait for completion\n");
+               return -1;
+       }
+
+       if (len > 0) {
+               tp = (u16 *)buffer;
+               for (i = 0; i < len / 2; i++) {
+                       if (iswrite)
+                               out_le16(priv->regbase + PIO_DATA, *tp++);
+                       else
+                               *tp++ = in_le16(priv->regbase + PIO_DATA);
+               }
+       }
+
+       return len;
+}
+
+static int mv_sata_identify(int port, u16 *id)
+{
+       struct sata_fis_h2d h2d;
+
+       memset(&h2d, 0, sizeof(struct sata_fis_h2d));
+
+       h2d.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       h2d.command = ATA_CMD_ID_ATA;
+
+       /* Give device time to get operational */
+       mdelay(10);
+
+       return mv_ata_exec_ata_cmd_nondma(port, &h2d, (u8 *)id,
+                                         ATA_ID_WORDS * 2, READ_CMD);
+}
+
+static void mv_sata_xfer_mode(int port, u16 *id)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+
+       priv->pio = id[ATA_ID_PIO_MODES];
+       priv->mwdma = id[ATA_ID_MWDMA_MODES];
+       priv->udma = id[ATA_ID_UDMA_MODES];
+       debug("pio %04x, mwdma %04x, udma %04x\n", priv->pio, priv->mwdma,
+             priv->udma);
+}
+
+static void mv_sata_set_features(int port)
+{
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+       struct sata_fis_h2d cfis;
+       u8 udma_cap;
+
+       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis.command = ATA_CMD_SET_FEATURES;
+       cfis.features = SETFEATURES_XFER;
+
+       /* First check the device capablity */
+       udma_cap = (u8) (priv->udma & 0xff);
+
+       if (udma_cap == ATA_UDMA6)
+               cfis.sector_count = XFER_UDMA_6;
+       if (udma_cap == ATA_UDMA5)
+               cfis.sector_count = XFER_UDMA_5;
+       if (udma_cap == ATA_UDMA4)
+               cfis.sector_count = XFER_UDMA_4;
+       if (udma_cap == ATA_UDMA3)
+               cfis.sector_count = XFER_UDMA_3;
+
+       mv_ata_exec_ata_cmd_nondma(port, &cfis, NULL, 0, READ_CMD);
+}
+
+int mv_sata_spin_down(int dev)
+{
+       struct sata_fis_h2d cfis;
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
+
+       if (priv->link == 0) {
+               debug("No device on port: %d\n", dev);
+               return 1;
+       }
+
+       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis.command = ATA_CMD_STANDBY;
+
+       return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
+}
+
+int mv_sata_spin_up(int dev)
+{
+       struct sata_fis_h2d cfis;
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
+
+       if (priv->link == 0) {
+               debug("No device on port: %d\n", dev);
+               return 1;
+       }
+
+       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
+
+       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       cfis.command = ATA_CMD_IDLE;
+
+       return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
+}
+
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       return ata_low_level_rw(dev, blknr, blkcnt, buffer, READ_CMD);
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       return ata_low_level_rw(dev, blknr, blkcnt, (void *)buffer, WRITE_CMD);
+}
+
+/*
+ * Initialize SATA memory windows
+ */
+static void mvsata_ide_conf_mbus_windows(void)
+{
+       const struct mbus_dram_target_info *dram;
+       int i;
+
+       dram = mvebu_mbus_dram_info();
+
+       /* Disable windows, Set Size/Base to 0  */
+       for (i = 0; i < 4; i++) {
+               writel(0, MVSATA_WIN_CONTROL(i));
+               writel(0, MVSATA_WIN_BASE(i));
+       }
+
+       for (i = 0; i < dram->num_cs; i++) {
+               const struct mbus_dram_window *cs = dram->cs + i;
+               writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+                      (dram->mbus_dram_target_id << 4) | 1,
+                      MVSATA_WIN_CONTROL(i));
+               writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
+       }
+}
+
+int init_sata(int dev)
+{
+       struct mv_priv *priv;
+
+       debug("Initialize sata dev: %d\n", dev);
+
+       if (dev < 0 || dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
+               printf("Invalid sata device %d\n", dev);
+               return -1;
+       }
+
+       priv = (struct mv_priv *)malloc(sizeof(struct mv_priv));
+       if (!priv) {
+               printf("Failed to allocate memory for private sata data\n");
+               return -ENOMEM;
+       }
+
+       memset((void *)priv, 0, sizeof(struct mv_priv));
+
+       /* Allocate and align request buffer */
+       priv->crqb_alloc = malloc(sizeof(struct crqb) * REQUEST_QUEUE_SIZE +
+                                 CRQB_ALIGN);
+       if (!priv->crqb_alloc) {
+               printf("Unable to allocate memory for request queue\n");
+               return -ENOMEM;
+       }
+       memset(priv->crqb_alloc, 0,
+              sizeof(struct crqb) * REQUEST_QUEUE_SIZE + CRQB_ALIGN);
+       priv->request = (struct crqb *)(((u32) priv->crqb_alloc + CRQB_ALIGN) &
+                                       ~(CRQB_ALIGN - 1));
+
+       /* Allocate and align response buffer */
+       priv->crpb_alloc = malloc(sizeof(struct crpb) * REQUEST_QUEUE_SIZE +
+                                 CRPB_ALIGN);
+       if (!priv->crpb_alloc) {
+               printf("Unable to allocate memory for response queue\n");
+               return -ENOMEM;
+       }
+       memset(priv->crpb_alloc, 0,
+              sizeof(struct crpb) * REQUEST_QUEUE_SIZE + CRPB_ALIGN);
+       priv->response = (struct crpb *)(((u32) priv->crpb_alloc + CRPB_ALIGN) &
+                                        ~(CRPB_ALIGN - 1));
+
+       sata_dev_desc[dev].priv = (void *)priv;
+
+       sprintf(priv->name, "SATA%d", dev);
+
+       priv->regbase = dev == 0 ? SATA0_BASE : SATA1_BASE;
+
+       if (!hw_init) {
+               debug("Initialize sata hw\n");
+               hw_init = 1;
+               mv_reset_one_hc();
+               mvsata_ide_conf_mbus_windows();
+       }
+
+       mv_reset_port(dev);
+
+       if (probe_port(dev)) {
+               priv->link = 0;
+               return -ENODEV;
+       }
+       priv->link = 1;
+
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+int scan_sata(int port)
+{
+       unsigned char serial[ATA_ID_SERNO_LEN + 1];
+       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+       unsigned char product[ATA_ID_PROD_LEN + 1];
+       u64 n_sectors;
+       u16 *id;
+       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+
+       if (!priv->link)
+               return -ENODEV;
+
+       id = (u16 *)malloc(ATA_ID_WORDS * 2);
+       if (!id) {
+               printf("Failed to malloc id data\n");
+               return -ENOMEM;
+       }
+
+       mv_sata_identify(port, id);
+       ata_swap_buf_le16(id, ATA_ID_WORDS);
+#ifdef DEBUG
+       ata_dump_id(id);
+#endif
+
+       /* Serial number */
+       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+       memcpy(sata_dev_desc[port].product, serial, sizeof(serial));
+
+       /* Firmware version */
+       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+       memcpy(sata_dev_desc[port].revision, firmware, sizeof(firmware));
+
+       /* Product model */
+       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+       memcpy(sata_dev_desc[port].vendor, product, sizeof(product));
+
+       /* Total sectors */
+       n_sectors = ata_id_n_sectors(id);
+       sata_dev_desc[port].lba = n_sectors;
+
+       /* Check if support LBA48 */
+       if (ata_id_has_lba48(id)) {
+               sata_dev_desc[port].lba48 = 1;
+               debug("Device support LBA48\n");
+       }
+
+       /* Get the NCQ queue depth from device */
+       priv->queue_depth = ata_id_queue_depth(id);
+
+       /* Get the xfer mode from device */
+       mv_sata_xfer_mode(port, id);
+
+       /* Set the xfer mode to highest speed */
+       mv_sata_set_features(port);
+
+       /* Start up */
+       mv_start_edma_engine(port);
+
+       return 0;
+}
diff --git a/drivers/ata/sata_sandbox.c b/drivers/ata/sata_sandbox.c
new file mode 100644 (file)
index 0000000..bd967d2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+
+int init_sata(int dev)
+{
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+int scan_sata(int dev)
+{
+       return 0;
+}
+
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       return 0;
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       return 0;
+}
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
new file mode 100644 (file)
index 0000000..daff7d4
--- /dev/null
@@ -0,0 +1,715 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Author: Tang Yuantian <b29983@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <command.h>
+#include <asm/byteorder.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <fis.h>
+#include <sata.h>
+#include <libata.h>
+#include <sata.h>
+#include "sata_sil.h"
+
+/* Convert sectorsize to wordsize */
+#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
+#define virt_to_bus(devno, v)  pci_virt_to_mem(devno, (void *) (v))
+
+static struct sata_info sata_info;
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3131},
+       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3132},
+       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3124},
+       {}
+};
+
+static void sil_sata_dump_fis(struct sata_fis_d2h *s)
+{
+       printf("Status FIS dump:\n");
+       printf("fis_type:               %02x\n", s->fis_type);
+       printf("pm_port_i:              %02x\n", s->pm_port_i);
+       printf("status:                 %02x\n", s->status);
+       printf("error:                  %02x\n", s->error);
+       printf("lba_low:                %02x\n", s->lba_low);
+       printf("lba_mid:                %02x\n", s->lba_mid);
+       printf("lba_high:               %02x\n", s->lba_high);
+       printf("device:                 %02x\n", s->device);
+       printf("lba_low_exp:            %02x\n", s->lba_low_exp);
+       printf("lba_mid_exp:            %02x\n", s->lba_mid_exp);
+       printf("lba_high_exp:           %02x\n", s->lba_high_exp);
+       printf("res1:                   %02x\n", s->res1);
+       printf("sector_count:           %02x\n", s->sector_count);
+       printf("sector_count_exp:       %02x\n", s->sector_count_exp);
+}
+
+static const char *sata_spd_string(unsigned int speed)
+{
+       static const char * const spd_str[] = {
+               "1.5 Gbps",
+               "3.0 Gbps",
+               "6.0 Gbps",
+       };
+
+       if ((speed - 1) > 2)
+               return "<unknown>";
+
+       return spd_str[speed - 1];
+}
+
+static u32 ata_wait_register(void *reg, u32 mask,
+                        u32 val, int timeout_msec)
+{
+       u32 tmp;
+
+       tmp = readl(reg);
+       while ((tmp & mask) == val && timeout_msec > 0) {
+               mdelay(1);
+               timeout_msec--;
+               tmp = readl(reg);
+       }
+
+       return tmp;
+}
+
+static void sil_config_port(void *port)
+{
+       /* configure IRQ WoC */
+       writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
+       /* zero error counters. */
+       writew(0x8000, port + PORT_DECODE_ERR_THRESH);
+       writew(0x8000, port + PORT_CRC_ERR_THRESH);
+       writew(0x8000, port + PORT_HSHK_ERR_THRESH);
+       writew(0x0000, port + PORT_DECODE_ERR_CNT);
+       writew(0x0000, port + PORT_CRC_ERR_CNT);
+       writew(0x0000, port + PORT_HSHK_ERR_CNT);
+
+       /* always use 64bit activation */
+       writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
+
+       /* clear port multiplier enable and resume bits */
+       writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
+}
+
+static int sil_init_port(void *port)
+{
+       u32 tmp;
+
+       writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+       ata_wait_register(port + PORT_CTRL_STAT,
+                         PORT_CS_INIT, PORT_CS_INIT, 100);
+       tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                               PORT_CS_RDY, 0, 100);
+
+       if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
+               return 1;
+
+       return 0;
+}
+
+static void sil_read_fis(int dev, int tag, struct sata_fis_d2h *fis)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       void *port = sata->port;
+       struct sil_prb *prb;
+       int i;
+       u32 *src, *dst;
+
+       prb = port + PORT_LRAM + tag * PORT_LRAM_SLOT_SZ;
+       src = (u32 *)&prb->fis;
+       dst = (u32 *)fis;
+       for (i = 0; i < sizeof(struct sata_fis_h2d); i += 4)
+               *dst++ = readl(src++);
+}
+
+static int sil_exec_cmd(int dev, struct sil_cmd_block *pcmd, int tag)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       void *port = sata->port;
+       u64 paddr = virt_to_bus(sata->devno, pcmd);
+       u32 irq_mask, irq_stat;
+       int rc;
+
+       writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR);
+
+       /* better to add momery barrior here */
+       writel((u32)paddr, port + PORT_CMD_ACTIVATE + tag * 8);
+       writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + tag * 8 + 4);
+
+       irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
+       irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask,
+                       0, 10000);
+
+       /* clear IRQs */
+       writel(irq_mask, port + PORT_IRQ_STAT);
+       irq_stat >>= PORT_IRQ_RAW_SHIFT;
+
+       if (irq_stat & PORT_IRQ_COMPLETE)
+               rc = 0;
+       else {
+               /* force port into known state */
+               sil_init_port(port);
+               if (irq_stat & PORT_IRQ_ERROR)
+                       rc = 1; /* error */
+               else
+                       rc = 2; /* busy */
+       }
+
+       return rc;
+}
+
+static int sil_cmd_set_feature(int dev)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+       struct sata_fis_d2h fis;
+       u8 udma_cap;
+       int ret;
+
+       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       pcmd->prb.fis.command = ATA_CMD_SET_FEATURES;
+       pcmd->prb.fis.features = SETFEATURES_XFER;
+
+       /* First check the device capablity */
+       udma_cap = (u8)(sata->udma & 0xff);
+       debug("udma_cap %02x\n", udma_cap);
+
+       if (udma_cap == ATA_UDMA6)
+               pcmd->prb.fis.sector_count = XFER_UDMA_6;
+       if (udma_cap == ATA_UDMA5)
+               pcmd->prb.fis.sector_count = XFER_UDMA_5;
+       if (udma_cap == ATA_UDMA4)
+               pcmd->prb.fis.sector_count = XFER_UDMA_4;
+       if (udma_cap == ATA_UDMA3)
+               pcmd->prb.fis.sector_count = XFER_UDMA_3;
+
+       ret = sil_exec_cmd(dev, pcmd, 0);
+       if (ret) {
+               sil_read_fis(dev, 0, &fis);
+               printf("Err: exe cmd(0x%x).\n",
+                               readl(sata->port + PORT_SERROR));
+               sil_sata_dump_fis(&fis);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int sil_cmd_identify_device(int dev, u16 *id)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+       struct sata_fis_d2h fis;
+       int ret;
+
+       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
+       pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       pcmd->prb.fis.command = ATA_CMD_ID_ATA;
+       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, id));
+       pcmd->sge.cnt = cpu_to_le32(sizeof(id[0]) * ATA_ID_WORDS);
+       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
+
+       ret = sil_exec_cmd(dev, pcmd, 0);
+       if (ret) {
+               sil_read_fis(dev, 0, &fis);
+               printf("Err: id cmd(0x%x).\n", readl(sata->port + PORT_SERROR));
+               sil_sata_dump_fis(&fis);
+               return 1;
+       }
+       ata_swap_buf_le16(id, ATA_ID_WORDS);
+
+       return 0;
+}
+
+static int sil_cmd_soft_reset(int dev)
+{
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       struct sata_fis_d2h fis;
+       void *port = sata->port;
+       int ret;
+
+       /* put the port into known state */
+       if (sil_init_port(port)) {
+               printf("SRST: port %d not ready\n", dev);
+               return 1;
+       }
+
+       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
+
+       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_SRST);
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = 0xf;
+
+       ret = sil_exec_cmd(dev, &cmdb, 0);
+       if (ret) {
+               sil_read_fis(dev, 0, &fis);
+               printf("SRST cmd error.\n");
+               sil_sata_dump_fis(&fis);
+               return 1;
+       }
+
+       return 0;
+}
+
+static ulong sil_sata_rw_cmd(int dev, ulong start, ulong blkcnt,
+               u8 *buffer, int is_write)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+       struct sata_fis_d2h fis;
+       u64 block;
+       int ret;
+
+       block = (u64)start;
+       memset(pcmd, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       if (is_write) {
+               pcmd->prb.fis.command = ATA_CMD_WRITE;
+               pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
+       } else {
+               pcmd->prb.fis.command = ATA_CMD_READ;
+               pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
+       }
+
+       pcmd->prb.fis.device = ATA_LBA;
+       pcmd->prb.fis.device |= (block >> 24) & 0xf;
+       pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
+       pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
+       pcmd->prb.fis.lba_low = block & 0xff;
+       pcmd->prb.fis.sector_count = (u8)blkcnt & 0xff;
+
+       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
+       pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
+       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
+
+       ret = sil_exec_cmd(dev, pcmd, 0);
+       if (ret) {
+               sil_read_fis(dev, 0, &fis);
+               printf("Err: rw cmd(0x%08x).\n",
+                               readl(sata->port + PORT_SERROR));
+               sil_sata_dump_fis(&fis);
+               return 1;
+       }
+
+       return blkcnt;
+}
+
+static ulong sil_sata_rw_cmd_ext(int dev, ulong start, ulong blkcnt,
+               u8 *buffer, int is_write)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+       struct sata_fis_d2h fis;
+       u64 block;
+       int ret;
+
+       block = (u64)start;
+       memset(pcmd, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       if (is_write) {
+               pcmd->prb.fis.command = ATA_CMD_WRITE_EXT;
+               pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
+       } else {
+               pcmd->prb.fis.command = ATA_CMD_READ_EXT;
+               pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
+       }
+
+       pcmd->prb.fis.lba_high_exp = (block >> 40) & 0xff;
+       pcmd->prb.fis.lba_mid_exp = (block >> 32) & 0xff;
+       pcmd->prb.fis.lba_low_exp = (block >> 24) & 0xff;
+       pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
+       pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
+       pcmd->prb.fis.lba_low = block & 0xff;
+       pcmd->prb.fis.device = ATA_LBA;
+       pcmd->prb.fis.sector_count_exp = (blkcnt >> 8) & 0xff;
+       pcmd->prb.fis.sector_count = blkcnt & 0xff;
+
+       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
+       pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
+       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
+
+       ret = sil_exec_cmd(dev, pcmd, 0);
+       if (ret) {
+               sil_read_fis(dev, 0, &fis);
+               printf("Err: rw ext cmd(0x%08x).\n",
+                               readl(sata->port + PORT_SERROR));
+               sil_sata_dump_fis(&fis);
+               return 1;
+       }
+
+       return blkcnt;
+}
+
+static ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt,
+                              const void *buffer, int is_write)
+{
+       ulong start, blks, max_blks;
+       u8 *addr;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS;
+       do {
+               if (blks > max_blks) {
+                       sil_sata_rw_cmd(dev, start, max_blks, addr, is_write);
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       sil_sata_rw_cmd(dev, start, blks, addr, is_write);
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+static ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt,
+                              const void *buffer, int is_write)
+{
+       ulong start, blks, max_blks;
+       u8 *addr;
+
+       start = blknr;
+       blks = blkcnt;
+       addr = (u8 *)buffer;
+
+       max_blks = ATA_MAX_SECTORS_LBA48;
+       do {
+               if (blks > max_blks) {
+                       sil_sata_rw_cmd_ext(dev, start, max_blks,
+                                       addr, is_write);
+                       start += max_blks;
+                       blks -= max_blks;
+                       addr += ATA_SECT_SIZE * max_blks;
+               } else {
+                       sil_sata_rw_cmd_ext(dev, start, blks,
+                                       addr, is_write);
+                       start += blks;
+                       blks = 0;
+                       addr += ATA_SECT_SIZE * blks;
+               }
+       } while (blks != 0);
+
+       return blkcnt;
+}
+
+static void sil_sata_cmd_flush_cache(int dev)
+{
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+
+       memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       pcmd->prb.fis.command = ATA_CMD_FLUSH;
+
+       sil_exec_cmd(dev, pcmd, 0);
+}
+
+static void sil_sata_cmd_flush_cache_ext(int dev)
+{
+       struct sil_cmd_block cmdb, *pcmd = &cmdb;
+
+       memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
+       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+       pcmd->prb.fis.pm_port_c = (1 << 7);
+       pcmd->prb.fis.command = ATA_CMD_FLUSH_EXT;
+
+       sil_exec_cmd(dev, pcmd, 0);
+}
+
+static void sil_sata_init_wcache(int dev, u16 *id)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+
+       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
+               sata->wcache = 1;
+       if (ata_id_has_flush(id))
+               sata->flush = 1;
+       if (ata_id_has_flush_ext(id))
+               sata->flush_ext = 1;
+}
+
+static int sil_sata_get_wcache(int dev)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+
+       return sata->wcache;
+}
+
+static int sil_sata_get_flush(int dev)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+
+       return sata->flush;
+}
+
+static int sil_sata_get_flush_ext(int dev)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+
+       return sata->flush_ext;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       ulong rc;
+
+       if (sata->lba48)
+               rc = sil_sata_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
+       else
+               rc = sil_sata_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
+
+       return rc;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       struct sil_sata *sata = sata_dev_desc[dev].priv;
+       ulong rc;
+
+       if (sata->lba48) {
+               rc = sil_sata_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
+               if (sil_sata_get_wcache(dev) && sil_sata_get_flush_ext(dev))
+                       sil_sata_cmd_flush_cache_ext(dev);
+       } else {
+               rc = sil_sata_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD);
+               if (sil_sata_get_wcache(dev) && sil_sata_get_flush(dev))
+                       sil_sata_cmd_flush_cache(dev);
+       }
+
+       return rc;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+int init_sata(int dev)
+{
+       static int init_done, idx;
+       pci_dev_t devno;
+       u16 word;
+
+       if (init_done == 1 && dev < sata_info.maxport)
+               return 0;
+
+       init_done = 1;
+
+       /* Find PCI device(s) */
+       devno = pci_find_devices(supported, idx++);
+       if (devno == -1)
+               return 1;
+
+       pci_read_config_word(devno, PCI_DEVICE_ID, &word);
+
+       /* get the port count */
+       word &= 0xf;
+
+       sata_info.portbase = sata_info.maxport;
+       sata_info.maxport = sata_info.portbase + word;
+       sata_info.devno = devno;
+
+       /* Read out all BARs */
+       sata_info.iobase[0] = (ulong)pci_map_bar(devno,
+                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       sata_info.iobase[1] = (ulong)pci_map_bar(devno,
+                       PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
+       sata_info.iobase[2] = (ulong)pci_map_bar(devno,
+                       PCI_BASE_ADDRESS_4, PCI_REGION_MEM);
+
+       /* mask out the unused bits */
+       sata_info.iobase[0] &= 0xffffff80;
+       sata_info.iobase[1] &= 0xfffffc00;
+       sata_info.iobase[2] &= 0xffffff80;
+
+       /* Enable Bus Mastering and memory region */
+       pci_write_config_word(devno, PCI_COMMAND,
+                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+       /* Check if mem accesses and Bus Mastering are enabled. */
+       pci_read_config_word(devno, PCI_COMMAND, &word);
+       if (!(word & PCI_COMMAND_MEMORY) ||
+                       (!(word & PCI_COMMAND_MASTER))) {
+               printf("Error: Can not enable MEM access or Bus Mastering.\n");
+               debug("PCI command: %04x\n", word);
+               return 1;
+       }
+
+       /* GPIO off */
+       writel(0, (void *)(sata_info.iobase[0] + HOST_FLASH_CMD));
+       /* clear global reset & mask interrupts during initialization */
+       writel(0, (void *)(sata_info.iobase[0] + HOST_CTRL));
+
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+int scan_sata(int dev)
+{
+       unsigned char serial[ATA_ID_SERNO_LEN + 1];
+       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+       unsigned char product[ATA_ID_PROD_LEN + 1];
+       struct sil_sata *sata;
+       void *port;
+       int cnt;
+       u16 *id;
+       u32 tmp;
+
+       if (dev >= sata_info.maxport) {
+               printf("SATA#%d is not present\n", dev);
+               return 1;
+       }
+
+       printf("SATA#%d\n", dev);
+       port = (void *)sata_info.iobase[1] +
+               PORT_REGS_SIZE * (dev - sata_info.portbase);
+
+       /* Initial PHY setting */
+       writel(0x20c, port + PORT_PHY_CFG);
+
+       /* clear port RST */
+       tmp = readl(port + PORT_CTRL_STAT);
+       if (tmp & PORT_CS_PORT_RST) {
+               writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
+               tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                               PORT_CS_PORT_RST, PORT_CS_PORT_RST, 100);
+               if (tmp & PORT_CS_PORT_RST)
+                       printf("Err: Failed to clear port RST\n");
+       }
+
+       /* Check if device is present */
+       for (cnt = 0; cnt < 100; cnt++) {
+               tmp = readl(port + PORT_SSTATUS);
+               if ((tmp & 0xF) == 0x3)
+                       break;
+               mdelay(1);
+       }
+
+       tmp = readl(port + PORT_SSTATUS);
+       if ((tmp & 0xf) != 0x3) {
+               printf("        (No RDY)\n");
+               return 1;
+       }
+
+       /* Wait for port ready */
+       tmp = ata_wait_register(port + PORT_CTRL_STAT,
+                               PORT_CS_RDY, PORT_CS_RDY, 100);
+       if ((tmp & PORT_CS_RDY) != PORT_CS_RDY) {
+               printf("%d port not ready.\n", dev);
+               return 1;
+       }
+
+       /* configure port */
+       sil_config_port(port);
+
+       /* Reset port */
+       writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
+       readl(port + PORT_CTRL_STAT);
+       tmp = ata_wait_register(port + PORT_CTRL_STAT, PORT_CS_DEV_RST,
+                               PORT_CS_DEV_RST, 100);
+       if (tmp & PORT_CS_DEV_RST) {
+               printf("%d port reset failed.\n", dev);
+               return 1;
+       }
+
+       sata = (struct sil_sata *)malloc(sizeof(struct sil_sata));
+       if (!sata) {
+               printf("%d no memory.\n", dev);
+               return 1;
+       }
+       memset((void *)sata, 0, sizeof(struct sil_sata));
+
+       /* turn on port interrupt */
+       tmp = readl((void *)(sata_info.iobase[0] + HOST_CTRL));
+       tmp |= (1 << (dev - sata_info.portbase));
+       writel(tmp, (void *)(sata_info.iobase[0] + HOST_CTRL));
+
+       /* Save the private struct to block device struct */
+       sata_dev_desc[dev].priv = (void *)sata;
+       sata->port = port;
+       sata->devno = sata_info.devno;
+       sprintf(sata->name, "SATA#%d", dev);
+       sil_cmd_soft_reset(dev);
+       tmp = readl(port + PORT_SSTATUS);
+       tmp = (tmp >> 4) & 0xf;
+       printf("        (%s)\n", sata_spd_string(tmp));
+
+       id = (u16 *)malloc(ATA_ID_WORDS * 2);
+       if (!id) {
+               printf("Id malloc failed\n");
+               free((void *)sata);
+               return 1;
+       }
+       sil_cmd_identify_device(dev, id);
+
+#ifdef CONFIG_LBA48
+       /* Check if support LBA48 */
+       if (ata_id_has_lba48(id)) {
+               sata_dev_desc[dev].lba48 = 1;
+               sata->lba48 = 1;
+               debug("Device supports LBA48\n");
+       } else
+               debug("Device supports LBA28\n");
+#endif
+
+       /* Serial number */
+       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+       memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
+
+       /* Firmware version */
+       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+       memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
+
+       /* Product model */
+       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+       memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
+
+       /* Totoal sectors */
+       sata_dev_desc[dev].lba = ata_id_n_sectors(id);
+
+       sil_sata_init_wcache(dev, id);
+       sil_cmd_set_feature(dev);
+
+#ifdef DEBUG
+       sil_cmd_identify_device(dev, id);
+       ata_dump_id(id);
+#endif
+       free((void *)id);
+
+       return 0;
+}
diff --git a/drivers/ata/sata_sil.h b/drivers/ata/sata_sil.h
new file mode 100644 (file)
index 0000000..55954ef
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Author: Tang Yuantian <b29983@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef SATA_SIL3132_H
+#define SATA_SIL3132_H
+
+#define READ_CMD       0
+#define WRITE_CMD      1
+
+/*
+ * SATA device driver struct for each dev
+ */
+struct sil_sata {
+       char    name[12];
+       void    *port;  /* the port base address */
+       int             lba48;
+       u16             pio;
+       u16             mwdma;
+       u16             udma;
+       pci_dev_t devno;
+       int             wcache;
+       int             flush;
+       int             flush_ext;
+};
+
+/* sata info for each controller */
+struct sata_info {
+       ulong iobase[3];
+       pci_dev_t devno;
+       int portbase;
+       int maxport;
+};
+
+/*
+ * Scatter gather entry (SGE),MUST 8 bytes aligned
+ */
+struct sil_sge {
+       __le64 addr;
+       __le32 cnt;
+       __le32 flags;
+} __attribute__ ((aligned(8), packed));
+
+/*
+ * Port request block, MUST 8 bytes aligned
+ */
+struct sil_prb {
+       __le16 ctrl;
+       __le16 prot;
+       __le32 rx_cnt;
+       struct sata_fis_h2d fis;
+} __attribute__ ((aligned(8), packed));
+
+struct sil_cmd_block {
+       struct sil_prb prb;
+       struct sil_sge sge;
+};
+
+enum {
+       HOST_SLOT_STAT          = 0x00, /* 32 bit slot stat * 4 */
+       HOST_CTRL               = 0x40,
+       HOST_IRQ_STAT           = 0x44,
+       HOST_PHY_CFG            = 0x48,
+       HOST_BIST_CTRL          = 0x50,
+       HOST_BIST_PTRN          = 0x54,
+       HOST_BIST_STAT          = 0x58,
+       HOST_MEM_BIST_STAT      = 0x5c,
+       HOST_FLASH_CMD          = 0x70,
+               /* 8 bit regs */
+       HOST_FLASH_DATA         = 0x74,
+       HOST_TRANSITION_DETECT  = 0x75,
+       HOST_GPIO_CTRL          = 0x76,
+       HOST_I2C_ADDR           = 0x78, /* 32 bit */
+       HOST_I2C_DATA           = 0x7c,
+       HOST_I2C_XFER_CNT       = 0x7e,
+       HOST_I2C_CTRL           = 0x7f,
+
+       /* HOST_SLOT_STAT bits */
+       HOST_SSTAT_ATTN         = (1 << 31),
+
+       /* HOST_CTRL bits */
+       HOST_CTRL_M66EN         = (1 << 16), /* M66EN PCI bus signal */
+       HOST_CTRL_TRDY          = (1 << 17), /* latched PCI TRDY */
+       HOST_CTRL_STOP          = (1 << 18), /* latched PCI STOP */
+       HOST_CTRL_DEVSEL        = (1 << 19), /* latched PCI DEVSEL */
+       HOST_CTRL_REQ64         = (1 << 20), /* latched PCI REQ64 */
+       HOST_CTRL_GLOBAL_RST    = (1 << 31), /* global reset */
+
+       /*
+        * Port registers
+        * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
+        */
+       PORT_REGS_SIZE          = 0x2000,
+
+       PORT_LRAM               = 0x0000, /* 31 LRAM slots and PMP regs */
+       PORT_LRAM_SLOT_SZ       = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
+
+       PORT_PMP                = 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
+       PORT_PMP_STATUS         = 0x0000, /* port device status offset */
+       PORT_PMP_QACTIVE        = 0x0004, /* port device QActive offset */
+       PORT_PMP_SIZE           = 0x0008, /* 8 bytes per PMP */
+
+       /* 32 bit regs */
+       PORT_CTRL_STAT          = 0x1000, /* write: ctrl-set, read: stat */
+       PORT_CTRL_CLR           = 0x1004, /* write: ctrl-clear */
+       PORT_IRQ_STAT           = 0x1008, /* high: status, low: interrupt */
+       PORT_IRQ_ENABLE_SET     = 0x1010, /* write: enable-set */
+       PORT_IRQ_ENABLE_CLR     = 0x1014, /* write: enable-clear */
+       PORT_ACTIVATE_UPPER_ADDR = 0x101c,
+       PORT_EXEC_FIFO          = 0x1020, /* command execution fifo */
+       PORT_CMD_ERR            = 0x1024, /* command error number */
+       PORT_FIS_CFG            = 0x1028,
+       PORT_FIFO_THRES         = 0x102c,
+
+       /* 16 bit regs */
+       PORT_DECODE_ERR_CNT     = 0x1040,
+       PORT_DECODE_ERR_THRESH  = 0x1042,
+       PORT_CRC_ERR_CNT        = 0x1044,
+       PORT_CRC_ERR_THRESH     = 0x1046,
+       PORT_HSHK_ERR_CNT       = 0x1048,
+       PORT_HSHK_ERR_THRESH    = 0x104a,
+
+       /* 32 bit regs */
+       PORT_PHY_CFG            = 0x1050,
+       PORT_SLOT_STAT          = 0x1800,
+       PORT_CMD_ACTIVATE       = 0x1c00, /* 64 bit cmd activate * 31 */
+       PORT_CONTEXT            = 0x1e04,
+       PORT_EXEC_DIAG          = 0x1e00, /* 32bit exec diag * 16 */
+       PORT_PSD_DIAG           = 0x1e40, /* 32bit psd diag * 16 */
+       PORT_SCONTROL           = 0x1f00,
+       PORT_SSTATUS            = 0x1f04,
+       PORT_SERROR             = 0x1f08,
+       PORT_SACTIVE            = 0x1f0c,
+
+       /* PORT_CTRL_STAT bits */
+       PORT_CS_PORT_RST        = (1 << 0), /* port reset */
+       PORT_CS_DEV_RST         = (1 << 1), /* device reset */
+       PORT_CS_INIT            = (1 << 2), /* port initialize */
+       PORT_CS_IRQ_WOC         = (1 << 3), /* interrupt write one to clear */
+       PORT_CS_CDB16           = (1 << 5), /* 0=12b cdb, 1=16b cdb */
+       PORT_CS_PMP_RESUME      = (1 << 6), /* PMP resume */
+       PORT_CS_32BIT_ACTV      = (1 << 10), /* 32-bit activation */
+       PORT_CS_PMP_EN          = (1 << 13), /* port multiplier enable */
+       PORT_CS_RDY             = (1 << 31), /* port ready to accept commands */
+
+       /* PORT_IRQ_STAT/ENABLE_SET/CLR */
+       /* bits[11:0] are masked */
+       PORT_IRQ_COMPLETE       = (1 << 0), /* command(s) completed */
+       PORT_IRQ_ERROR          = (1 << 1), /* command execution error */
+       PORT_IRQ_PORTRDY_CHG    = (1 << 2), /* port ready change */
+       PORT_IRQ_PWR_CHG        = (1 << 3), /* power management change */
+       PORT_IRQ_PHYRDY_CHG     = (1 << 4), /* PHY ready change */
+       PORT_IRQ_COMWAKE        = (1 << 5), /* COMWAKE received */
+       PORT_IRQ_UNK_FIS        = (1 << 6), /* unknown FIS received */
+       PORT_IRQ_DEV_XCHG       = (1 << 7), /* device exchanged */
+       PORT_IRQ_8B10B          = (1 << 8), /* 8b/10b decode error threshold */
+       PORT_IRQ_CRC            = (1 << 9), /* CRC error threshold */
+       PORT_IRQ_HANDSHAKE      = (1 << 10), /* handshake error threshold */
+       PORT_IRQ_SDB_NOTIFY     = (1 << 11), /* SDB notify received */
+
+       DEF_PORT_IRQ            = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
+                                 PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG |
+                                 PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_NOTIFY,
+
+       /* bits[27:16] are unmasked (raw) */
+       PORT_IRQ_RAW_SHIFT      = 16,
+       PORT_IRQ_MASKED_MASK    = 0x7ff,
+       PORT_IRQ_RAW_MASK       = (0x7ff << PORT_IRQ_RAW_SHIFT),
+
+       /* ENABLE_SET/CLR specific, intr steering - 2 bit field */
+       PORT_IRQ_STEER_SHIFT    = 30,
+       PORT_IRQ_STEER_MASK     = (3 << PORT_IRQ_STEER_SHIFT),
+
+       /* PORT_CMD_ERR constants */
+       PORT_CERR_DEV           = 1, /* Error bit in D2H Register FIS */
+       PORT_CERR_SDB           = 2, /* Error bit in SDB FIS */
+       PORT_CERR_DATA          = 3, /* Error in data FIS not detected by dev */
+       PORT_CERR_SEND          = 4, /* Initial cmd FIS transmission failure */
+       PORT_CERR_INCONSISTENT  = 5, /* Protocol mismatch */
+       PORT_CERR_DIRECTION     = 6, /* Data direction mismatch */
+       PORT_CERR_UNDERRUN      = 7, /* Ran out of SGEs while writing */
+       PORT_CERR_OVERRUN       = 8, /* Ran out of SGEs while reading */
+
+       /* bits of PRB control field */
+       PRB_CTRL_PROTOCOL       = (1 << 0), /* override def. ATA protocol */
+       PRB_CTRL_PACKET_READ    = (1 << 4), /* PACKET cmd read */
+       PRB_CTRL_PACKET_WRITE   = (1 << 5), /* PACKET cmd write */
+       PRB_CTRL_NIEN           = (1 << 6), /* Mask completion irq */
+       PRB_CTRL_SRST           = (1 << 7), /* Soft reset request (ign BSY?) */
+
+       /* PRB protocol field */
+       PRB_PROT_PACKET         = (1 << 0),
+       PRB_PROT_TCQ            = (1 << 1),
+       PRB_PROT_NCQ            = (1 << 2),
+       PRB_PROT_READ           = (1 << 3),
+       PRB_PROT_WRITE          = (1 << 4),
+       PRB_PROT_TRANSPARENT    = (1 << 5),
+
+       /*
+        * Other constants
+        */
+       SGE_TRM                 = (1 << 31), /* Last SGE in chain */
+       SGE_LNK                 = (1 << 30), /* linked list
+                                               Points to SGT, not SGE */
+       SGE_DRD                 = (1 << 29), /* discard data read (/dev/null)
+                                               data address ignored */
+
+       CMD_ERR         = 0x21,
+};
+
+#endif
diff --git a/drivers/ata/sata_sil3114.c b/drivers/ata/sata_sil3114.c
new file mode 100644 (file)
index 0000000..61ffb66
--- /dev/null
@@ -0,0 +1,835 @@
+/*
+ * Copyright (C) Excito Elektronik i Skåne AB, All rights reserved.
+ * Author: Tor Krill <tor@excito.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * This is a driver for Silicon Image sil3114 sata chip modelled on
+ * the ata_piix driver
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <command.h>
+#include <config.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <ide.h>
+#include <sata.h>
+#include <libata.h>
+#include "sata_sil3114.h"
+
+/* Convert sectorsize to wordsize */
+#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
+
+/* Forwards */
+u8 sil3114_spin_up (int num);
+u8 sil3114_spin_down (int num);
+static int sata_bus_softreset (int num);
+static void sata_identify (int num, int dev);
+static u8 check_power_mode (int num);
+static void sata_port (struct sata_ioports *ioport);
+static void set_Feature_cmd (int num, int dev);
+static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits,
+                         unsigned int max, u8 usealtstatus);
+static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus);
+static void msleep (int count);
+
+static u32 iobase[6] = { 0, 0, 0, 0, 0, 0};    /* PCI BAR registers for device */
+
+static struct sata_port port[CONFIG_SYS_SATA_MAX_DEVICE];
+
+static void output_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words)
+{
+       while (words--) {
+               __raw_writew (*sect_buf++, (void *)ioaddr->data_addr);
+       }
+}
+
+static int input_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words)
+{
+       while (words--) {
+               *sect_buf++ = __raw_readw ((void *)ioaddr->data_addr);
+       }
+       return 0;
+}
+
+static int sata_bus_softreset (int num)
+{
+       u8 status = 0;
+
+       port[num].dev_mask = 1;
+
+       port[num].ctl_reg = 0x08;       /*Default value of control reg */
+       writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
+       udelay (10);
+       writeb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
+       udelay (10);
+       writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
+
+       /* spec mandates ">= 2ms" before checking status.
+        * We wait 150ms, because that was the magic delay used for
+        * ATAPI devices in Hale Landis's ATADRVR, for the period of time
+        * between when the ATA command register is written, and then
+        * status is checked.  Because waiting for "a while" before
+        * checking status is fine, post SRST, we perform this magic
+        * delay here as well.
+        */
+       msleep (150);
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300, 0);
+       while ((status & ATA_BUSY)) {
+               msleep (100);
+               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3, 0);
+       }
+
+       if (status & ATA_BUSY) {
+               printf ("ata%u is slow to respond,plz be patient\n", num);
+       }
+
+       while ((status & ATA_BUSY)) {
+               msleep (100);
+               status = sata_chk_status (&port[num].ioaddr, 0);
+       }
+
+       if (status & ATA_BUSY) {
+               printf ("ata%u failed to respond : ", num);
+               printf ("bus reset failed\n");
+               port[num].dev_mask = 0;
+               return 1;
+       }
+       return 0;
+}
+
+static void sata_identify (int num, int dev)
+{
+       u8 cmd = 0, status = 0, devno = num;
+       u16 iobuf[ATA_SECTOR_WORDS];
+       u64 n_sectors = 0;
+
+       memset (iobuf, 0, sizeof (iobuf));
+
+       if (!(port[num].dev_mask & 0x01)) {
+               printf ("dev%d is not present on port#%d\n", dev, num);
+               return;
+       }
+
+       debug ("port=%d dev=%d\n", num, dev);
+
+       status = 0;
+       cmd = ATA_CMD_ID_ATA;   /*Device Identify Command */
+       writeb (cmd, port[num].ioaddr.command_addr);
+       readb (port[num].ioaddr.altstatus_addr);
+       udelay (10);
+
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000, 0);
+       if (status & ATA_ERR) {
+               printf ("\ndevice not responding\n");
+               port[num].dev_mask &= ~0x01;
+               return;
+       }
+
+       input_data (&port[num].ioaddr, iobuf, ATA_SECTOR_WORDS);
+
+       ata_swap_buf_le16 (iobuf, ATA_SECTOR_WORDS);
+
+       debug ("Specific config: %x\n", iobuf[2]);
+
+       /* we require LBA and DMA support (bits 8 & 9 of word 49) */
+       if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) {
+               debug ("ata%u: no dma/lba\n", num);
+       }
+#ifdef DEBUG
+       ata_dump_id (iobuf);
+#endif
+       n_sectors = ata_id_n_sectors (iobuf);
+
+       if (n_sectors == 0) {
+               port[num].dev_mask &= ~0x01;
+               return;
+       }
+       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].revision,
+                        ATA_ID_FW_REV, sizeof (sata_dev_desc[devno].revision));
+       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].vendor,
+                        ATA_ID_PROD, sizeof (sata_dev_desc[devno].vendor));
+       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].product,
+                        ATA_ID_SERNO, sizeof (sata_dev_desc[devno].product));
+
+       /* TODO - atm we asume harddisk ie not removable */
+       sata_dev_desc[devno].removable = 0;
+
+       sata_dev_desc[devno].lba = (u32) n_sectors;
+       debug("lba=0x%lx\n", sata_dev_desc[devno].lba);
+
+#ifdef CONFIG_LBA48
+       if (iobuf[83] & (1 << 10)) {
+               sata_dev_desc[devno].lba48 = 1;
+       } else {
+               sata_dev_desc[devno].lba48 = 0;
+       }
+#endif
+
+       /* assuming HD */
+       sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
+       sata_dev_desc[devno].blksz = ATA_SECT_SIZE;
+       sata_dev_desc[devno].lun = 0;   /* just to fill something in... */
+}
+
+static void set_Feature_cmd (int num, int dev)
+{
+       u8 status = 0;
+
+       if (!(port[num].dev_mask & 0x01)) {
+               debug ("dev%d is not present on port#%d\n", dev, num);
+               return;
+       }
+
+       writeb (SETFEATURES_XFER, port[num].ioaddr.feature_addr);
+       writeb (XFER_PIO_4, port[num].ioaddr.nsect_addr);
+       writeb (0, port[num].ioaddr.lbal_addr);
+       writeb (0, port[num].ioaddr.lbam_addr);
+       writeb (0, port[num].ioaddr.lbah_addr);
+
+       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
+       writeb (ATA_CMD_SET_FEATURES, port[num].ioaddr.command_addr);
+
+       udelay (50);
+       msleep (150);
+
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0);
+       if ((status & (ATA_BUSY | ATA_ERR))) {
+               printf ("Error  : status 0x%02x\n", status);
+               port[num].dev_mask &= ~0x01;
+       }
+}
+
+u8 sil3114_spin_down (int num)
+{
+       u8 status = 0;
+
+       debug ("Spin down disk\n");
+
+       if (!(port[num].dev_mask & 0x01)) {
+               debug ("Device ata%d is not present\n", num);
+               return 1;
+       }
+
+       if ((status = check_power_mode (num)) == 0x00) {
+               debug ("Already in standby\n");
+               return 0;
+       }
+
+       if (status == 0x01) {
+               printf ("Failed to check power mode on ata%d\n", num);
+               return 1;
+       }
+
+       if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) {
+               printf ("Device ata%d not ready\n", num);
+               return 1;
+       }
+
+       writeb (0x00, port[num].ioaddr.feature_addr);
+
+       writeb (0x00, port[num].ioaddr.nsect_addr);
+       writeb (0x00, port[num].ioaddr.lbal_addr);
+       writeb (0x00, port[num].ioaddr.lbam_addr);
+       writeb (0x00, port[num].ioaddr.lbah_addr);
+
+       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
+       writeb (ATA_CMD_STANDBY, port[num].ioaddr.command_addr);
+
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0);
+       if ((status & (ATA_BUSY | ATA_ERR))) {
+               printf ("Error waiting for disk spin down: status 0x%02x\n",
+                       status);
+               port[num].dev_mask &= ~0x01;
+               return 1;
+       }
+       return 0;
+}
+
+u8 sil3114_spin_up (int num)
+{
+       u8 status = 0;
+
+       debug ("Spin up disk\n");
+
+       if (!(port[num].dev_mask & 0x01)) {
+               debug ("Device ata%d is not present\n", num);
+               return 1;
+       }
+
+       if ((status = check_power_mode (num)) != 0x00) {
+               if (status == 0x01) {
+                       printf ("Failed to check power mode on ata%d\n", num);
+                       return 1;
+               } else {
+                       /* should be up and running already */
+                       return 0;
+               }
+       }
+
+       if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) {
+               printf ("Device ata%d not ready\n", num);
+               return 1;
+       }
+
+       debug ("Stautus of device check: %d\n", status);
+
+       writeb (0x00, port[num].ioaddr.feature_addr);
+
+       writeb (0x00, port[num].ioaddr.nsect_addr);
+       writeb (0x00, port[num].ioaddr.lbal_addr);
+       writeb (0x00, port[num].ioaddr.lbam_addr);
+       writeb (0x00, port[num].ioaddr.lbah_addr);
+
+       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
+       writeb (ATA_CMD_IDLE, port[num].ioaddr.command_addr);
+
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0);
+       if ((status & (ATA_BUSY | ATA_ERR))) {
+               printf ("Error waiting for disk spin up: status 0x%02x\n",
+                       status);
+               port[num].dev_mask &= ~0x01;
+               return 1;
+       }
+
+       /* Wait for disk to enter Active state */
+       do {
+               msleep (10);
+               status = check_power_mode (num);
+       } while ((status == 0x00) || (status == 0x80));
+
+       if (status == 0x01) {
+               printf ("Falied waiting for disk to spin up\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+/* Return value is not the usual here
+ * 0x00 - Device stand by
+ * 0x01 - Operation failed
+ * 0x80 - Device idle
+ * 0xff - Device active
+*/
+static u8 check_power_mode (int num)
+{
+       u8 status = 0;
+       u8 res = 0;
+       if (!(port[num].dev_mask & 0x01)) {
+               debug ("Device ata%d is not present\n", num);
+               return 1;
+       }
+
+       if (!(sata_chk_status (&port[num].ioaddr, 0) & ATA_DRDY)) {
+               printf ("Device ata%d not ready\n", num);
+               return 1;
+       }
+
+       writeb (0, port[num].ioaddr.feature_addr);
+       writeb (0, port[num].ioaddr.nsect_addr);
+       writeb (0, port[num].ioaddr.lbal_addr);
+       writeb (0, port[num].ioaddr.lbam_addr);
+       writeb (0, port[num].ioaddr.lbah_addr);
+
+       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
+       writeb (ATA_CMD_CHK_POWER, port[num].ioaddr.command_addr);
+
+       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0);
+       if ((status & (ATA_BUSY | ATA_ERR))) {
+               printf
+                   ("Error waiting for check power mode complete  : status 0x%02x\n",
+                    status);
+               port[num].dev_mask &= ~0x01;
+               return 1;
+       }
+       res = readb (port[num].ioaddr.nsect_addr);
+       debug ("Check powermode: %d\n", res);
+       return res;
+
+}
+
+static void sata_port (struct sata_ioports *ioport)
+{
+       ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
+       ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
+       ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
+       ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
+       ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
+       ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
+       ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
+       ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
+       ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
+       ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
+}
+
+static u8 wait_for_irq (int num, unsigned int max)
+{
+
+       u32 port = iobase[5];
+       switch (num) {
+       case 0:
+               port += VND_TF_CNST_CH0;
+               break;
+       case 1:
+               port += VND_TF_CNST_CH1;
+               break;
+       case 2:
+               port += VND_TF_CNST_CH2;
+               break;
+       case 3:
+               port += VND_TF_CNST_CH3;
+               break;
+       default:
+               return 1;
+       }
+
+       do {
+               if (readl (port) & VND_TF_CNST_INTST) {
+                       break;
+               }
+               udelay (1000);
+               max--;
+       } while ((max > 0));
+
+       return (max == 0);
+}
+
+static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits,
+                         unsigned int max, u8 usealtstatus)
+{
+       u8 status;
+
+       do {
+               if (!((status = sata_chk_status (ioaddr, usealtstatus)) & bits)) {
+                       break;
+               }
+               udelay (1000);
+               max--;
+       } while ((status & bits) && (max > 0));
+
+       return status;
+}
+
+static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus)
+{
+       if (!usealtstatus) {
+               return readb (ioaddr->status_addr);
+       } else {
+               return readb (ioaddr->altstatus_addr);
+       }
+}
+
+static void msleep (int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               udelay (1000);
+}
+
+/* Read up to 255 sectors
+ *
+ * Returns sectors read
+*/
+static u8 do_one_read (int device, ulong block, u8 blkcnt, u16 * buff,
+                      uchar lba48)
+{
+
+       u8 sr = 0;
+       u8 status;
+       u64 blknr = (u64) block;
+
+       if (!(sata_chk_status (&port[device].ioaddr, 0) & ATA_DRDY)) {
+               printf ("Device ata%d not ready\n", device);
+               return 0;
+       }
+
+       /* Set up transfer */
+#ifdef CONFIG_LBA48
+       if (lba48) {
+               /* write high bits */
+               writeb (0, port[device].ioaddr.nsect_addr);
+               writeb ((blknr >> 24) & 0xFF, port[device].ioaddr.lbal_addr);
+               writeb ((blknr >> 32) & 0xFF, port[device].ioaddr.lbam_addr);
+               writeb ((blknr >> 40) & 0xFF, port[device].ioaddr.lbah_addr);
+       }
+#endif
+       writeb (blkcnt, port[device].ioaddr.nsect_addr);
+       writeb (((blknr) >> 0) & 0xFF, port[device].ioaddr.lbal_addr);
+       writeb ((blknr >> 8) & 0xFF, port[device].ioaddr.lbam_addr);
+       writeb ((blknr >> 16) & 0xFF, port[device].ioaddr.lbah_addr);
+
+#ifdef CONFIG_LBA48
+       if (lba48) {
+               writeb (ATA_LBA, port[device].ioaddr.device_addr);
+               writeb (ATA_CMD_PIO_READ_EXT, port[device].ioaddr.command_addr);
+       } else
+#endif
+       {
+               writeb (ATA_LBA | ((blknr >> 24) & 0xF),
+                       port[device].ioaddr.device_addr);
+               writeb (ATA_CMD_PIO_READ, port[device].ioaddr.command_addr);
+       }
+
+       status = sata_busy_wait (&port[device].ioaddr, ATA_BUSY, 10000, 1);
+
+       if (status & ATA_BUSY) {
+               u8 err = 0;
+
+               printf ("Device %d not responding status %d\n", device, status);
+               err = readb (port[device].ioaddr.error_addr);
+               printf ("Error reg = 0x%x\n", err);
+
+               return (sr);
+       }
+       while (blkcnt--) {
+
+               if (wait_for_irq (device, 500)) {
+                       printf ("ata%u irq failed\n", device);
+                       return sr;
+               }
+
+               status = sata_chk_status (&port[device].ioaddr, 0);
+               if (status & ATA_ERR) {
+                       printf ("ata%u error %d\n", device,
+                               readb (port[device].ioaddr.error_addr));
+                       return sr;
+               }
+               /* Read one sector */
+               input_data (&port[device].ioaddr, buff, ATA_SECTOR_WORDS);
+               buff += ATA_SECTOR_WORDS;
+               sr++;
+
+       }
+       return sr;
+}
+
+ulong sata_read (int device, ulong block, lbaint_t blkcnt, void *buff)
+{
+       ulong n = 0, sread;
+       u16 *buffer = (u16 *) buff;
+       u8 status = 0;
+       u64 blknr = (u64) block;
+       unsigned char lba48 = 0;
+
+#ifdef CONFIG_LBA48
+       if (blknr > 0xfffffff) {
+               if (!sata_dev_desc[device].lba48) {
+                       printf ("Drive doesn't support 48-bit addressing\n");
+                       return 0;
+               }
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+
+       while (blkcnt > 0) {
+
+               if (blkcnt > 255) {
+                       sread = 255;
+               } else {
+                       sread = blkcnt;
+               }
+
+               status = do_one_read (device, blknr, sread, buffer, lba48);
+               if (status != sread) {
+                       printf ("Read failed\n");
+                       return n;
+               }
+
+               blkcnt -= sread;
+               blknr += sread;
+               n += sread;
+               buffer += sread * ATA_SECTOR_WORDS;
+       }
+       return n;
+}
+
+ulong sata_write (int device, ulong block, lbaint_t blkcnt, const void *buff)
+{
+       ulong n = 0;
+       u16 *buffer = (u16 *) buff;
+       unsigned char status = 0, num = 0;
+       u64 blknr = (u64) block;
+#ifdef CONFIG_LBA48
+       unsigned char lba48 = 0;
+
+       if (blknr > 0xfffffff) {
+               if (!sata_dev_desc[device].lba48) {
+                       printf ("Drive doesn't support 48-bit addressing\n");
+                       return 0;
+               }
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+       /*Port Number */
+       num = device;
+
+       while (blkcnt-- > 0) {
+               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500, 0);
+               if (status & ATA_BUSY) {
+                       printf ("ata%u failed to respond\n", port[num].port_no);
+                       return n;
+               }
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       /* write high bits */
+                       writeb (0, port[num].ioaddr.nsect_addr);
+                       writeb ((blknr >> 24) & 0xFF,
+                               port[num].ioaddr.lbal_addr);
+                       writeb ((blknr >> 32) & 0xFF,
+                               port[num].ioaddr.lbam_addr);
+                       writeb ((blknr >> 40) & 0xFF,
+                               port[num].ioaddr.lbah_addr);
+               }
+#endif
+               writeb (1, port[num].ioaddr.nsect_addr);
+               writeb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
+               writeb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
+               writeb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       writeb (ATA_LBA, port[num].ioaddr.device_addr);
+                       writeb (ATA_CMD_PIO_WRITE_EXT, port[num].ioaddr.command_addr);
+               } else
+#endif
+               {
+                       writeb (ATA_LBA | ((blknr >> 24) & 0xF),
+                               port[num].ioaddr.device_addr);
+                       writeb (ATA_CMD_PIO_WRITE, port[num].ioaddr.command_addr);
+               }
+
+               msleep (50);
+               /*may take up to 4 sec */
+               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000, 0);
+               if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) {
+                       printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
+                               device, (ulong) blknr, status);
+                       return (n);
+               }
+
+               output_data (&port[num].ioaddr, buffer, ATA_SECTOR_WORDS);
+               readb (port[num].ioaddr.altstatus_addr);
+               udelay (50);
+
+               ++n;
+               ++blknr;
+               buffer += ATA_SECTOR_WORDS;
+       }
+       return n;
+}
+
+/* Driver implementation */
+static u8 sil_get_device_cache_line (pci_dev_t pdev)
+{
+       u8 cache_line = 0;
+       pci_read_config_byte (pdev, PCI_CACHE_LINE_SIZE, &cache_line);
+       return cache_line;
+}
+
+int init_sata (int dev)
+{
+       static u8 init_done = 0;
+       static int res = 1;
+       pci_dev_t devno;
+       u8 cls = 0;
+       u16 cmd = 0;
+       u32 sconf = 0;
+
+       if (init_done) {
+               return res;
+       }
+
+       init_done = 1;
+
+       if ((devno = pci_find_device (SIL_VEND_ID, SIL3114_DEVICE_ID, 0)) == -1) {
+               res = 1;
+               return res;
+       }
+
+       /* Read out all BARs, even though we only use MMIO from BAR5 */
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase[0]);
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_1, &iobase[1]);
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_2, &iobase[2]);
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_3, &iobase[3]);
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_4, &iobase[4]);
+       pci_read_config_dword (devno, PCI_BASE_ADDRESS_5, &iobase[5]);
+
+       if ((iobase[0] == 0xFFFFFFFF) || (iobase[1] == 0xFFFFFFFF) ||
+           (iobase[2] == 0xFFFFFFFF) || (iobase[3] == 0xFFFFFFFF) ||
+           (iobase[4] == 0xFFFFFFFF) || (iobase[5] == 0xFFFFFFFF)) {
+               printf ("Error no base addr for SATA controller\n");
+               res = 1;
+               return res;
+       }
+
+       /* mask off unused bits */
+       iobase[0] &= 0xfffffffc;
+       iobase[1] &= 0xfffffff8;
+       iobase[2] &= 0xfffffffc;
+       iobase[3] &= 0xfffffff8;
+       iobase[4] &= 0xfffffff0;
+       iobase[5] &= 0xfffffc00;
+
+       /* from sata_sil in Linux kernel */
+       cls = sil_get_device_cache_line (devno);
+       if (cls) {
+               cls >>= 3;
+               cls++;          /* cls = (line_size/8)+1 */
+               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH0);
+               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH1);
+               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH2);
+               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH3);
+       } else {
+               printf ("Cache line not set. Driver may not function\n");
+       }
+
+       /* Enable operation */
+       pci_read_config_word (devno, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+       pci_write_config_word (devno, PCI_COMMAND, cmd);
+
+       /* Disable interrupt usage */
+       pci_read_config_dword (devno, VND_SYSCONFSTAT, &sconf);
+       sconf |= (VND_SYSCONFSTAT_CHN_0_INTBLOCK | VND_SYSCONFSTAT_CHN_1_INTBLOCK);
+       pci_write_config_dword (devno, VND_SYSCONFSTAT, sconf);
+
+       res = 0;
+       return res;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+/* Check if device is connected to port */
+int sata_bus_probe (int portno)
+{
+       u32 port = iobase[5];
+       u32 val;
+       switch (portno) {
+       case 0:
+               port += VND_SSTATUS_CH0;
+               break;
+       case 1:
+               port += VND_SSTATUS_CH1;
+               break;
+       case 2:
+               port += VND_SSTATUS_CH2;
+               break;
+       case 3:
+               port += VND_SSTATUS_CH3;
+               break;
+       default:
+               return 0;
+       }
+       val = readl (port);
+       if ((val & SATA_DET_PRES) == SATA_DET_PRES) {
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int sata_phy_reset (int portno)
+{
+       u32 port = iobase[5];
+       u32 val;
+       switch (portno) {
+       case 0:
+               port += VND_SCONTROL_CH0;
+               break;
+       case 1:
+               port += VND_SCONTROL_CH1;
+               break;
+       case 2:
+               port += VND_SCONTROL_CH2;
+               break;
+       case 3:
+               port += VND_SCONTROL_CH3;
+               break;
+       default:
+               return 0;
+       }
+       val = readl (port);
+       writel (val | SATA_SC_DET_RST, port);
+       msleep (150);
+       writel (val & ~SATA_SC_DET_RST, port);
+       return 0;
+}
+
+int scan_sata (int dev)
+{
+       /* A bit brain dead, but the code has a legacy */
+       switch (dev) {
+       case 0:
+               port[0].port_no = 0;
+               port[0].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH0;
+               port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
+                   (iobase[5] + VND_TF2_CH0) | ATA_PCI_CTL_OFS;
+               port[0].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH0;
+               break;
+#if (CONFIG_SYS_SATA_MAX_DEVICE >= 1)
+       case 1:
+               port[1].port_no = 0;
+               port[1].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH1;
+               port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
+                   (iobase[5] + VND_TF2_CH1) | ATA_PCI_CTL_OFS;
+               port[1].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH1;
+               break;
+#elif (CONFIG_SYS_SATA_MAX_DEVICE >= 2)
+       case 2:
+               port[2].port_no = 0;
+               port[2].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH2;
+               port[2].ioaddr.altstatus_addr = port[2].ioaddr.ctl_addr =
+                   (iobase[5] + VND_TF2_CH2) | ATA_PCI_CTL_OFS;
+               port[2].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH2;
+               break;
+#elif (CONFIG_SYS_SATA_MAX_DEVICE >= 3)
+       case 3:
+               port[3].port_no = 0;
+               port[3].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH3;
+               port[3].ioaddr.altstatus_addr = port[3].ioaddr.ctl_addr =
+                   (iobase[5] + VND_TF2_CH3) | ATA_PCI_CTL_OFS;
+               port[3].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH3;
+               break;
+#endif
+       default:
+               printf ("Tried to scan unknown port: ata%d\n", dev);
+               return 1;
+       }
+
+       /* Initialize other registers */
+       sata_port (&port[dev].ioaddr);
+
+       /* Check for attached device */
+       if (!sata_bus_probe (dev)) {
+               port[dev].port_state = 0;
+               debug ("SATA#%d port is not present\n", dev);
+       } else {
+               debug ("SATA#%d port is present\n", dev);
+               if (sata_bus_softreset (dev)) {
+                       /* soft reset failed, try a hard one */
+                       sata_phy_reset (dev);
+                       if (sata_bus_softreset (dev)) {
+                               port[dev].port_state = 0;
+                       } else {
+                               port[dev].port_state = 1;
+                       }
+               } else {
+                       port[dev].port_state = 1;
+               }
+       }
+       if (port[dev].port_state == 1) {
+               /* Probe device and set xfer mode */
+               sata_identify (dev, 0);
+               set_Feature_cmd (dev, 0);
+       }
+
+       return 0;
+}
diff --git a/drivers/ata/sata_sil3114.h b/drivers/ata/sata_sil3114.h
new file mode 100644 (file)
index 0000000..091fca1
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) Excito Elektronik i Skåne AB, All rights reserved.
+ * Author: Tor Krill <tor@excito.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef SATA_SIL3114_H
+#define SATA_SIL3114_H
+
+struct sata_ioports {
+       unsigned long cmd_addr;
+       unsigned long data_addr;
+       unsigned long error_addr;
+       unsigned long feature_addr;
+       unsigned long nsect_addr;
+       unsigned long lbal_addr;
+       unsigned long lbam_addr;
+       unsigned long lbah_addr;
+       unsigned long device_addr;
+       unsigned long status_addr;
+       unsigned long command_addr;
+       unsigned long altstatus_addr;
+       unsigned long ctl_addr;
+       unsigned long bmdma_addr;
+       unsigned long scr_addr;
+};
+
+struct sata_port {
+       unsigned char port_no;  /* primary=0, secondary=1       */
+       struct sata_ioports ioaddr;     /* ATA cmd/ctl/dma reg blks     */
+       unsigned char ctl_reg;
+       unsigned char last_ctl;
+       unsigned char port_state;       /* 1-port is available and      */
+       /* 0-port is not available      */
+       unsigned char dev_mask;
+};
+
+/* Missing ata defines */
+#define ATA_CMD_STANDBY                        0xE2
+#define ATA_CMD_STANDBYNOW1            0xE0
+#define ATA_CMD_IDLE                   0xE3
+#define ATA_CMD_IDLEIMMEDIATE  0xE1
+
+/* Defines for SIL3114 chip */
+
+/* PCI defines */
+#define SIL_VEND_ID            0x1095
+#define SIL3114_DEVICE_ID      0x3114
+
+/* some vendor specific registers */
+#define        VND_SYSCONFSTAT 0x88    /* System Configuration Status and Command */
+#define VND_SYSCONFSTAT_CHN_0_INTBLOCK (1<<22)
+#define VND_SYSCONFSTAT_CHN_1_INTBLOCK (1<<23)
+#define VND_SYSCONFSTAT_CHN_2_INTBLOCK (1<<24)
+#define VND_SYSCONFSTAT_CHN_3_INTBLOCK (1<<25)
+
+/* internal registers mapped by BAR5 */
+/* SATA Control*/
+#define VND_SCONTROL_CH0       0x100
+#define VND_SCONTROL_CH1       0x180
+#define VND_SCONTROL_CH2       0x300
+#define VND_SCONTROL_CH3       0x380
+
+#define SATA_SC_IPM_T2P                (1<<16)
+#define SATA_SC_IPM_T2S                (2<<16)
+#define SATA_SC_SPD_1_5                (1<<4)
+#define SATA_SC_SPD_3_0                (2<<4)
+#define SATA_SC_DET_RST                (1)     /* ATA Reset sequence */
+#define SATA_SC_DET_PDIS       (4)     /* PHY Disable */
+
+/* SATA Status */
+#define VND_SSTATUS_CH0                0x104
+#define VND_SSTATUS_CH1                0x184
+#define VND_SSTATUS_CH2                0x304
+#define VND_SSTATUS_CH3                0x384
+
+#define SATA_SS_IPM_ACTIVE     (1<<8)
+#define SATA_SS_IPM_PARTIAL    (2<<8)
+#define SATA_SS_IPM_SLUMBER    (6<<8)
+#define SATA_SS_SPD_1_5                (1<<4)
+#define SATA_SS_SPD_3_0                (2<<4)
+#define SATA_DET_P_NOPHY       (1)     /* Device presence but no PHY connection established */
+#define SATA_DET_PRES          (3)     /* Device presence and active PHY */
+#define SATA_DET_OFFLINE       (4)     /* Device offline or in loopback mode */
+
+/* Task file registers in BAR5 mapping */
+#define VND_TF0_CH0                    0x80
+#define VND_TF0_CH1                    0xc0
+#define VND_TF0_CH2                    0x280
+#define VND_TF0_CH3                    0x2c0
+#define VND_TF1_CH0                    0x88
+#define VND_TF1_CH1                    0xc8
+#define VND_TF1_CH2                    0x288
+#define VND_TF1_CH3                    0x2c8
+#define VND_TF2_CH0                    0x88
+#define VND_TF2_CH1                    0xc8
+#define VND_TF2_CH2                    0x288
+#define VND_TF2_CH3                    0x2c8
+
+#define VND_BMDMA_CH0          0x00
+#define VND_BMDMA_CH1          0x08
+#define VND_BMDMA_CH2          0x200
+#define VND_BMDMA_CH3          0x208
+#define VND_BMDMA2_CH0         0x10
+#define VND_BMDMA2_CH1         0x18
+#define VND_BMDMA2_CH2         0x210
+#define VND_BMDMA2_CH3         0x218
+
+/* FIFO control */
+#define        VND_FIFOCFG_CH0         0x40
+#define        VND_FIFOCFG_CH1         0x44
+#define        VND_FIFOCFG_CH2         0x240
+#define        VND_FIFOCFG_CH3         0x244
+
+/* Task File configuration and status */
+#define VND_TF_CNST_CH0                0xa0
+#define VND_TF_CNST_CH1                0xe0
+#define VND_TF_CNST_CH2                0x2a0
+#define VND_TF_CNST_CH3                0x2e0
+
+#define VND_TF_CNST_BFCMD      (1<<1)
+#define VND_TF_CNST_CHNRST     (1<<2)
+#define VND_TF_CNST_VDMA       (1<<10)
+#define VND_TF_CNST_INTST      (1<<11)
+#define VND_TF_CNST_WDTO       (1<<12)
+#define VND_TF_CNST_WDEN       (1<<13)
+#define VND_TF_CNST_WDIEN      (1<<14)
+
+/* for testing */
+#define VND_SSDR                       0x04c   /* System Software Data Register */
+#define VND_FMACS                      0x050   /* Flash Memory Address control and status */
+
+#endif
index ed7fa88bf5f3f99641c2bc5d4be86535add7b11b..1ddd6508e40da4ed347c4cb010c2eb42bea03ece 100644 (file)
@@ -10,28 +10,6 @@ config BLK
          be partitioned into several areas, called 'partitions' in U-Boot.
          A filesystem can be placed in each partition.
 
-config AHCI
-       bool "Support SATA controllers with driver model"
-       depends on DM
-       help
-         This enables a uclass for disk controllers in U-Boot. Various driver
-         types can use this, such as AHCI/SATA. It does not provide any standard
-         operations at present. The block device interface has not been converted
-         to driver model.
-
-config SATA
-       bool "Support SATA controllers"
-       help
-         This enables support for SATA (Serial Advanced Technology
-         Attachment), a serial bus standard for connecting to hard drives and
-         other storage devices.
-
-         SATA replaces PATA (originally just ATA), which stands for Parallel AT
-         Attachment, where AT refers to an IBM AT (Advanced Technology)
-         computer released in 1984.
-
-         See also CMD_SATA which provides command-line support.
-
 config SCSI
        bool "Support SCSI controllers"
        help
@@ -59,29 +37,6 @@ config BLOCK_CACHE
          it will prevent repeated reads from directory structures and other
          filesystem data structures.
 
-menu "SATA/SCSI device support"
-
-config SATA_CEVA
-       bool "Ceva Sata controller"
-       depends on AHCI
-       depends on DM_SCSI
-       help
-         This option enables Ceva Sata controller hard IP available on Xilinx
-         ZynqMP. Support up to 2 external devices. Complient with SATA 3.1 and
-         AHCI 1.3 specifications with hot-plug detect feature.
-
-
-config DWC_AHCI
-       bool "Enable Synopsys DWC AHCI driver support"
-       select SCSI_AHCI
-       select PHY
-       depends on DM_SCSI
-       help
-         Enable this driver to support Sata devices through
-         Synopsys DWC AHCI module.
-
-endmenu
-
 config IDE
        bool "Support IDE controllers"
        help
index 035e078f814de24fa945168b9fd272ad2d4ebb19..064c76fc98a9f9a7efefece8c12e80681cd91ad6 100644 (file)
@@ -11,22 +11,8 @@ ifndef CONFIG_BLK
 obj-y += blk_legacy.o
 endif
 
-obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
-obj-$(CONFIG_AHCI) += ahci-uclass.o
-obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
-obj-$(CONFIG_SCSI_AHCI) += ahci.o
-obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
-obj-$(CONFIG_FSL_SATA) += fsl_sata.o
 obj-$(CONFIG_IDE) += ide.o
 obj-$(CONFIG_IDE_FTIDE020) += ftide020.o
-obj-$(CONFIG_LIBATA) += libata.o
-obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
-obj-$(CONFIG_MX51_PATA) += mxc_ata.o
-obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
-obj-$(CONFIG_SATA_DWC) += sata_dwc.o
-obj-$(CONFIG_SATA_MV) += sata_mv.o
-obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
-obj-$(CONFIG_SATA_SIL) += sata_sil.o
-obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
+obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
 obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
diff --git a/drivers/block/ahci-uclass.c b/drivers/block/ahci-uclass.c
deleted file mode 100644 (file)
index 7b8c326..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-
-UCLASS_DRIVER(ahci) = {
-       .id             = UCLASS_AHCI,
-       .name           = "ahci",
-};
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
deleted file mode 100644 (file)
index f474471..0000000
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
- * Copyright (C) Freescale Semiconductor, Inc. 2006.
- * Author: Jason Jin<Jason.jin@freescale.com>
- *         Zhang Wei<wei.zhang@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- *
- * with the reference on libata and ahci drvier in kernel
- */
-#include <common.h>
-
-#include <command.h>
-#include <dm.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <linux/errno.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <memalign.h>
-#include <scsi.h>
-#include <libata.h>
-#include <linux/ctype.h>
-#include <ahci.h>
-
-static int ata_io_flush(u8 port);
-
-struct ahci_probe_ent *probe_ent = NULL;
-u16 *ataid[AHCI_MAX_PORTS];
-
-#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
-
-/*
- * Some controllers limit number of blocks they can read/write at once.
- * Contemporary SSD devices work much faster if the read/write size is aligned
- * to a power of 2.  Let's set default to 128 and allowing to be overwritten if
- * needed.
- */
-#ifndef MAX_SATA_BLOCKS_READ_WRITE
-#define MAX_SATA_BLOCKS_READ_WRITE     0x80
-#endif
-
-/* Maximum timeouts for each event */
-#define WAIT_MS_SPINUP 20000
-#define WAIT_MS_DATAIO 10000
-#define WAIT_MS_FLUSH  5000
-#define WAIT_MS_LINKUP 200
-
-__weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
-{
-       return base + 0x100 + (port * 0x80);
-}
-
-
-static void ahci_setup_port(struct ahci_ioports *port, void __iomem *base,
-                           unsigned int port_idx)
-{
-       base = ahci_port_base(base, port_idx);
-
-       port->cmd_addr = base;
-       port->scr_addr = base + PORT_SCR;
-}
-
-
-#define msleep(a) udelay(a * 1000)
-
-static void ahci_dcache_flush_range(unsigned long begin, unsigned long len)
-{
-       const unsigned long start = begin;
-       const unsigned long end = start + len;
-
-       debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
-       flush_dcache_range(start, end);
-}
-
-/*
- * SATA controller DMAs to physical RAM.  Ensure data from the
- * controller is invalidated from dcache; next access comes from
- * physical RAM.
- */
-static void ahci_dcache_invalidate_range(unsigned long begin, unsigned long len)
-{
-       const unsigned long start = begin;
-       const unsigned long end = start + len;
-
-       debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
-       invalidate_dcache_range(start, end);
-}
-
-/*
- * Ensure data for SATA controller is flushed out of dcache and
- * written to physical memory.
- */
-static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
-{
-       ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
-                               AHCI_PORT_PRIV_DMA_SZ);
-}
-
-static int waiting_for_cmd_completed(void __iomem *offset,
-                                    int timeout_msec,
-                                    u32 sign)
-{
-       int i;
-       u32 status;
-
-       for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
-               msleep(1);
-
-       return (i < timeout_msec) ? 0 : -1;
-}
-
-int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port)
-{
-       u32 tmp;
-       int j = 0;
-       void __iomem *port_mmio = probe_ent->port[port].port_mmio;
-
-       /*
-        * Bring up SATA link.
-        * SATA link bringup time is usually less than 1 ms; only very
-        * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
-        */
-       while (j < WAIT_MS_LINKUP) {
-               tmp = readl(port_mmio + PORT_SCR_STAT);
-               tmp &= PORT_SCR_STAT_DET_MASK;
-               if (tmp == PORT_SCR_STAT_DET_PHYRDY)
-                       return 0;
-               udelay(1000);
-               j++;
-       }
-       return 1;
-}
-
-#ifdef CONFIG_SUNXI_AHCI
-/* The sunxi AHCI controller requires this undocumented setup */
-static void sunxi_dma_init(void __iomem *port_mmio)
-{
-       clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400);
-}
-#endif
-
-int ahci_reset(void __iomem *base)
-{
-       int i = 1000;
-       u32 __iomem *host_ctl_reg = base + HOST_CTL;
-       u32 tmp = readl(host_ctl_reg); /* global controller reset */
-
-       if ((tmp & HOST_RESET) == 0)
-               writel_with_flush(tmp | HOST_RESET, host_ctl_reg);
-
-       /*
-        * reset must complete within 1 second, or
-        * the hardware should be considered fried.
-        */
-       do {
-               udelay(1000);
-               tmp = readl(host_ctl_reg);
-               i--;
-       } while ((i > 0) && (tmp & HOST_RESET));
-
-       if (i == 0) {
-               printf("controller reset failed (0x%x)\n", tmp);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int ahci_host_init(struct ahci_probe_ent *probe_ent)
-{
-#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
-# ifdef CONFIG_DM_PCI
-       struct udevice *dev = probe_ent->dev;
-       struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
-# else
-       pci_dev_t pdev = probe_ent->dev;
-       unsigned short vendor;
-# endif
-       u16 tmp16;
-#endif
-       void __iomem *mmio = probe_ent->mmio_base;
-       u32 tmp, cap_save, cmd;
-       int i, j, ret;
-       void __iomem *port_mmio;
-       u32 port_map;
-
-       debug("ahci_host_init: start\n");
-
-       cap_save = readl(mmio + HOST_CAP);
-       cap_save &= ((1 << 28) | (1 << 17));
-       cap_save |= (1 << 27);  /* Staggered Spin-up. Not needed. */
-
-       ret = ahci_reset(probe_ent->mmio_base);
-       if (ret)
-               return ret;
-
-       writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
-       writel(cap_save, mmio + HOST_CAP);
-       writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
-
-#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
-# ifdef CONFIG_DM_PCI
-       if (pplat->vendor == PCI_VENDOR_ID_INTEL) {
-               u16 tmp16;
-
-               dm_pci_read_config16(dev, 0x92, &tmp16);
-               dm_pci_write_config16(dev, 0x92, tmp16 | 0xf);
-       }
-# else
-       pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
-
-       if (vendor == PCI_VENDOR_ID_INTEL) {
-               u16 tmp16;
-               pci_read_config_word(pdev, 0x92, &tmp16);
-               tmp16 |= 0xf;
-               pci_write_config_word(pdev, 0x92, tmp16);
-       }
-# endif
-#endif
-       probe_ent->cap = readl(mmio + HOST_CAP);
-       probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
-       port_map = probe_ent->port_map;
-       probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
-
-       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
-             probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
-
-       if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
-               probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               if (!(port_map & (1 << i)))
-                       continue;
-               probe_ent->port[i].port_mmio = ahci_port_base(mmio, i);
-               port_mmio = (u8 *) probe_ent->port[i].port_mmio;
-               ahci_setup_port(&probe_ent->port[i], mmio, i);
-
-               /* make sure port is not active */
-               tmp = readl(port_mmio + PORT_CMD);
-               if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-                          PORT_CMD_FIS_RX | PORT_CMD_START)) {
-                       debug("Port %d is active. Deactivating.\n", i);
-                       tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
-                                PORT_CMD_FIS_RX | PORT_CMD_START);
-                       writel_with_flush(tmp, port_mmio + PORT_CMD);
-
-                       /* spec says 500 msecs for each bit, so
-                        * this is slightly incorrect.
-                        */
-                       msleep(500);
-               }
-
-#ifdef CONFIG_SUNXI_AHCI
-               sunxi_dma_init(port_mmio);
-#endif
-
-               /* Add the spinup command to whatever mode bits may
-                * already be on in the command register.
-                */
-               cmd = readl(port_mmio + PORT_CMD);
-               cmd |= PORT_CMD_SPIN_UP;
-               writel_with_flush(cmd, port_mmio + PORT_CMD);
-
-               /* Bring up SATA link. */
-               ret = ahci_link_up(probe_ent, i);
-               if (ret) {
-                       printf("SATA link %d timeout.\n", i);
-                       continue;
-               } else {
-                       debug("SATA link ok.\n");
-               }
-
-               /* Clear error status */
-               tmp = readl(port_mmio + PORT_SCR_ERR);
-               if (tmp)
-                       writel(tmp, port_mmio + PORT_SCR_ERR);
-
-               debug("Spinning up device on SATA port %d... ", i);
-
-               j = 0;
-               while (j < WAIT_MS_SPINUP) {
-                       tmp = readl(port_mmio + PORT_TFDATA);
-                       if (!(tmp & (ATA_BUSY | ATA_DRQ)))
-                               break;
-                       udelay(1000);
-                       tmp = readl(port_mmio + PORT_SCR_STAT);
-                       tmp &= PORT_SCR_STAT_DET_MASK;
-                       if (tmp == PORT_SCR_STAT_DET_PHYRDY)
-                               break;
-                       j++;
-               }
-
-               tmp = readl(port_mmio + PORT_SCR_STAT) & PORT_SCR_STAT_DET_MASK;
-               if (tmp == PORT_SCR_STAT_DET_COMINIT) {
-                       debug("SATA link %d down (COMINIT received), retrying...\n", i);
-                       i--;
-                       continue;
-               }
-
-               printf("Target spinup took %d ms.\n", j);
-               if (j == WAIT_MS_SPINUP)
-                       debug("timeout.\n");
-               else
-                       debug("ok.\n");
-
-               tmp = readl(port_mmio + PORT_SCR_ERR);
-               debug("PORT_SCR_ERR 0x%x\n", tmp);
-               writel(tmp, port_mmio + PORT_SCR_ERR);
-
-               /* ack any pending irq events for this port */
-               tmp = readl(port_mmio + PORT_IRQ_STAT);
-               debug("PORT_IRQ_STAT 0x%x\n", tmp);
-               if (tmp)
-                       writel(tmp, port_mmio + PORT_IRQ_STAT);
-
-               writel(1 << i, mmio + HOST_IRQ_STAT);
-
-               /* register linkup ports */
-               tmp = readl(port_mmio + PORT_SCR_STAT);
-               debug("SATA port %d status: 0x%x\n", i, tmp);
-               if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
-                       probe_ent->link_port_map |= (0x01 << i);
-       }
-
-       tmp = readl(mmio + HOST_CTL);
-       debug("HOST_CTL 0x%x\n", tmp);
-       writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
-       tmp = readl(mmio + HOST_CTL);
-       debug("HOST_CTL 0x%x\n", tmp);
-#if !defined(CONFIG_DM_SCSI)
-#ifndef CONFIG_SCSI_AHCI_PLAT
-# ifdef CONFIG_DM_PCI
-       dm_pci_read_config16(dev, PCI_COMMAND, &tmp16);
-       tmp |= PCI_COMMAND_MASTER;
-       dm_pci_write_config16(dev, PCI_COMMAND, tmp16);
-# else
-       pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
-       tmp |= PCI_COMMAND_MASTER;
-       pci_write_config_word(pdev, PCI_COMMAND, tmp16);
-# endif
-#endif
-#endif
-       return 0;
-}
-
-
-static void ahci_print_info(struct ahci_probe_ent *probe_ent)
-{
-#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
-# if defined(CONFIG_DM_PCI)
-       struct udevice *dev = probe_ent->dev;
-# else
-       pci_dev_t pdev = probe_ent->dev;
-# endif
-       u16 cc;
-#endif
-       void __iomem *mmio = probe_ent->mmio_base;
-       u32 vers, cap, cap2, impl, speed;
-       const char *speed_s;
-       const char *scc_s;
-
-       vers = readl(mmio + HOST_VERSION);
-       cap = probe_ent->cap;
-       cap2 = readl(mmio + HOST_CAP2);
-       impl = probe_ent->port_map;
-
-       speed = (cap >> 20) & 0xf;
-       if (speed == 1)
-               speed_s = "1.5";
-       else if (speed == 2)
-               speed_s = "3";
-       else if (speed == 3)
-               speed_s = "6";
-       else
-               speed_s = "?";
-
-#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI)
-       scc_s = "SATA";
-#else
-# ifdef CONFIG_DM_PCI
-       dm_pci_read_config16(dev, 0x0a, &cc);
-# else
-       pci_read_config_word(pdev, 0x0a, &cc);
-# endif
-       if (cc == 0x0101)
-               scc_s = "IDE";
-       else if (cc == 0x0106)
-               scc_s = "SATA";
-       else if (cc == 0x0104)
-               scc_s = "RAID";
-       else
-               scc_s = "unknown";
-#endif
-       printf("AHCI %02x%02x.%02x%02x "
-              "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
-              (vers >> 24) & 0xff,
-              (vers >> 16) & 0xff,
-              (vers >> 8) & 0xff,
-              vers & 0xff,
-              ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
-
-       printf("flags: "
-              "%s%s%s%s%s%s%s"
-              "%s%s%s%s%s%s%s"
-              "%s%s%s%s%s%s\n",
-              cap & (1 << 31) ? "64bit " : "",
-              cap & (1 << 30) ? "ncq " : "",
-              cap & (1 << 28) ? "ilck " : "",
-              cap & (1 << 27) ? "stag " : "",
-              cap & (1 << 26) ? "pm " : "",
-              cap & (1 << 25) ? "led " : "",
-              cap & (1 << 24) ? "clo " : "",
-              cap & (1 << 19) ? "nz " : "",
-              cap & (1 << 18) ? "only " : "",
-              cap & (1 << 17) ? "pmp " : "",
-              cap & (1 << 16) ? "fbss " : "",
-              cap & (1 << 15) ? "pio " : "",
-              cap & (1 << 14) ? "slum " : "",
-              cap & (1 << 13) ? "part " : "",
-              cap & (1 << 7) ? "ccc " : "",
-              cap & (1 << 6) ? "ems " : "",
-              cap & (1 << 5) ? "sxs " : "",
-              cap2 & (1 << 2) ? "apst " : "",
-              cap2 & (1 << 1) ? "nvmp " : "",
-              cap2 & (1 << 0) ? "boh " : "");
-}
-
-#ifndef CONFIG_SCSI_AHCI_PLAT
-# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
-static int ahci_init_one(struct udevice *dev)
-# else
-static int ahci_init_one(pci_dev_t dev)
-# endif
-{
-#if !defined(CONFIG_DM_SCSI)
-       u16 vendor;
-#endif
-       int rc;
-
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       if (!probe_ent) {
-               printf("%s: No memory for probe_ent\n", __func__);
-               return -ENOMEM;
-       }
-
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
-       probe_ent->dev = dev;
-
-       probe_ent->host_flags = ATA_FLAG_SATA
-                               | ATA_FLAG_NO_LEGACY
-                               | ATA_FLAG_MMIO
-                               | ATA_FLAG_PIO_DMA
-                               | ATA_FLAG_NO_ATAPI;
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
-
-#if !defined(CONFIG_DM_SCSI)
-#ifdef CONFIG_DM_PCI
-       probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
-                                             PCI_REGION_MEM);
-
-       /* Take from kernel:
-        * JMicron-specific fixup:
-        * make sure we're in AHCI mode
-        */
-       dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor);
-       if (vendor == 0x197b)
-               dm_pci_write_config8(dev, 0x41, 0xa1);
-#else
-       probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
-                                          PCI_REGION_MEM);
-
-       /* Take from kernel:
-        * JMicron-specific fixup:
-        * make sure we're in AHCI mode
-        */
-       pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
-       if (vendor == 0x197b)
-               pci_write_config_byte(dev, 0x41, 0xa1);
-#endif
-#else
-       struct scsi_platdata *plat = dev_get_platdata(dev);
-       probe_ent->mmio_base = (void *)plat->base;
-#endif
-
-       debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
-       /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
-       if (rc)
-               goto err_out;
-
-       ahci_print_info(probe_ent);
-
-       return 0;
-
-      err_out:
-       return rc;
-}
-#endif
-
-#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
-
-static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
-       u32 sg_count;
-       int i;
-
-       sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
-       if (sg_count > AHCI_MAX_SG) {
-               printf("Error:Too much sg!\n");
-               return -1;
-       }
-
-       for (i = 0; i < sg_count; i++) {
-               ahci_sg->addr =
-                   cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
-               ahci_sg->addr_hi = 0;
-               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
-                                         (buf_len < MAX_DATA_BYTE_COUNT
-                                          ? (buf_len - 1)
-                                          : (MAX_DATA_BYTE_COUNT - 1)));
-               ahci_sg++;
-               buf_len -= MAX_DATA_BYTE_COUNT;
-       }
-
-       return sg_count;
-}
-
-
-static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
-{
-       pp->cmd_slot->opts = cpu_to_le32(opts);
-       pp->cmd_slot->status = 0;
-       pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff);
-#ifdef CONFIG_PHYS_64BIT
-       pp->cmd_slot->tbl_addr_hi =
-           cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16));
-#endif
-}
-
-static int wait_spinup(void __iomem *port_mmio)
-{
-       ulong start;
-       u32 tf_data;
-
-       start = get_timer(0);
-       do {
-               tf_data = readl(port_mmio + PORT_TFDATA);
-               if (!(tf_data & ATA_BUSY))
-                       return 0;
-       } while (get_timer(start) < WAIT_MS_SPINUP);
-
-       return -ETIMEDOUT;
-}
-
-static int ahci_port_start(u8 port)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       void __iomem *port_mmio = pp->port_mmio;
-       u32 port_status;
-       void __iomem *mem;
-
-       debug("Enter start port: %d\n", port);
-       port_status = readl(port_mmio + PORT_SCR_STAT);
-       debug("Port %d status: %x\n", port, port_status);
-       if ((port_status & 0xf) != 0x03) {
-               printf("No Link on this port!\n");
-               return -1;
-       }
-
-       mem = malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
-       if (!mem) {
-               free(pp);
-               printf("%s: No mem for table!\n", __func__);
-               return -ENOMEM;
-       }
-
-       /* Aligned to 2048-bytes */
-       mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ);
-       memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
-
-       /*
-        * First item in chunk of DMA memory: 32-slot command table,
-        * 32 bytes each in size
-        */
-       pp->cmd_slot =
-               (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
-       debug("cmd_slot = %p\n", pp->cmd_slot);
-       mem += (AHCI_CMD_SLOT_SZ + 224);
-
-       /*
-        * Second item: Received-FIS area
-        */
-       pp->rx_fis = virt_to_phys((void *)mem);
-       mem += AHCI_RX_FIS_SZ;
-
-       /*
-        * Third item: data area for storing a single command
-        * and its scatter-gather table
-        */
-       pp->cmd_tbl = virt_to_phys((void *)mem);
-       debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl);
-
-       mem += AHCI_CMD_TBL_HDR;
-       pp->cmd_tbl_sg =
-                       (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
-
-       writel_with_flush((unsigned long)pp->cmd_slot,
-                         port_mmio + PORT_LST_ADDR);
-
-       writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
-
-#ifdef CONFIG_SUNXI_AHCI
-       sunxi_dma_init(port_mmio);
-#endif
-
-       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
-                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
-                         PORT_CMD_START, port_mmio + PORT_CMD);
-
-       debug("Exit start port %d\n", port);
-
-       /*
-        * Make sure interface is not busy based on error and status
-        * information from task file data register before proceeding
-        */
-       return wait_spinup(port_mmio);
-}
-
-
-static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
-                               int buf_len, u8 is_write)
-{
-
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       void __iomem *port_mmio = pp->port_mmio;
-       u32 opts;
-       u32 port_status;
-       int sg_count;
-
-       debug("Enter %s: for port %d\n", __func__, port);
-
-       if (port > probe_ent->n_ports) {
-               printf("Invalid port number %d\n", port);
-               return -1;
-       }
-
-       port_status = readl(port_mmio + PORT_SCR_STAT);
-       if ((port_status & 0xf) != 0x03) {
-               debug("No Link on port %d!\n", port);
-               return -1;
-       }
-
-       memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
-
-       sg_count = ahci_fill_sg(port, buf, buf_len);
-       opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
-       ahci_fill_cmd_slot(pp, opts);
-
-       ahci_dcache_flush_sata_cmd(pp);
-       ahci_dcache_flush_range((unsigned long)buf, (unsigned long)buf_len);
-
-       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
-
-       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
-                               WAIT_MS_DATAIO, 0x1)) {
-               printf("timeout exit!\n");
-               return -1;
-       }
-
-       ahci_dcache_invalidate_range((unsigned long)buf,
-                                    (unsigned long)buf_len);
-       debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status);
-
-       return 0;
-}
-
-
-static char *ata_id_strcpy(u16 *target, u16 *src, int len)
-{
-       int i;
-       for (i = 0; i < len / 2; i++)
-               target[i] = swab16(src[i]);
-       return (char *)target;
-}
-
-/*
- * SCSI INQUIRY command operation.
- */
-static int ata_scsiop_inquiry(ccb *pccb)
-{
-       static const u8 hdr[] = {
-               0,
-               0,
-               0x5,            /* claim SPC-3 version compatibility */
-               2,
-               95 - 4,
-       };
-       u8 fis[20];
-       u16 *idbuf;
-       ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
-       u8 port;
-
-       /* Clean ccb data buffer */
-       memset(pccb->pdata, 0, pccb->datalen);
-
-       memcpy(pccb->pdata, hdr, sizeof(hdr));
-
-       if (pccb->datalen <= 35)
-               return 0;
-
-       memset(fis, 0, sizeof(fis));
-       /* Construct the FIS */
-       fis[0] = 0x27;          /* Host to device FIS. */
-       fis[1] = 1 << 7;        /* Command FIS. */
-       fis[2] = ATA_CMD_ID_ATA; /* Command byte. */
-
-       /* Read id from sata */
-       port = pccb->target;
-
-       if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), (u8 *)tmpid,
-                               ATA_ID_WORDS * 2, 0)) {
-               debug("scsi_ahci: SCSI inquiry command failure.\n");
-               return -EIO;
-       }
-
-       if (!ataid[port]) {
-               ataid[port] = malloc(ATA_ID_WORDS * 2);
-               if (!ataid[port]) {
-                       printf("%s: No memory for ataid[port]\n", __func__);
-                       return -ENOMEM;
-               }
-       }
-
-       idbuf = ataid[port];
-
-       memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
-       ata_swap_buf_le16(idbuf, ATA_ID_WORDS);
-
-       memcpy(&pccb->pdata[8], "ATA     ", 8);
-       ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16);
-       ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4);
-
-#ifdef DEBUG
-       ata_dump_id(idbuf);
-#endif
-       return 0;
-}
-
-
-/*
- * SCSI READ10/WRITE10 command operation.
- */
-static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
-{
-       lbaint_t lba = 0;
-       u16 blocks = 0;
-       u8 fis[20];
-       u8 *user_buffer = pccb->pdata;
-       u32 user_buffer_size = pccb->datalen;
-
-       /* Retrieve the base LBA number from the ccb structure. */
-       if (pccb->cmd[0] == SCSI_READ16) {
-               memcpy(&lba, pccb->cmd + 2, 8);
-               lba = be64_to_cpu(lba);
-       } else {
-               u32 temp;
-               memcpy(&temp, pccb->cmd + 2, 4);
-               lba = be32_to_cpu(temp);
-       }
-
-       /*
-        * Retrieve the base LBA number and the block count from
-        * the ccb structure.
-        *
-        * For 10-byte and 16-byte SCSI R/W commands, transfer
-        * length 0 means transfer 0 block of data.
-        * However, for ATA R/W commands, sector count 0 means
-        * 256 or 65536 sectors, not 0 sectors as in SCSI.
-        *
-        * WARNING: one or two older ATA drives treat 0 as 0...
-        */
-       if (pccb->cmd[0] == SCSI_READ16)
-               blocks = (((u16)pccb->cmd[13]) << 8) | ((u16) pccb->cmd[14]);
-       else
-               blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);
-
-       debug("scsi_ahci: %s %u blocks starting from lba 0x" LBAFU "\n",
-             is_write ?  "write" : "read", blocks, lba);
-
-       /* Preset the FIS */
-       memset(fis, 0, sizeof(fis));
-       fis[0] = 0x27;           /* Host to device FIS. */
-       fis[1] = 1 << 7;         /* Command FIS. */
-       /* Command byte (read/write). */
-       fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
-
-       while (blocks) {
-               u16 now_blocks; /* number of blocks per iteration */
-               u32 transfer_size; /* number of bytes per iteration */
-
-               now_blocks = min((u16)MAX_SATA_BLOCKS_READ_WRITE, blocks);
-
-               transfer_size = ATA_SECT_SIZE * now_blocks;
-               if (transfer_size > user_buffer_size) {
-                       printf("scsi_ahci: Error: buffer too small.\n");
-                       return -EIO;
-               }
-
-               /*
-                * LBA48 SATA command but only use 32bit address range within
-                * that (unless we've enabled 64bit LBA support). The next
-                * smaller command range (28bit) is too small.
-                */
-               fis[4] = (lba >> 0) & 0xff;
-               fis[5] = (lba >> 8) & 0xff;
-               fis[6] = (lba >> 16) & 0xff;
-               fis[7] = 1 << 6; /* device reg: set LBA mode */
-               fis[8] = ((lba >> 24) & 0xff);
-#ifdef CONFIG_SYS_64BIT_LBA
-               if (pccb->cmd[0] == SCSI_READ16) {
-                       fis[9] = ((lba >> 32) & 0xff);
-                       fis[10] = ((lba >> 40) & 0xff);
-               }
-#endif
-
-               fis[3] = 0xe0; /* features */
-
-               /* Block (sector) count */
-               fis[12] = (now_blocks >> 0) & 0xff;
-               fis[13] = (now_blocks >> 8) & 0xff;
-
-               /* Read/Write from ahci */
-               if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
-                                       user_buffer, transfer_size,
-                                       is_write)) {
-                       debug("scsi_ahci: SCSI %s10 command failure.\n",
-                             is_write ? "WRITE" : "READ");
-                       return -EIO;
-               }
-
-               /* If this transaction is a write, do a following flush.
-                * Writes in u-boot are so rare, and the logic to know when is
-                * the last write and do a flush only there is sufficiently
-                * difficult. Just do a flush after every write. This incurs,
-                * usually, one extra flush when the rare writes do happen.
-                */
-               if (is_write) {
-                       if (-EIO == ata_io_flush(pccb->target))
-                               return -EIO;
-               }
-               user_buffer += transfer_size;
-               user_buffer_size -= transfer_size;
-               blocks -= now_blocks;
-               lba += now_blocks;
-       }
-
-       return 0;
-}
-
-
-/*
- * SCSI READ CAPACITY10 command operation.
- */
-static int ata_scsiop_read_capacity10(ccb *pccb)
-{
-       u32 cap;
-       u64 cap64;
-       u32 block_size;
-
-       if (!ataid[pccb->target]) {
-               printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
-                      "\tNo ATA info!\n"
-                      "\tPlease run SCSI command INQUIRY first!\n");
-               return -EPERM;
-       }
-
-       cap64 = ata_id_n_sectors(ataid[pccb->target]);
-       if (cap64 > 0x100000000ULL)
-               cap64 = 0xffffffff;
-
-       cap = cpu_to_be32(cap64);
-       memcpy(pccb->pdata, &cap, sizeof(cap));
-
-       block_size = cpu_to_be32((u32)512);
-       memcpy(&pccb->pdata[4], &block_size, 4);
-
-       return 0;
-}
-
-
-/*
- * SCSI READ CAPACITY16 command operation.
- */
-static int ata_scsiop_read_capacity16(ccb *pccb)
-{
-       u64 cap;
-       u64 block_size;
-
-       if (!ataid[pccb->target]) {
-               printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
-                      "\tNo ATA info!\n"
-                      "\tPlease run SCSI command INQUIRY first!\n");
-               return -EPERM;
-       }
-
-       cap = ata_id_n_sectors(ataid[pccb->target]);
-       cap = cpu_to_be64(cap);
-       memcpy(pccb->pdata, &cap, sizeof(cap));
-
-       block_size = cpu_to_be64((u64)512);
-       memcpy(&pccb->pdata[8], &block_size, 8);
-
-       return 0;
-}
-
-
-/*
- * SCSI TEST UNIT READY command operation.
- */
-static int ata_scsiop_test_unit_ready(ccb *pccb)
-{
-       return (ataid[pccb->target]) ? 0 : -EPERM;
-}
-
-
-int scsi_exec(ccb *pccb)
-{
-       int ret;
-
-       switch (pccb->cmd[0]) {
-       case SCSI_READ16:
-       case SCSI_READ10:
-               ret = ata_scsiop_read_write(pccb, 0);
-               break;
-       case SCSI_WRITE10:
-               ret = ata_scsiop_read_write(pccb, 1);
-               break;
-       case SCSI_RD_CAPAC10:
-               ret = ata_scsiop_read_capacity10(pccb);
-               break;
-       case SCSI_RD_CAPAC16:
-               ret = ata_scsiop_read_capacity16(pccb);
-               break;
-       case SCSI_TST_U_RDY:
-               ret = ata_scsiop_test_unit_ready(pccb);
-               break;
-       case SCSI_INQUIRY:
-               ret = ata_scsiop_inquiry(pccb);
-               break;
-       default:
-               printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
-               return false;
-       }
-
-       if (ret) {
-               debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
-               return false;
-       }
-       return true;
-
-}
-
-#if defined(CONFIG_DM_SCSI)
-void scsi_low_level_init(int busdevfunc, struct udevice *dev)
-#else
-void scsi_low_level_init(int busdevfunc)
-#endif
-{
-       int i;
-       u32 linkmap;
-
-#ifndef CONFIG_SCSI_AHCI_PLAT
-# if defined(CONFIG_DM_PCI)
-       struct udevice *dev;
-       int ret;
-
-       ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
-       if (ret)
-               return;
-       ahci_init_one(dev);
-# elif defined(CONFIG_DM_SCSI)
-       ahci_init_one(dev);
-# else
-       ahci_init_one(busdevfunc);
-# endif
-#endif
-
-       linkmap = probe_ent->link_port_map;
-
-       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
-               if (((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start((u8) i)) {
-                               printf("Can not start port %d\n", i);
-                               continue;
-                       }
-               }
-       }
-}
-
-#ifdef CONFIG_SCSI_AHCI_PLAT
-int ahci_init(void __iomem *base)
-{
-       int i, rc = 0;
-       u32 linkmap;
-
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       if (!probe_ent) {
-               printf("%s: No memory for probe_ent\n", __func__);
-               return -ENOMEM;
-       }
-
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
-
-       probe_ent->host_flags = ATA_FLAG_SATA
-                               | ATA_FLAG_NO_LEGACY
-                               | ATA_FLAG_MMIO
-                               | ATA_FLAG_PIO_DMA
-                               | ATA_FLAG_NO_ATAPI;
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
-
-       probe_ent->mmio_base = base;
-
-       /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
-       if (rc)
-               goto err_out;
-
-       ahci_print_info(probe_ent);
-
-       linkmap = probe_ent->link_port_map;
-
-       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
-               if (((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start((u8) i)) {
-                               printf("Can not start port %d\n", i);
-                               continue;
-                       }
-               }
-       }
-err_out:
-       return rc;
-}
-
-void __weak scsi_init(void)
-{
-}
-
-#endif
-
-/*
- * In the general case of generic rotating media it makes sense to have a
- * flush capability. It probably even makes sense in the case of SSDs because
- * one cannot always know for sure what kind of internal cache/flush mechanism
- * is embodied therein. At first it was planned to invoke this after the last
- * write to disk and before rebooting. In practice, knowing, a priori, which
- * is the last write is difficult. Because writing to the disk in u-boot is
- * very rare, this flush command will be invoked after every block write.
- */
-static int ata_io_flush(u8 port)
-{
-       u8 fis[20];
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       void __iomem *port_mmio = pp->port_mmio;
-       u32 cmd_fis_len = 5;    /* five dwords */
-
-       /* Preset the FIS */
-       memset(fis, 0, 20);
-       fis[0] = 0x27;           /* Host to device FIS. */
-       fis[1] = 1 << 7;         /* Command FIS. */
-       fis[2] = ATA_CMD_FLUSH_EXT;
-
-       memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
-       ahci_fill_cmd_slot(pp, cmd_fis_len);
-       ahci_dcache_flush_sata_cmd(pp);
-       writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
-
-       if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
-                       WAIT_MS_FLUSH, 0x1)) {
-               debug("scsi_ahci: flush command timeout on port %d.\n", port);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-
-__weak void scsi_bus_reset(void)
-{
-       /*Not implement*/
-}
diff --git a/drivers/block/dwc_ahci.c b/drivers/block/dwc_ahci.c
deleted file mode 100644 (file)
index 3f839bf..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * DWC SATA platform driver
- *
- * (C) Copyright 2016
- *     Texas Instruments Incorporated, <www.ti.com>
- *
- * Author: Mugunthan V N <mugunthanvnm@ti.com>
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <ahci.h>
-#include <scsi.h>
-#include <sata.h>
-#include <asm/arch/sata.h>
-#include <asm/io.h>
-#include <generic-phy.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct dwc_ahci_priv {
-       void *base;
-       void *wrapper_base;
-};
-
-static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
-{
-       struct dwc_ahci_priv *priv = dev_get_priv(dev);
-       struct scsi_platdata *plat = dev_get_platdata(dev);
-       fdt_addr_t addr;
-
-       plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-                                      "max-id", CONFIG_SYS_SCSI_MAX_SCSI_ID);
-       plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-                                       "max-lun", CONFIG_SYS_SCSI_MAX_LUN);
-
-       priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *),
-                                MAP_NOCACHE);
-
-       addr = devfdt_get_addr_index(dev, 1);
-       if (addr != FDT_ADDR_T_NONE) {
-               priv->wrapper_base = map_physmem(addr, sizeof(void *),
-                                                MAP_NOCACHE);
-       } else {
-               priv->wrapper_base = NULL;
-       }
-
-       return 0;
-}
-
-static int dwc_ahci_probe(struct udevice *dev)
-{
-       struct dwc_ahci_priv *priv = dev_get_priv(dev);
-       int ret;
-       struct phy phy;
-
-       ret = generic_phy_get_by_name(dev, "sata-phy", &phy);
-       if (ret) {
-               error("can't get the phy from DT\n");
-               return ret;
-       }
-
-       ret = generic_phy_init(&phy);
-       if (ret) {
-               error("unable to initialize the sata phy\n");
-               return ret;
-       }
-
-       ret = generic_phy_power_on(&phy);
-       if (ret) {
-               error("unable to power on the sata phy\n");
-               return ret;
-       }
-
-       if (priv->wrapper_base) {
-               u32 val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
-
-               /* Enable SATA module, No Idle, No Standby */
-               writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
-       }
-
-       return ahci_init(priv->base);
-}
-
-static const struct udevice_id dwc_ahci_ids[] = {
-       { .compatible = "snps,dwc-ahci" },
-       { }
-};
-
-U_BOOT_DRIVER(dwc_ahci) = {
-       .name   = "dwc_ahci",
-       .id     = UCLASS_SCSI,
-       .of_match = dwc_ahci_ids,
-       .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata,
-       .probe  = dwc_ahci_probe,
-       .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
-       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
-       .flags = DM_FLAG_ALLOC_PRIV_DMA,
-};
diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c
deleted file mode 100644 (file)
index c306e92..0000000
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
- * Terry Lv <r65388@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <libata.h>
-#include <ahci.h>
-#include <fis.h>
-#include <sata.h>
-
-#include <common.h>
-#include <malloc.h>
-#include <linux/ctype.h>
-#include <linux/errno.h>
-#include <asm/io.h>
-#include <linux/bitops.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/sys_proto.h>
-#include "dwc_ahsata.h"
-
-struct sata_port_regs {
-       u32 clb;
-       u32 clbu;
-       u32 fb;
-       u32 fbu;
-       u32 is;
-       u32 ie;
-       u32 cmd;
-       u32 res1[1];
-       u32 tfd;
-       u32 sig;
-       u32 ssts;
-       u32 sctl;
-       u32 serr;
-       u32 sact;
-       u32 ci;
-       u32 sntf;
-       u32 res2[1];
-       u32 dmacr;
-       u32 res3[1];
-       u32 phycr;
-       u32 physr;
-};
-
-struct sata_host_regs {
-       u32 cap;
-       u32 ghc;
-       u32 is;
-       u32 pi;
-       u32 vs;
-       u32 ccc_ctl;
-       u32 ccc_ports;
-       u32 res1[2];
-       u32 cap2;
-       u32 res2[30];
-       u32 bistafr;
-       u32 bistcr;
-       u32 bistfctr;
-       u32 bistsr;
-       u32 bistdecr;
-       u32 res3[2];
-       u32 oobr;
-       u32 res4[8];
-       u32 timer1ms;
-       u32 res5[1];
-       u32 gparam1r;
-       u32 gparam2r;
-       u32 pparamr;
-       u32 testr;
-       u32 versionr;
-       u32 idr;
-};
-
-#define MAX_DATA_BYTES_PER_SG  (4 * 1024 * 1024)
-#define MAX_BYTES_PER_TRANS (AHCI_MAX_SG * MAX_DATA_BYTES_PER_SG)
-
-#define writel_with_flush(a, b)        do { writel(a, b); readl(b); } while (0)
-
-static int is_ready;
-
-static inline void __iomem *ahci_port_base(void __iomem *base, u32 port)
-{
-       return base + 0x100 + (port * 0x80);
-}
-
-static int waiting_for_cmd_completed(u8 *offset,
-                                       int timeout_msec,
-                                       u32 sign)
-{
-       int i;
-       u32 status;
-
-       for (i = 0;
-               ((status = readl(offset)) & sign) && i < timeout_msec;
-               ++i)
-               mdelay(1);
-
-       return (i < timeout_msec) ? 0 : -1;
-}
-
-static int ahci_setup_oobr(struct ahci_probe_ent *probe_ent,
-                                               int clk)
-{
-       struct sata_host_regs *host_mmio =
-               (struct sata_host_regs *)probe_ent->mmio_base;
-
-       writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr));
-       writel(0x02060b14, &(host_mmio->oobr));
-
-       return 0;
-}
-
-static int ahci_host_init(struct ahci_probe_ent *probe_ent)
-{
-       u32 tmp, cap_save, num_ports;
-       int i, j, timeout = 1000;
-       struct sata_port_regs *port_mmio = NULL;
-       struct sata_host_regs *host_mmio =
-               (struct sata_host_regs *)probe_ent->mmio_base;
-       int clk = mxc_get_clock(MXC_SATA_CLK);
-
-       cap_save = readl(&(host_mmio->cap));
-       cap_save |= SATA_HOST_CAP_SSS;
-
-       /* global controller reset */
-       tmp = readl(&(host_mmio->ghc));
-       if ((tmp & SATA_HOST_GHC_HR) == 0)
-               writel_with_flush(tmp | SATA_HOST_GHC_HR, &(host_mmio->ghc));
-
-       while ((readl(&(host_mmio->ghc)) & SATA_HOST_GHC_HR)
-               && --timeout)
-               ;
-
-       if (timeout <= 0) {
-               debug("controller reset failed (0x%x)\n", tmp);
-               return -1;
-       }
-
-       /* Set timer 1ms */
-       writel(clk / 1000, &(host_mmio->timer1ms));
-
-       ahci_setup_oobr(probe_ent, 0);
-
-       writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc));
-       writel(cap_save, &(host_mmio->cap));
-       num_ports = (cap_save & SATA_HOST_CAP_NP_MASK) + 1;
-       writel_with_flush((1 << num_ports) - 1,
-                               &(host_mmio->pi));
-
-       /*
-        * Determine which Ports are implemented by the DWC_ahsata,
-        * by reading the PI register. This bit map value aids the
-        * software to determine how many Ports are available and
-        * which Port registers need to be initialized.
-        */
-       probe_ent->cap = readl(&(host_mmio->cap));
-       probe_ent->port_map = readl(&(host_mmio->pi));
-
-       /* Determine how many command slots the HBA supports */
-       probe_ent->n_ports =
-               (probe_ent->cap & SATA_HOST_CAP_NP_MASK) + 1;
-
-       debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
-               probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               probe_ent->port[i].port_mmio =
-                       ahci_port_base(host_mmio, i);
-               port_mmio =
-                       (struct sata_port_regs *)probe_ent->port[i].port_mmio;
-
-               /* Ensure that the DWC_ahsata is in idle state */
-               tmp = readl(&(port_mmio->cmd));
-
-               /*
-                * When P#CMD.ST, P#CMD.CR, P#CMD.FRE and P#CMD.FR
-                * are all cleared, the Port is in an idle state.
-                */
-               if (tmp & (SATA_PORT_CMD_CR | SATA_PORT_CMD_FR |
-                       SATA_PORT_CMD_FRE | SATA_PORT_CMD_ST)) {
-
-                       /*
-                        * System software places a Port into the idle state by
-                        * clearing P#CMD.ST and waiting for P#CMD.CR to return
-                        * 0 when read.
-                        */
-                       tmp &= ~SATA_PORT_CMD_ST;
-                       writel_with_flush(tmp, &(port_mmio->cmd));
-
-                       /*
-                        * spec says 500 msecs for each bit, so
-                        * this is slightly incorrect.
-                        */
-                       mdelay(500);
-
-                       timeout = 1000;
-                       while ((readl(&(port_mmio->cmd)) & SATA_PORT_CMD_CR)
-                               && --timeout)
-                               ;
-
-                       if (timeout <= 0) {
-                               debug("port reset failed (0x%x)\n", tmp);
-                               return -1;
-                       }
-               }
-
-               /* Spin-up device */
-               tmp = readl(&(port_mmio->cmd));
-               writel((tmp | SATA_PORT_CMD_SUD), &(port_mmio->cmd));
-
-               /* Wait for spin-up to finish */
-               timeout = 1000;
-               while (!(readl(&(port_mmio->cmd)) | SATA_PORT_CMD_SUD)
-                       && --timeout)
-                       ;
-               if (timeout <= 0) {
-                       debug("Spin-Up can't finish!\n");
-                       return -1;
-               }
-
-               for (j = 0; j < 100; ++j) {
-                       mdelay(10);
-                       tmp = readl(&(port_mmio->ssts));
-                       if (((tmp & SATA_PORT_SSTS_DET_MASK) == 0x3) ||
-                               ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x1))
-                               break;
-               }
-
-               /* Wait for COMINIT bit 26 (DIAG_X) in SERR */
-               timeout = 1000;
-               while (!(readl(&(port_mmio->serr)) | SATA_PORT_SERR_DIAG_X)
-                       && --timeout)
-                       ;
-               if (timeout <= 0) {
-                       debug("Can't find DIAG_X set!\n");
-                       return -1;
-               }
-
-               /*
-                * For each implemented Port, clear the P#SERR
-                * register, by writing ones to each implemented\
-                * bit location.
-                */
-               tmp = readl(&(port_mmio->serr));
-               debug("P#SERR 0x%x\n",
-                               tmp);
-               writel(tmp, &(port_mmio->serr));
-
-               /* Ack any pending irq events for this port */
-               tmp = readl(&(host_mmio->is));
-               debug("IS 0x%x\n", tmp);
-               if (tmp)
-                       writel(tmp, &(host_mmio->is));
-
-               writel(1 << i, &(host_mmio->is));
-
-               /* set irq mask (enables interrupts) */
-               writel(DEF_PORT_IRQ, &(port_mmio->ie));
-
-               /* register linkup ports */
-               tmp = readl(&(port_mmio->ssts));
-               debug("Port %d status: 0x%x\n", i, tmp);
-               if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03)
-                       probe_ent->link_port_map |= (0x01 << i);
-       }
-
-       tmp = readl(&(host_mmio->ghc));
-       debug("GHC 0x%x\n", tmp);
-       writel(tmp | SATA_HOST_GHC_IE, &(host_mmio->ghc));
-       tmp = readl(&(host_mmio->ghc));
-       debug("GHC 0x%x\n", tmp);
-
-       return 0;
-}
-
-static void ahci_print_info(struct ahci_probe_ent *probe_ent)
-{
-       struct sata_host_regs *host_mmio =
-               (struct sata_host_regs *)probe_ent->mmio_base;
-       u32 vers, cap, impl, speed;
-       const char *speed_s;
-       const char *scc_s;
-
-       vers = readl(&(host_mmio->vs));
-       cap = probe_ent->cap;
-       impl = probe_ent->port_map;
-
-       speed = (cap & SATA_HOST_CAP_ISS_MASK)
-               >> SATA_HOST_CAP_ISS_OFFSET;
-       if (speed == 1)
-               speed_s = "1.5";
-       else if (speed == 2)
-               speed_s = "3";
-       else
-               speed_s = "?";
-
-       scc_s = "SATA";
-
-       printf("AHCI %02x%02x.%02x%02x "
-               "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
-               (vers >> 24) & 0xff,
-               (vers >> 16) & 0xff,
-               (vers >> 8) & 0xff,
-               vers & 0xff,
-               ((cap >> 8) & 0x1f) + 1,
-               (cap & 0x1f) + 1,
-               speed_s,
-               impl,
-               scc_s);
-
-       printf("flags: "
-               "%s%s%s%s%s%s"
-               "%s%s%s%s%s%s%s\n",
-               cap & (1 << 31) ? "64bit " : "",
-               cap & (1 << 30) ? "ncq " : "",
-               cap & (1 << 28) ? "ilck " : "",
-               cap & (1 << 27) ? "stag " : "",
-               cap & (1 << 26) ? "pm " : "",
-               cap & (1 << 25) ? "led " : "",
-               cap & (1 << 24) ? "clo " : "",
-               cap & (1 << 19) ? "nz " : "",
-               cap & (1 << 18) ? "only " : "",
-               cap & (1 << 17) ? "pmp " : "",
-               cap & (1 << 15) ? "pio " : "",
-               cap & (1 << 14) ? "slum " : "",
-               cap & (1 << 13) ? "part " : "");
-}
-
-static int ahci_init_one(int pdev)
-{
-       int rc;
-       struct ahci_probe_ent *probe_ent = NULL;
-
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
-       probe_ent->dev = pdev;
-
-       probe_ent->host_flags = ATA_FLAG_SATA
-                               | ATA_FLAG_NO_LEGACY
-                               | ATA_FLAG_MMIO
-                               | ATA_FLAG_PIO_DMA
-                               | ATA_FLAG_NO_ATAPI;
-
-       probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR;
-
-       /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
-       if (rc)
-               goto err_out;
-
-       ahci_print_info(probe_ent);
-
-       /* Save the private struct to block device struct */
-       sata_dev_desc[pdev].priv = (void *)probe_ent;
-
-       return 0;
-
-err_out:
-       return rc;
-}
-
-static int ahci_fill_sg(struct ahci_probe_ent *probe_ent,
-                       u8 port, unsigned char *buf, int buf_len)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
-       u32 sg_count, max_bytes;
-       int i;
-
-       max_bytes = MAX_DATA_BYTES_PER_SG;
-       sg_count = ((buf_len - 1) / max_bytes) + 1;
-       if (sg_count > AHCI_MAX_SG) {
-               printf("Error:Too much sg!\n");
-               return -1;
-       }
-
-       for (i = 0; i < sg_count; i++) {
-               ahci_sg->addr =
-                       cpu_to_le32((u32)buf + i * max_bytes);
-               ahci_sg->addr_hi = 0;
-               ahci_sg->flags_size = cpu_to_le32(0x3fffff &
-                                       (buf_len < max_bytes
-                                       ? (buf_len - 1)
-                                       : (max_bytes - 1)));
-               ahci_sg++;
-               buf_len -= max_bytes;
-       }
-
-       return sg_count;
-}
-
-static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts)
-{
-       struct ahci_cmd_hdr *cmd_hdr = (struct ahci_cmd_hdr *)(pp->cmd_slot +
-                                       AHCI_CMD_SLOT_SZ * cmd_slot);
-
-       memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ);
-       cmd_hdr->opts = cpu_to_le32(opts);
-       cmd_hdr->status = 0;
-       pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff);
-#ifdef CONFIG_PHYS_64BIT
-       pp->cmd_slot->tbl_addr_hi =
-           cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16));
-#endif
-}
-
-#define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0)
-
-static int ahci_exec_ata_cmd(struct ahci_probe_ent *probe_ent,
-               u8 port, struct sata_fis_h2d *cfis,
-               u8 *buf, u32 buf_len, s32 is_write)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       struct sata_port_regs *port_mmio =
-                       (struct sata_port_regs *)pp->port_mmio;
-       u32 opts;
-       int sg_count = 0, cmd_slot = 0;
-
-       cmd_slot = AHCI_GET_CMD_SLOT(readl(&(port_mmio->ci)));
-       if (32 == cmd_slot) {
-               printf("Can't find empty command slot!\n");
-               return 0;
-       }
-
-       /* Check xfer length */
-       if (buf_len > MAX_BYTES_PER_TRANS) {
-               printf("Max transfer length is %dB\n\r",
-                       MAX_BYTES_PER_TRANS);
-               return 0;
-       }
-
-       memcpy((u8 *)(pp->cmd_tbl), cfis, sizeof(struct sata_fis_h2d));
-       if (buf && buf_len)
-               sg_count = ahci_fill_sg(probe_ent, port, buf, buf_len);
-       opts = (sizeof(struct sata_fis_h2d) >> 2) | (sg_count << 16);
-       if (is_write) {
-               opts |= 0x40;
-               flush_cache((ulong)buf, buf_len);
-       }
-       ahci_fill_cmd_slot(pp, cmd_slot, opts);
-
-       flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ);
-       writel_with_flush(1 << cmd_slot, &(port_mmio->ci));
-
-       if (waiting_for_cmd_completed((u8 *)&(port_mmio->ci),
-                               10000, 0x1 << cmd_slot)) {
-               printf("timeout exit!\n");
-               return -1;
-       }
-       invalidate_dcache_range((int)(pp->cmd_slot),
-                               (int)(pp->cmd_slot)+AHCI_PORT_PRIV_DMA_SZ);
-       debug("ahci_exec_ata_cmd: %d byte transferred.\n",
-             pp->cmd_slot->status);
-       if (!is_write)
-               invalidate_dcache_range((ulong)buf, (ulong)buf+buf_len);
-
-       return buf_len;
-}
-
-static void ahci_set_feature(u8 dev, u8 port)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 1 << 7;
-       cfis->command = ATA_CMD_SET_FEATURES;
-       cfis->features = SETFEATURES_XFER;
-       cfis->sector_count = ffs(probe_ent->udma_mask + 1) + 0x3e;
-
-       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD);
-}
-
-static int ahci_port_start(struct ahci_probe_ent *probe_ent,
-                                       u8 port)
-{
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
-       struct sata_port_regs *port_mmio =
-               (struct sata_port_regs *)pp->port_mmio;
-       u32 port_status;
-       u32 mem;
-       int timeout = 10000000;
-
-       debug("Enter start port: %d\n", port);
-       port_status = readl(&(port_mmio->ssts));
-       debug("Port %d status: %x\n", port, port_status);
-       if ((port_status & 0xf) != 0x03) {
-               printf("No Link on this port!\n");
-               return -1;
-       }
-
-       mem = (u32)malloc(AHCI_PORT_PRIV_DMA_SZ + 1024);
-       if (!mem) {
-               free(pp);
-               printf("No mem for table!\n");
-               return -ENOMEM;
-       }
-
-       mem = (mem + 0x400) & (~0x3ff); /* Aligned to 1024-bytes */
-       memset((u8 *)mem, 0, AHCI_PORT_PRIV_DMA_SZ);
-
-       /*
-        * First item in chunk of DMA memory: 32-slot command table,
-        * 32 bytes each in size
-        */
-       pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
-       debug("cmd_slot = 0x%x\n", (unsigned int) pp->cmd_slot);
-       mem += (AHCI_CMD_SLOT_SZ * DWC_AHSATA_MAX_CMD_SLOTS);
-
-       /*
-        * Second item: Received-FIS area, 256-Byte aligned
-        */
-       pp->rx_fis = mem;
-       mem += AHCI_RX_FIS_SZ;
-
-       /*
-        * Third item: data area for storing a single command
-        * and its scatter-gather table
-        */
-       pp->cmd_tbl = mem;
-       debug("cmd_tbl_dma = 0x%lx\n", pp->cmd_tbl);
-
-       mem += AHCI_CMD_TBL_HDR;
-
-       writel_with_flush(0x00004444, &(port_mmio->dmacr));
-       pp->cmd_tbl_sg = (struct ahci_sg *)mem;
-       writel_with_flush((u32)pp->cmd_slot, &(port_mmio->clb));
-       writel_with_flush(pp->rx_fis, &(port_mmio->fb));
-
-       /* Enable FRE */
-       writel_with_flush((SATA_PORT_CMD_FRE | readl(&(port_mmio->cmd))),
-                       &(port_mmio->cmd));
-
-       /* Wait device ready */
-       while ((readl(&(port_mmio->tfd)) & (SATA_PORT_TFD_STS_ERR |
-               SATA_PORT_TFD_STS_DRQ | SATA_PORT_TFD_STS_BSY))
-               && --timeout)
-               ;
-       if (timeout <= 0) {
-               debug("Device not ready for BSY, DRQ and"
-                       "ERR in TFD!\n");
-               return -1;
-       }
-
-       writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
-                         PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
-                         PORT_CMD_START, &(port_mmio->cmd));
-
-       debug("Exit start port %d\n", port);
-
-       return 0;
-}
-
-int init_sata(int dev)
-{
-       int i;
-       u32 linkmap;
-       struct ahci_probe_ent *probe_ent = NULL;
-
-#if defined(CONFIG_MX6)
-       if (!is_mx6dq() && !is_mx6dqp())
-               return 1;
-#endif
-       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
-               printf("The sata index %d is out of ranges\n\r", dev);
-               return -1;
-       }
-
-       ahci_init_one(dev);
-
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       linkmap = probe_ent->link_port_map;
-
-       if (0 == linkmap) {
-               printf("No port device detected!\n");
-               return 1;
-       }
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               if ((linkmap >> i) && ((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start(probe_ent, (u8)i)) {
-                               printf("Can not start port %d\n", i);
-                               return 1;
-                       }
-                       probe_ent->hard_port_no = i;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-int reset_sata(int dev)
-{
-       struct ahci_probe_ent *probe_ent;
-       struct sata_host_regs *host_mmio;
-
-       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
-               printf("The sata index %d is out of ranges\n\r", dev);
-               return -1;
-       }
-
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       if (NULL == probe_ent)
-               /* not initialized, so nothing to reset */
-               return 0;
-
-       host_mmio = (struct sata_host_regs *)probe_ent->mmio_base;
-       setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR);
-       while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR)
-               udelay(100);
-
-       return 0;
-}
-
-static void dwc_ahsata_print_info(int dev)
-{
-       struct blk_desc *pdev = &(sata_dev_desc[dev]);
-
-       printf("SATA Device Info:\n\r");
-#ifdef CONFIG_SYS_64BIT_LBA
-       printf("S/N: %s\n\rProduct model number: %s\n\r"
-               "Firmware version: %s\n\rCapacity: %lld sectors\n\r",
-               pdev->product, pdev->vendor, pdev->revision, pdev->lba);
-#else
-       printf("S/N: %s\n\rProduct model number: %s\n\r"
-               "Firmware version: %s\n\rCapacity: %ld sectors\n\r",
-               pdev->product, pdev->vendor, pdev->revision, pdev->lba);
-#endif
-}
-
-static void dwc_ahsata_identify(int dev, u16 *id)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_ID_ATA;
-
-       ahci_exec_ata_cmd(probe_ent, port, cfis,
-                       (u8 *)id, ATA_ID_WORDS * 2, READ_CMD);
-       ata_swap_buf_le16(id, ATA_ID_WORDS);
-}
-
-static void dwc_ahsata_xfer_mode(int dev, u16 *id)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-
-       probe_ent->pio_mask = id[ATA_ID_PIO_MODES];
-       probe_ent->udma_mask = id[ATA_ID_UDMA_MODES];
-       debug("pio %04x, udma %04x\n\r",
-               probe_ent->pio_mask, probe_ent->udma_mask);
-}
-
-static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt,
-                               u8 *buffer, int is_write)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-       u32 block;
-
-       block = start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
-       cfis->device = ATA_LBA;
-
-       cfis->device |= (block >> 24) & 0xf;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-       cfis->sector_count = (u8)(blkcnt & 0xff);
-
-       if (ahci_exec_ata_cmd(probe_ent, port, cfis,
-                       buffer, ATA_SECT_SIZE * blkcnt, is_write) > 0)
-               return blkcnt;
-       else
-               return 0;
-}
-
-void dwc_ahsata_flush_cache(int dev)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_FLUSH;
-
-       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
-}
-
-static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt,
-                               u8 *buffer, int is_write)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-       u64 block;
-
-       block = (u64)start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-
-       cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
-                                : ATA_CMD_READ_EXT;
-
-       cfis->lba_high_exp = (block >> 40) & 0xff;
-       cfis->lba_mid_exp = (block >> 32) & 0xff;
-       cfis->lba_low_exp = (block >> 24) & 0xff;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-       cfis->device = ATA_LBA;
-       cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
-       cfis->sector_count = blkcnt & 0xff;
-
-       if (ahci_exec_ata_cmd(probe_ent, port, cfis, buffer,
-                       ATA_SECT_SIZE * blkcnt, is_write) > 0)
-               return blkcnt;
-       else
-               return 0;
-}
-
-u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt,
-                               u8 *buffer, int is_write)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-       u64 block;
-
-       if (sata_dev_desc[dev].lba48 != 1) {
-               printf("execute FPDMA command on non-LBA48 hard disk\n\r");
-               return -1;
-       }
-
-       block = (u64)start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-
-       cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
-                                : ATA_CMD_FPDMA_READ;
-
-       cfis->lba_high_exp = (block >> 40) & 0xff;
-       cfis->lba_mid_exp = (block >> 32) & 0xff;
-       cfis->lba_low_exp = (block >> 24) & 0xff;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-
-       cfis->device = ATA_LBA;
-       cfis->features_exp = (blkcnt >> 8) & 0xff;
-       cfis->features = blkcnt & 0xff;
-
-       /* Use the latest queue */
-       ahci_exec_ata_cmd(probe_ent, port, cfis,
-                       buffer, ATA_SECT_SIZE * blkcnt, is_write);
-
-       return blkcnt;
-}
-
-void dwc_ahsata_flush_cache_ext(int dev)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
-       struct sata_fis_h2d *cfis = &h2d;
-       u8 port = probe_ent->hard_port_no;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_FLUSH_EXT;
-
-       ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
-}
-
-static void dwc_ahsata_init_wcache(int dev, u16 *id)
-{
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-
-       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
-               probe_ent->flags |= SATA_FLAG_WCACHE;
-       if (ata_id_has_flush(id))
-               probe_ent->flags |= SATA_FLAG_FLUSH;
-       if (ata_id_has_flush_ext(id))
-               probe_ent->flags |= SATA_FLAG_FLUSH_EXT;
-}
-
-u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
-                               const void *buffer, int is_write)
-{
-       u32 start, blks;
-       u8 *addr;
-       int max_blks;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS_LBA48;
-
-       do {
-               if (blks > max_blks) {
-                       if (max_blks != dwc_ahsata_rw_cmd_ext(dev, start,
-                                               max_blks, addr, is_write))
-                               return 0;
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       if (blks != dwc_ahsata_rw_cmd_ext(dev, start,
-                                               blks, addr, is_write))
-                               return 0;
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt,
-                               const void *buffer, int is_write)
-{
-       u32 start, blks;
-       u8 *addr;
-       int max_blks;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS;
-       do {
-               if (blks > max_blks) {
-                       if (max_blks != dwc_ahsata_rw_cmd(dev, start,
-                                               max_blks, addr, is_write))
-                               return 0;
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       if (blks != dwc_ahsata_rw_cmd(dev, start,
-                                               blks, addr, is_write))
-                               return 0;
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-int sata_port_status(int dev, int port)
-{
-       struct sata_port_regs *port_mmio;
-       struct ahci_probe_ent *probe_ent = NULL;
-
-       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1))
-               return -EINVAL;
-
-       if (sata_dev_desc[dev].priv == NULL)
-               return -ENODEV;
-
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio;
-
-       return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       u32 rc;
-
-       if (sata_dev_desc[dev].lba48)
-               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
-                                               buffer, READ_CMD);
-       else
-               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
-                                               buffer, READ_CMD);
-       return rc;
-}
-
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       u32 rc;
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       u32 flags = probe_ent->flags;
-
-       if (sata_dev_desc[dev].lba48) {
-               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
-                                               buffer, WRITE_CMD);
-               if ((flags & SATA_FLAG_WCACHE) &&
-                       (flags & SATA_FLAG_FLUSH_EXT))
-                       dwc_ahsata_flush_cache_ext(dev);
-       } else {
-               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
-                                               buffer, WRITE_CMD);
-               if ((flags & SATA_FLAG_WCACHE) &&
-                       (flags & SATA_FLAG_FLUSH))
-                       dwc_ahsata_flush_cache(dev);
-       }
-       return rc;
-}
-
-int scan_sata(int dev)
-{
-       u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 };
-       u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 };
-       u8 product[ATA_ID_PROD_LEN + 1] = { 0 };
-       u16 *id;
-       u64 n_sectors;
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
-       u8 port = probe_ent->hard_port_no;
-       struct blk_desc *pdev = &(sata_dev_desc[dev]);
-
-       id = (u16 *)memalign(ARCH_DMA_MINALIGN,
-                               roundup(ARCH_DMA_MINALIGN,
-                                       (ATA_ID_WORDS * 2)));
-       if (!id) {
-               printf("id malloc failed\n\r");
-               return -1;
-       }
-
-       /* Identify device to get information */
-       dwc_ahsata_identify(dev, id);
-
-       /* Serial number */
-       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-       memcpy(pdev->product, serial, sizeof(serial));
-
-       /* Firmware version */
-       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
-       memcpy(pdev->revision, firmware, sizeof(firmware));
-
-       /* Product model */
-       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
-       memcpy(pdev->vendor, product, sizeof(product));
-
-       /* Totoal sectors */
-       n_sectors = ata_id_n_sectors(id);
-       pdev->lba = (u32)n_sectors;
-
-       pdev->type = DEV_TYPE_HARDDISK;
-       pdev->blksz = ATA_SECT_SIZE;
-       pdev->lun = 0 ;
-
-       /* Check if support LBA48 */
-       if (ata_id_has_lba48(id)) {
-               pdev->lba48 = 1;
-               debug("Device support LBA48\n\r");
-       }
-
-       /* Get the NCQ queue depth from device */
-       probe_ent->flags &= (~SATA_FLAG_Q_DEP_MASK);
-       probe_ent->flags |= ata_id_queue_depth(id);
-
-       /* Get the xfer mode from device */
-       dwc_ahsata_xfer_mode(dev, id);
-
-       /* Get the write cache status from device */
-       dwc_ahsata_init_wcache(dev, id);
-
-       /* Set the xfer mode to highest speed */
-       ahci_set_feature(dev, port);
-
-       free((void *)id);
-
-       dwc_ahsata_print_info(dev);
-
-       is_ready = 1;
-
-       return 0;
-}
diff --git a/drivers/block/dwc_ahsata.h b/drivers/block/dwc_ahsata.h
deleted file mode 100644 (file)
index caa2e50..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2010 Freescale Semiconductor, Inc.
- * Terry Lv <r65388@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __FSL_SATA_H__
-#define __FSL_SATA_H__
-
-#define DWC_AHSATA_MAX_CMD_SLOTS       32
-
-/* Max host controller numbers */
-#define SATA_HC_MAX_NUM                4
-/* Max command queue depth per host controller */
-#define DWC_AHSATA_HC_MAX_CMD  32
-/* Max port number per host controller */
-#define SATA_HC_MAX_PORT       16
-
-/* Generic Host Register */
-
-/* HBA Capabilities Register */
-#define SATA_HOST_CAP_S64A             0x80000000
-#define SATA_HOST_CAP_SNCQ             0x40000000
-#define SATA_HOST_CAP_SSNTF            0x20000000
-#define SATA_HOST_CAP_SMPS             0x10000000
-#define SATA_HOST_CAP_SSS              0x08000000
-#define SATA_HOST_CAP_SALP             0x04000000
-#define SATA_HOST_CAP_SAL              0x02000000
-#define SATA_HOST_CAP_SCLO             0x01000000
-#define SATA_HOST_CAP_ISS_MASK         0x00f00000
-#define SATA_HOST_CAP_ISS_OFFSET       20
-#define SATA_HOST_CAP_SNZO             0x00080000
-#define SATA_HOST_CAP_SAM              0x00040000
-#define SATA_HOST_CAP_SPM              0x00020000
-#define SATA_HOST_CAP_PMD              0x00008000
-#define SATA_HOST_CAP_SSC              0x00004000
-#define SATA_HOST_CAP_PSC              0x00002000
-#define SATA_HOST_CAP_NCS              0x00001f00
-#define SATA_HOST_CAP_CCCS             0x00000080
-#define SATA_HOST_CAP_EMS              0x00000040
-#define SATA_HOST_CAP_SXS              0x00000020
-#define SATA_HOST_CAP_NP_MASK          0x0000001f
-
-/* Global HBA Control Register */
-#define SATA_HOST_GHC_AE       0x80000000
-#define SATA_HOST_GHC_IE       0x00000002
-#define SATA_HOST_GHC_HR       0x00000001
-
-/* Interrupt Status Register */
-
-/* Ports Implemented Register */
-
-/* AHCI Version Register */
-#define SATA_HOST_VS_MJR_MASK  0xffff0000
-#define SATA_HOST_VS_MJR_OFFSET        16
-#define SATA_HOST_VS_MJR_MNR   0x0000ffff
-
-/* Command Completion Coalescing Control */
-#define SATA_HOST_CCC_CTL_TV_MASK      0xffff0000
-#define SATA_HOST_CCC_CTL_TV_OFFSET            16
-#define SATA_HOST_CCC_CTL_CC_MASK      0x0000ff00
-#define SATA_HOST_CCC_CTL_CC_OFFSET            8
-#define SATA_HOST_CCC_CTL_INT_MASK     0x000000f8
-#define SATA_HOST_CCC_CTL_INT_OFFSET   3
-#define SATA_HOST_CCC_CTL_EN   0x00000001
-
-/* Command Completion Coalescing Ports */
-
-/* HBA Capabilities Extended Register */
-#define SATA_HOST_CAP2_APST            0x00000004
-
-/* BIST Activate FIS Register */
-#define SATA_HOST_BISTAFR_NCP_MASK     0x0000ff00
-#define SATA_HOST_BISTAFR_NCP_OFFSET   8
-#define SATA_HOST_BISTAFR_PD_MASK      0x000000ff
-#define SATA_HOST_BISTAFR_PD_OFFSET            0
-
-/* BIST Control Register */
-#define SATA_HOST_BISTCR_FERLB 0x00100000
-#define SATA_HOST_BISTCR_TXO   0x00040000
-#define SATA_HOST_BISTCR_CNTCLR        0x00020000
-#define SATA_HOST_BISTCR_NEALB 0x00010000
-#define SATA_HOST_BISTCR_LLC_MASK      0x00000700
-#define SATA_HOST_BISTCR_LLC_OFFSET    8
-#define SATA_HOST_BISTCR_ERREN 0x00000040
-#define SATA_HOST_BISTCR_FLIP  0x00000020
-#define SATA_HOST_BISTCR_PV            0x00000010
-#define SATA_HOST_BISTCR_PATTERN_MASK  0x0000000f
-#define SATA_HOST_BISTCR_PATTERN_OFFSET        0
-
-/* BIST FIS Count Register */
-
-/* BIST Status Register */
-#define SATA_HOST_BISTSR_FRAMERR_MASK  0x0000ffff
-#define SATA_HOST_BISTSR_FRAMERR_OFFSET        0
-#define SATA_HOST_BISTSR_BRSTERR_MASK  0x00ff0000
-#define SATA_HOST_BISTSR_BRSTERR_OFFSET        16
-
-/* BIST DWORD Error Count Register */
-
-/* OOB Register*/
-#define SATA_HOST_OOBR_WE              0x80000000
-#define SATA_HOST_OOBR_cwMin_MASK      0x7f000000
-#define SATA_HOST_OOBR_cwMAX_MASK      0x00ff0000
-#define SATA_HOST_OOBR_ciMin_MASK      0x0000ff00
-#define SATA_HOST_OOBR_ciMax_MASK      0x000000ff
-
-/* Timer 1-ms Register */
-
-/* Global Parameter 1 Register */
-#define SATA_HOST_GPARAM1R_ALIGN_M     0x80000000
-#define SATA_HOST_GPARAM1R_RX_BUFFER   0x40000000
-#define SATA_HOST_GPARAM1R_PHY_DATA_MASK       0x30000000
-#define SATA_HOST_GPARAM1R_PHY_RST     0x08000000
-#define SATA_HOST_GPARAM1R_PHY_CTRL_MASK       0x07e00000
-#define SATA_HOST_GPARAM1R_PHY_STAT_MASK       0x001f8000
-#define SATA_HOST_GPARAM1R_LATCH_M     0x00004000
-#define SATA_HOST_GPARAM1R_BIST_M      0x00002000
-#define SATA_HOST_GPARAM1R_PHY_TYPE    0x00001000
-#define SATA_HOST_GPARAM1R_RETURN_ERR  0x00000400
-#define SATA_HOST_GPARAM1R_AHB_ENDIAN_MASK     0x00000300
-#define SATA_HOST_GPARAM1R_S_HADDR     0X00000080
-#define SATA_HOST_GPARAM1R_M_HADDR     0X00000040
-
-/* Global Parameter 2 Register */
-#define SATA_HOST_GPARAM2R_DEV_CP      0x00004000
-#define SATA_HOST_GPARAM2R_DEV_MP      0x00002000
-#define SATA_HOST_GPARAM2R_DEV_ENCODE_M        0x00001000
-#define SATA_HOST_GPARAM2R_RXOOB_CLK_M 0x00000800
-#define SATA_HOST_GPARAM2R_RXOOB_M     0x00000400
-#define SATA_HOST_GPARAM2R_TX_OOB_M    0x00000200
-#define SATA_HOST_GPARAM2R_RXOOB_CLK_MASK      0x000001ff
-
-/* Port Parameter Register */
-#define SATA_HOST_PPARAMR_TX_MEM_M     0x00000200
-#define SATA_HOST_PPARAMR_TX_MEM_S     0x00000100
-#define SATA_HOST_PPARAMR_RX_MEM_M     0x00000080
-#define SATA_HOST_PPARAMR_RX_MEM_S     0x00000040
-#define SATA_HOST_PPARAMR_TXFIFO_DEPTH_MASK    0x00000038
-#define SATA_HOST_PPARAMR_RXFIFO_DEPTH_MASK    0x00000007
-
-/* Test Register */
-#define SATA_HOST_TESTR_PSEL_MASK      0x00070000
-#define SATA_HOST_TESTR_TEST_IF                0x00000001
-
-/* Port Register Descriptions */
-/* Port# Command List Base Address Register */
-#define SATA_PORT_CLB_CLB_MASK         0xfffffc00
-
-/* Port# Command List Base Address Upper 32-Bits Register */
-
-/* Port# FIS Base Address Register */
-#define SATA_PORT_FB_FB_MASK           0xfffffff0
-
-/* Port# FIS Base Address Upper 32-Bits Register */
-
-/* Port# Interrupt Status Register */
-#define SATA_PORT_IS_CPDS              0x80000000
-#define SATA_PORT_IS_TFES              0x40000000
-#define SATA_PORT_IS_HBFS              0x20000000
-#define SATA_PORT_IS_HBDS              0x10000000
-#define SATA_PORT_IS_IFS               0x08000000
-#define SATA_PORT_IS_INFS              0x04000000
-#define SATA_PORT_IS_OFS               0x01000000
-#define SATA_PORT_IS_IPMS              0x00800000
-#define SATA_PORT_IS_PRCS              0x00400000
-#define SATA_PORT_IS_DMPS              0x00000080
-#define SATA_PORT_IS_PCS               0x00000040
-#define SATA_PORT_IS_DPS               0x00000020
-#define SATA_PORT_IS_UFS               0x00000010
-#define SATA_PORT_IS_SDBS              0x00000008
-#define SATA_PORT_IS_DSS               0x00000004
-#define SATA_PORT_IS_PSS               0x00000002
-#define SATA_PORT_IS_DHRS              0x00000001
-
-/* Port# Interrupt Enable Register */
-#define SATA_PORT_IE_CPDE              0x80000000
-#define SATA_PORT_IE_TFEE              0x40000000
-#define SATA_PORT_IE_HBFE              0x20000000
-#define SATA_PORT_IE_HBDE              0x10000000
-#define SATA_PORT_IE_IFE               0x08000000
-#define SATA_PORT_IE_INFE              0x04000000
-#define SATA_PORT_IE_OFE               0x01000000
-#define SATA_PORT_IE_IPME              0x00800000
-#define SATA_PORT_IE_PRCE              0x00400000
-#define SATA_PORT_IE_DMPE              0x00000080
-#define SATA_PORT_IE_PCE               0x00000040
-#define SATA_PORT_IE_DPE               0x00000020
-#define SATA_PORT_IE_UFE               0x00000010
-#define SATA_PORT_IE_SDBE              0x00000008
-#define SATA_PORT_IE_DSE               0x00000004
-#define SATA_PORT_IE_PSE               0x00000002
-#define SATA_PORT_IE_DHRE              0x00000001
-
-/* Port# Command Register */
-#define SATA_PORT_CMD_ICC_MASK         0xf0000000
-#define SATA_PORT_CMD_ASP              0x08000000
-#define SATA_PORT_CMD_ALPE             0x04000000
-#define SATA_PORT_CMD_DLAE             0x02000000
-#define SATA_PORT_CMD_ATAPI            0x01000000
-#define SATA_PORT_CMD_APSTE            0x00800000
-#define SATA_PORT_CMD_ESP              0x00200000
-#define SATA_PORT_CMD_CPD              0x00100000
-#define SATA_PORT_CMD_MPSP             0x00080000
-#define SATA_PORT_CMD_HPCP             0x00040000
-#define SATA_PORT_CMD_PMA              0x00020000
-#define SATA_PORT_CMD_CPS              0x00010000
-#define SATA_PORT_CMD_CR               0x00008000
-#define SATA_PORT_CMD_FR               0x00004000
-#define SATA_PORT_CMD_MPSS             0x00002000
-#define SATA_PORT_CMD_CCS_MASK         0x00001f00
-#define SATA_PORT_CMD_FRE              0x00000010
-#define SATA_PORT_CMD_CLO              0x00000008
-#define SATA_PORT_CMD_POD              0x00000004
-#define SATA_PORT_CMD_SUD              0x00000002
-#define SATA_PORT_CMD_ST               0x00000001
-
-/* Port# Task File Data Register */
-#define SATA_PORT_TFD_ERR_MASK         0x0000ff00
-#define SATA_PORT_TFD_STS_MASK         0x000000ff
-#define SATA_PORT_TFD_STS_ERR          0x00000001
-#define SATA_PORT_TFD_STS_DRQ          0x00000008
-#define SATA_PORT_TFD_STS_BSY          0x00000080
-
-/* Port# Signature Register */
-
-/* Port# Serial ATA Status {SStatus} Register */
-#define SATA_PORT_SSTS_IPM_MASK                0x00000f00
-#define SATA_PORT_SSTS_SPD_MASK                0x000000f0
-#define SATA_PORT_SSTS_DET_MASK                0x0000000f
-
-/* Port# Serial ATA Control {SControl} Register */
-#define SATA_PORT_SCTL_IPM_MASK                0x00000f00
-#define SATA_PORT_SCTL_SPD_MASK                0x000000f0
-#define SATA_PORT_SCTL_DET_MASK                0x0000000f
-
-/* Port# Serial ATA Error {SError} Register */
-#define SATA_PORT_SERR_DIAG_X          0x04000000
-#define SATA_PORT_SERR_DIAG_F          0x02000000
-#define SATA_PORT_SERR_DIAG_T          0x01000000
-#define SATA_PORT_SERR_DIAG_S          0x00800000
-#define SATA_PORT_SERR_DIAG_H          0x00400000
-#define SATA_PORT_SERR_DIAG_C          0x00200000
-#define SATA_PORT_SERR_DIAG_D          0x00100000
-#define SATA_PORT_SERR_DIAG_B          0x00080000
-#define SATA_PORT_SERR_DIAG_W          0x00040000
-#define SATA_PORT_SERR_DIAG_I          0x00020000
-#define SATA_PORT_SERR_DIAG_N          0x00010000
-#define SATA_PORT_SERR_ERR_E           0x00000800
-#define SATA_PORT_SERR_ERR_P           0x00000400
-#define SATA_PORT_SERR_ERR_C           0x00000200
-#define SATA_PORT_SERR_ERR_T           0x00000100
-#define SATA_PORT_SERR_ERR_M           0x00000002
-#define SATA_PORT_SERR_ERR_I           0x00000001
-
-/* Port# Serial ATA Active {SActive} Register */
-
-/* Port# Command Issue Register */
-
-/* Port# Serial ATA Notification Register */
-
-/* Port# DMA Control Register */
-#define SATA_PORT_DMACR_RXABL_MASK     0x0000f000
-#define SATA_PORT_DMACR_TXABL_MASK     0x00000f00
-#define SATA_PORT_DMACR_RXTS_MASK      0x000000f0
-#define SATA_PORT_DMACR_TXTS_MASK      0x0000000f
-
-/* Port# PHY Control Register */
-
-/* Port# PHY Status Register */
-
-#define SATA_HC_CMD_HDR_ENTRY_SIZE     sizeof(struct cmd_hdr_entry)
-
-/* DW0
-*/
-#define CMD_HDR_DI_CFL_MASK    0x0000001f
-#define CMD_HDR_DI_CFL_OFFSET  0
-#define CMD_HDR_DI_A                   0x00000020
-#define CMD_HDR_DI_W                   0x00000040
-#define CMD_HDR_DI_P                   0x00000080
-#define CMD_HDR_DI_R                   0x00000100
-#define CMD_HDR_DI_B                   0x00000200
-#define CMD_HDR_DI_C                   0x00000400
-#define CMD_HDR_DI_PMP_MASK    0x0000f000
-#define CMD_HDR_DI_PMP_OFFSET  12
-#define CMD_HDR_DI_PRDTL               0xffff0000
-#define CMD_HDR_DI_PRDTL_OFFSET        16
-
-/* prde_fis_len
-*/
-#define CMD_HDR_PRD_ENTRY_SHIFT        16
-#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
-#define CMD_HDR_FIS_LEN_SHIFT  2
-
-/* attribute
-*/
-#define CMD_HDR_ATTR_RES       0x00000800 /* Reserved bit, should be 1 */
-#define CMD_HDR_ATTR_VBIST     0x00000400 /* Vendor BIST */
-/* Snoop enable for all descriptor */
-#define CMD_HDR_ATTR_SNOOP     0x00000200
-#define CMD_HDR_ATTR_FPDMA     0x00000100 /* FPDMA queued command */
-#define CMD_HDR_ATTR_RESET     0x00000080 /* Reset - a SRST or device reset */
-/* BIST - require the host to enter BIST mode */
-#define CMD_HDR_ATTR_BIST      0x00000040
-#define CMD_HDR_ATTR_ATAPI     0x00000020 /* ATAPI command */
-#define CMD_HDR_ATTR_TAG       0x0000001f /* TAG mask */
-
-#define FLAGS_DMA      0x00000000
-#define FLAGS_FPDMA    0x00000001
-
-#define SATA_FLAG_Q_DEP_MASK   0x0000000f
-#define SATA_FLAG_WCACHE       0x00000100
-#define SATA_FLAG_FLUSH                0x00000200
-#define SATA_FLAG_FLUSH_EXT    0x00000400
-
-#define READ_CMD       0
-#define WRITE_CMD      1
-
-#endif /* __FSL_SATA_H__ */
diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c
deleted file mode 100644 (file)
index 31f7fab..0000000
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright (C) 2008,2010 Freescale Semiconductor, Inc.
- *             Dave Liu <daveliu@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <command.h>
-#include <console.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/fsl_serdes.h>
-#include <malloc.h>
-#include <libata.h>
-#include <fis.h>
-#include <sata.h>
-#include "fsl_sata.h"
-
-#ifndef CONFIG_SYS_SATA1_FLAGS
-       #define CONFIG_SYS_SATA1_FLAGS  FLAGS_DMA
-#endif
-#ifndef CONFIG_SYS_SATA2_FLAGS
-       #define CONFIG_SYS_SATA2_FLAGS  FLAGS_DMA
-#endif
-
-static struct fsl_sata_info fsl_sata_info[] = {
-#ifdef CONFIG_SATA1
-       {CONFIG_SYS_SATA1, CONFIG_SYS_SATA1_FLAGS},
-#else
-       {0, 0},
-#endif
-#ifdef CONFIG_SATA2
-       {CONFIG_SYS_SATA2, CONFIG_SYS_SATA2_FLAGS},
-#else
-       {0, 0},
-#endif
-};
-
-static inline void sdelay(unsigned long sec)
-{
-       unsigned long i;
-       for (i = 0; i < sec; i++)
-               mdelay(1000);
-}
-
-static void fsl_sata_dump_sfis(struct sata_fis_d2h *s)
-{
-       printf("Status FIS dump:\n\r");
-       printf("fis_type:               %02x\n\r", s->fis_type);
-       printf("pm_port_i:              %02x\n\r", s->pm_port_i);
-       printf("status:                 %02x\n\r", s->status);
-       printf("error:                  %02x\n\r", s->error);
-       printf("lba_low:                %02x\n\r", s->lba_low);
-       printf("lba_mid:                %02x\n\r", s->lba_mid);
-       printf("lba_high:               %02x\n\r", s->lba_high);
-       printf("device:                 %02x\n\r", s->device);
-       printf("lba_low_exp:            %02x\n\r", s->lba_low_exp);
-       printf("lba_mid_exp:            %02x\n\r", s->lba_mid_exp);
-       printf("lba_high_exp:           %02x\n\r", s->lba_high_exp);
-       printf("res1:                   %02x\n\r", s->res1);
-       printf("sector_count:           %02x\n\r", s->sector_count);
-       printf("sector_count_exp:       %02x\n\r", s->sector_count_exp);
-}
-
-static int ata_wait_register(unsigned __iomem *addr, u32 mask,
-                        u32 val, u32 timeout_msec)
-{
-       int i;
-       u32 temp;
-
-       for (i = 0; (((temp = in_le32(addr)) & mask) != val)
-                        && i < timeout_msec; i++)
-               mdelay(1);
-       return (i < timeout_msec) ? 0 : -1;
-}
-
-int init_sata(int dev)
-{
-       u32 length, align;
-       cmd_hdr_tbl_t *cmd_hdr;
-       u32 cda;
-       u32 val32;
-       fsl_sata_reg_t __iomem *reg;
-       u32 sig;
-       int i;
-       fsl_sata_t *sata;
-
-       if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
-               printf("the sata index %d is out of ranges\n\r", dev);
-               return -1;
-       }
-
-#ifdef CONFIG_MPC85xx
-       if ((dev == 0) && (!is_serdes_configured(SATA1))) {
-               printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
-               return -1;
-       }
-       if ((dev == 1) && (!is_serdes_configured(SATA2))) {
-               printf("SATA%d [dev = %d] is not enabled\n", dev+1, dev);
-               return -1;
-       }
-#endif
-
-       /* Allocate SATA device driver struct */
-       sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t));
-       if (!sata) {
-               printf("alloc the sata device struct failed\n\r");
-               return -1;
-       }
-       /* Zero all of the device driver struct */
-       memset((void *)sata, 0, sizeof(fsl_sata_t));
-
-       /* Save the private struct to block device struct */
-       sata_dev_desc[dev].priv = (void *)sata;
-
-       snprintf(sata->name, 12, "SATA%d", dev);
-
-       /* Set the controller register base address to device struct */
-       reg = (fsl_sata_reg_t *)(fsl_sata_info[dev].sata_reg_base);
-       sata->reg_base = reg;
-
-       /* Allocate the command header table, 4 bytes aligned */
-       length = sizeof(struct cmd_hdr_tbl);
-       align = SATA_HC_CMD_HDR_TBL_ALIGN;
-       sata->cmd_hdr_tbl_offset = (void *)malloc(length + align);
-       if (!sata->cmd_hdr_tbl_offset) {
-               printf("alloc the command header failed\n\r");
-               return -1;
-       }
-
-       cmd_hdr = (cmd_hdr_tbl_t *)(((u32)sata->cmd_hdr_tbl_offset + align)
-                                               & ~(align - 1));
-       sata->cmd_hdr = cmd_hdr;
-
-       /* Zero all of the command header table */
-       memset((void *)sata->cmd_hdr_tbl_offset, 0, length + align);
-
-       /* Allocate command descriptor for all command */
-       length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD;
-       align = SATA_HC_CMD_DESC_ALIGN;
-       sata->cmd_desc_offset = (void *)malloc(length + align);
-       if (!sata->cmd_desc_offset) {
-               printf("alloc the command descriptor failed\n\r");
-               return -1;
-       }
-       sata->cmd_desc = (cmd_desc_t *)(((u32)sata->cmd_desc_offset + align)
-                                               & ~(align - 1));
-       /* Zero all of command descriptor */
-       memset((void *)sata->cmd_desc_offset, 0, length + align);
-
-       /* Link the command descriptor to command header */
-       for (i = 0; i < SATA_HC_MAX_CMD; i++) {
-               cda = ((u32)sata->cmd_desc + SATA_HC_CMD_DESC_SIZE * i)
-                                        & ~(CMD_HDR_CDA_ALIGN - 1);
-               cmd_hdr->cmd_slot[i].cda = cpu_to_le32(cda);
-       }
-
-       /* To have safe state, force the controller offline */
-       val32 = in_le32(&reg->hcontrol);
-       val32 &= ~HCONTROL_ONOFF;
-       val32 |= HCONTROL_FORCE_OFFLINE;
-       out_le32(&reg->hcontrol, val32);
-
-       /* Wait the controller offline */
-       ata_wait_register(&reg->hstatus, HSTATUS_ONOFF, 0, 1000);
-
-       /* Set the command header base address to CHBA register to tell DMA */
-       out_le32(&reg->chba, (u32)cmd_hdr & ~0x3);
-
-       /* Snoop for the command header */
-       val32 = in_le32(&reg->hcontrol);
-       val32 |= HCONTROL_HDR_SNOOP;
-       out_le32(&reg->hcontrol, val32);
-
-       /* Disable all of interrupts */
-       val32 = in_le32(&reg->hcontrol);
-       val32 &= ~HCONTROL_INT_EN_ALL;
-       out_le32(&reg->hcontrol, val32);
-
-       /* Clear all of interrupts */
-       val32 = in_le32(&reg->hstatus);
-       out_le32(&reg->hstatus, val32);
-
-       /* Set the ICC, no interrupt coalescing */
-       out_le32(&reg->icc, 0x01000000);
-
-       /* No PM attatched, the SATA device direct connect */
-       out_le32(&reg->cqpmp, 0);
-
-       /* Clear SError register */
-       val32 = in_le32(&reg->serror);
-       out_le32(&reg->serror, val32);
-
-       /* Clear CER register */
-       val32 = in_le32(&reg->cer);
-       out_le32(&reg->cer, val32);
-
-       /* Clear DER register */
-       val32 = in_le32(&reg->der);
-       out_le32(&reg->der, val32);
-
-       /* No device detection or initialization action requested */
-       out_le32(&reg->scontrol, 0x00000300);
-
-       /* Configure the transport layer, default value */
-       out_le32(&reg->transcfg, 0x08000016);
-
-       /* Configure the link layer, default value */
-       out_le32(&reg->linkcfg, 0x0000ff34);
-
-       /* Bring the controller online */
-       val32 = in_le32(&reg->hcontrol);
-       val32 |= HCONTROL_ONOFF;
-       out_le32(&reg->hcontrol, val32);
-
-       mdelay(100);
-
-       /* print sata device name */
-       if (!dev)
-               printf("%s ", sata->name);
-       else
-               printf("       %s ", sata->name);
-
-       /* Wait PHY RDY signal changed for 500ms */
-       ata_wait_register(&reg->hstatus, HSTATUS_PHY_RDY,
-                         HSTATUS_PHY_RDY, 500);
-
-       /* Check PHYRDY */
-       val32 = in_le32(&reg->hstatus);
-       if (val32 & HSTATUS_PHY_RDY) {
-               sata->link = 1;
-       } else {
-               sata->link = 0;
-               printf("(No RDY)\n\r");
-               return -1;
-       }
-
-       /* Wait for signature updated, which is 1st D2H */
-       ata_wait_register(&reg->hstatus, HSTATUS_SIGNATURE,
-                         HSTATUS_SIGNATURE, 10000);
-
-       if (val32 & HSTATUS_SIGNATURE) {
-               sig = in_le32(&reg->sig);
-               debug("Signature updated, the sig =%08x\n\r", sig);
-               sata->ata_device_type = ata_dev_classify(sig);
-       }
-
-       /* Check the speed */
-       val32 = in_le32(&reg->sstatus);
-       if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN1)
-               printf("(1.5 Gbps)\n\r");
-       else if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN2)
-               printf("(3 Gbps)\n\r");
-
-       return 0;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-static void fsl_sata_dump_regs(fsl_sata_reg_t __iomem *reg)
-{
-       printf("\n\rSATA:           %08x\n\r", (u32)reg);
-       printf("CQR:            %08x\n\r", in_le32(&reg->cqr));
-       printf("CAR:            %08x\n\r", in_le32(&reg->car));
-       printf("CCR:            %08x\n\r", in_le32(&reg->ccr));
-       printf("CER:            %08x\n\r", in_le32(&reg->cer));
-       printf("CQR:            %08x\n\r", in_le32(&reg->cqr));
-       printf("DER:            %08x\n\r", in_le32(&reg->der));
-       printf("CHBA:           %08x\n\r", in_le32(&reg->chba));
-       printf("HStatus:        %08x\n\r", in_le32(&reg->hstatus));
-       printf("HControl:       %08x\n\r", in_le32(&reg->hcontrol));
-       printf("CQPMP:          %08x\n\r", in_le32(&reg->cqpmp));
-       printf("SIG:            %08x\n\r", in_le32(&reg->sig));
-       printf("ICC:            %08x\n\r", in_le32(&reg->icc));
-       printf("SStatus:        %08x\n\r", in_le32(&reg->sstatus));
-       printf("SError:         %08x\n\r", in_le32(&reg->serror));
-       printf("SControl:       %08x\n\r", in_le32(&reg->scontrol));
-       printf("SNotification:  %08x\n\r", in_le32(&reg->snotification));
-       printf("TransCfg:       %08x\n\r", in_le32(&reg->transcfg));
-       printf("TransStatus:    %08x\n\r", in_le32(&reg->transstatus));
-       printf("LinkCfg:        %08x\n\r", in_le32(&reg->linkcfg));
-       printf("LinkCfg1:       %08x\n\r", in_le32(&reg->linkcfg1));
-       printf("LinkCfg2:       %08x\n\r", in_le32(&reg->linkcfg2));
-       printf("LinkStatus:     %08x\n\r", in_le32(&reg->linkstatus));
-       printf("LinkStatus1:    %08x\n\r", in_le32(&reg->linkstatus1));
-       printf("PhyCtrlCfg:     %08x\n\r", in_le32(&reg->phyctrlcfg));
-       printf("SYSPR:          %08x\n\r", in_be32(&reg->syspr));
-}
-
-static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
-                               int is_ncq, int tag, u8 *buffer, u32 len)
-{
-       cmd_hdr_entry_t *cmd_hdr;
-       cmd_desc_t *cmd_desc;
-       sata_fis_h2d_t *h2d;
-       prd_entry_t *prde;
-       u32 ext_c_ddc;
-       u32 prde_count;
-       u32 val32;
-       u32 ttl;
-       fsl_sata_reg_t __iomem *reg = sata->reg_base;
-       int i;
-
-       /* Check xfer length */
-       if (len > SATA_HC_MAX_XFER_LEN) {
-               printf("max transfer length is 64MB\n\r");
-               return 0;
-       }
-
-       /* Setup the command descriptor */
-       cmd_desc = sata->cmd_desc + tag;
-
-       /* Get the pointer cfis of command descriptor */
-       h2d = (sata_fis_h2d_t *)cmd_desc->cfis;
-
-       /* Zero the cfis of command descriptor */
-       memset((void *)h2d, 0, SATA_HC_CMD_DESC_CFIS_SIZE);
-
-       /* Copy the cfis from user to command descriptor */
-       h2d->fis_type = cfis->fis_type;
-       h2d->pm_port_c = cfis->pm_port_c;
-       h2d->command = cfis->command;
-
-       h2d->features = cfis->features;
-       h2d->features_exp = cfis->features_exp;
-
-       h2d->lba_low = cfis->lba_low;
-       h2d->lba_mid = cfis->lba_mid;
-       h2d->lba_high = cfis->lba_high;
-       h2d->lba_low_exp = cfis->lba_low_exp;
-       h2d->lba_mid_exp = cfis->lba_mid_exp;
-       h2d->lba_high_exp = cfis->lba_high_exp;
-
-       if (!is_ncq) {
-               h2d->sector_count = cfis->sector_count;
-               h2d->sector_count_exp = cfis->sector_count_exp;
-       } else { /* NCQ */
-               h2d->sector_count = (u8)(tag << 3);
-       }
-
-       h2d->device = cfis->device;
-       h2d->control = cfis->control;
-
-       /* Setup the PRD table */
-       prde = (prd_entry_t *)cmd_desc->prdt;
-       memset((void *)prde, 0, sizeof(struct prdt));
-
-       prde_count = 0;
-       ttl = len;
-       for (i = 0; i < SATA_HC_MAX_PRD_DIRECT; i++) {
-               if (!len)
-                       break;
-               prde->dba = cpu_to_le32((u32)buffer & ~0x3);
-               debug("dba = %08x\n\r", (u32)buffer);
-
-               if (len < PRD_ENTRY_MAX_XFER_SZ) {
-                       ext_c_ddc = PRD_ENTRY_DATA_SNOOP | len;
-                       debug("ext_c_ddc1 = %08x, len = %08x\n\r", ext_c_ddc, len);
-                       prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
-                       prde_count++;
-                       prde++;
-                       break;
-               } else {
-                       ext_c_ddc = PRD_ENTRY_DATA_SNOOP; /* 4M bytes */
-                       debug("ext_c_ddc2 = %08x, len = %08x\n\r", ext_c_ddc, len);
-                       prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
-                       buffer += PRD_ENTRY_MAX_XFER_SZ;
-                       len -= PRD_ENTRY_MAX_XFER_SZ;
-                       prde_count++;
-                       prde++;
-               }
-       }
-
-       /* Setup the command slot of cmd hdr */
-       cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
-
-       cmd_hdr->cda = cpu_to_le32((u32)cmd_desc & ~0x3);
-
-       val32 = prde_count << CMD_HDR_PRD_ENTRY_SHIFT;
-       val32 |= sizeof(sata_fis_h2d_t);
-       cmd_hdr->prde_fis_len = cpu_to_le32(val32);
-
-       cmd_hdr->ttl = cpu_to_le32(ttl);
-
-       if (!is_ncq) {
-               val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP;
-       } else {
-               val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP | CMD_HDR_ATTR_FPDMA;
-       }
-
-       tag &= CMD_HDR_ATTR_TAG;
-       val32 |= tag;
-
-       debug("attribute = %08x\n\r", val32);
-       cmd_hdr->attribute = cpu_to_le32(val32);
-
-       /* Make sure cmd desc and cmd slot valid before command issue */
-       sync();
-
-       /* PMP*/
-       val32 = (u32)(h2d->pm_port_c & 0x0f);
-       out_le32(&reg->cqpmp, val32);
-
-       /* Wait no active */
-       if (ata_wait_register(&reg->car, (1 << tag), 0, 10000))
-               printf("Wait no active time out\n\r");
-
-       /* Issue command */
-       if (!(in_le32(&reg->cqr) & (1 << tag))) {
-               val32 = 1 << tag;
-               out_le32(&reg->cqr, val32);
-       }
-
-       /* Wait command completed for 10s */
-       if (ata_wait_register(&reg->ccr, (1 << tag), (1 << tag), 10000)) {
-               if (!is_ncq)
-                       printf("Non-NCQ command time out\n\r");
-               else
-                       printf("NCQ command time out\n\r");
-       }
-
-       val32 = in_le32(&reg->cer);
-
-       if (val32) {
-               u32 der;
-               fsl_sata_dump_sfis((struct sata_fis_d2h *)cmd_desc->sfis);
-               printf("CE at device\n\r");
-               fsl_sata_dump_regs(reg);
-               der = in_le32(&reg->der);
-               out_le32(&reg->cer, val32);
-               out_le32(&reg->der, der);
-       }
-
-       /* Clear complete flags */
-       val32 = in_le32(&reg->ccr);
-       out_le32(&reg->ccr, val32);
-
-       return len;
-}
-
-static int fsl_ata_exec_reset_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
-                                int tag, u8 *buffer, u32 len)
-{
-       return 0;
-}
-
-static int fsl_sata_exec_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
-                enum cmd_type command_type, int tag, u8 *buffer, u32 len)
-{
-       int rc;
-
-       if (tag > SATA_HC_MAX_CMD || tag < 0) {
-               printf("tag is out of range, tag=%d\n\r", tag);
-               return -1;
-       }
-
-       switch (command_type) {
-       case CMD_ATA:
-               rc = fsl_ata_exec_ata_cmd(sata, cfis, 0, tag, buffer, len);
-               return rc;
-       case CMD_RESET:
-               rc = fsl_ata_exec_reset_cmd(sata, cfis, tag, buffer, len);
-               return rc;
-       case CMD_NCQ:
-               rc = fsl_ata_exec_ata_cmd(sata, cfis, 1, tag, buffer, len);
-               return rc;
-       case CMD_ATAPI:
-       case CMD_VENDOR_BIST:
-       case CMD_BIST:
-               printf("not support now\n\r");
-               return -1;
-       default:
-               break;
-       }
-
-       return -1;
-}
-
-static void fsl_sata_identify(int dev, u16 *id)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_ID_ATA;
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2);
-       ata_swap_buf_le16(id, ATA_ID_WORDS);
-}
-
-static void fsl_sata_xfer_mode(int dev, u16 *id)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-
-       sata->pio = id[ATA_ID_PIO_MODES];
-       sata->mwdma = id[ATA_ID_MWDMA_MODES];
-       sata->udma = id[ATA_ID_UDMA_MODES];
-       debug("pio %04x, mwdma %04x, udma %04x\n\r", sata->pio, sata->mwdma, sata->udma);
-}
-
-static void fsl_sata_set_features(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-       u8 udma_cap;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_SET_FEATURES;
-       cfis->features = SETFEATURES_XFER;
-
-       /* First check the device capablity */
-       udma_cap = (u8)(sata->udma & 0xff);
-       debug("udma_cap %02x\n\r", udma_cap);
-
-       if (udma_cap == ATA_UDMA6)
-               cfis->sector_count = XFER_UDMA_6;
-       if (udma_cap == ATA_UDMA5)
-               cfis->sector_count = XFER_UDMA_5;
-       if (udma_cap == ATA_UDMA4)
-               cfis->sector_count = XFER_UDMA_4;
-       if (udma_cap == ATA_UDMA3)
-               cfis->sector_count = XFER_UDMA_3;
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
-}
-
-static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-       u32 block;
-
-       block = start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
-       cfis->device = ATA_LBA;
-
-       cfis->device |= (block >> 24) & 0xf;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-       cfis->sector_count = (u8)(blkcnt & 0xff);
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
-       return blkcnt;
-}
-
-static void fsl_sata_flush_cache(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_FLUSH;
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
-}
-
-static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-       u64 block;
-
-       block = (u64)start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-
-       cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
-                                : ATA_CMD_READ_EXT;
-
-       cfis->lba_high_exp = (block >> 40) & 0xff;
-       cfis->lba_mid_exp = (block >> 32) & 0xff;
-       cfis->lba_low_exp = (block >> 24) & 0xff;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-       cfis->device = ATA_LBA;
-       cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
-       cfis->sector_count = blkcnt & 0xff;
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
-       return blkcnt;
-}
-
-static u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer,
-                              int is_write)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-       int ncq_channel;
-       u64 block;
-
-       if (sata->lba48 != 1) {
-               printf("execute FPDMA command on non-LBA48 hard disk\n\r");
-               return -1;
-       }
-
-       block = (u64)start;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-
-       cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
-                                : ATA_CMD_FPDMA_READ;
-
-       cfis->lba_high_exp = (block >> 40) & 0xff;
-       cfis->lba_mid_exp = (block >> 32) & 0xff;
-       cfis->lba_low_exp = (block >> 24) & 0xff;
-       cfis->lba_high = (block >> 16) & 0xff;
-       cfis->lba_mid = (block >> 8) & 0xff;
-       cfis->lba_low = block & 0xff;
-
-       cfis->device = ATA_LBA;
-       cfis->features_exp = (blkcnt >> 8) & 0xff;
-       cfis->features = blkcnt & 0xff;
-
-       if (sata->queue_depth >= SATA_HC_MAX_CMD)
-               ncq_channel = SATA_HC_MAX_CMD - 1;
-       else
-               ncq_channel = sata->queue_depth - 1;
-
-       /* Use the latest queue */
-       fsl_sata_exec_cmd(sata, cfis, CMD_NCQ, ncq_channel, buffer, ATA_SECT_SIZE * blkcnt);
-       return blkcnt;
-}
-
-static void fsl_sata_flush_cache_ext(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       struct sata_fis_h2d h2d, *cfis = &h2d;
-
-       memset(cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis->pm_port_c = 0x80; /* is command */
-       cfis->command = ATA_CMD_FLUSH_EXT;
-
-       fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
-}
-
-static void fsl_sata_init_wcache(int dev, u16 *id)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-
-       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
-               sata->wcache = 1;
-       if (ata_id_has_flush(id))
-               sata->flush = 1;
-       if (ata_id_has_flush_ext(id))
-               sata->flush_ext = 1;
-}
-
-static int fsl_sata_get_wcache(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       return sata->wcache;
-}
-
-static int fsl_sata_get_flush(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       return sata->flush;
-}
-
-static int fsl_sata_get_flush_ext(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       return sata->flush_ext;
-}
-
-static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
-               const void *buffer, int is_write)
-{
-       u32 start, blks;
-       u8 *addr;
-       int max_blks;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS_LBA48;
-       do {
-               if (blks > max_blks) {
-                       if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
-                               fsl_sata_rw_cmd_ext(dev, start, max_blks, addr, is_write);
-                       else
-                               fsl_sata_rw_ncq_cmd(dev, start, max_blks, addr, is_write);
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
-                               fsl_sata_rw_cmd_ext(dev, start, blks, addr, is_write);
-                       else
-                               fsl_sata_rw_ncq_cmd(dev, start, blks, addr, is_write);
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-static u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt,
-                                 const void *buffer, int is_write)
-{
-       u32 start, blks;
-       u8 *addr;
-       int max_blks;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS;
-       do {
-               if (blks > max_blks) {
-                       fsl_sata_rw_cmd(dev, start, max_blks, addr, is_write);
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       fsl_sata_rw_cmd(dev, start, blks, addr, is_write);
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       u32 rc;
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-
-       if (sata->lba48)
-               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
-       else
-               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
-       return rc;
-}
-
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       u32 rc;
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-
-       if (sata->lba48) {
-               rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
-               if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush_ext(dev))
-                       fsl_sata_flush_cache_ext(dev);
-       } else {
-               rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD);
-               if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush(dev))
-                       fsl_sata_flush_cache(dev);
-       }
-       return rc;
-}
-
-int scan_sata(int dev)
-{
-       fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
-       unsigned char serial[ATA_ID_SERNO_LEN + 1];
-       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
-       unsigned char product[ATA_ID_PROD_LEN + 1];
-       u16 *id;
-       u64 n_sectors;
-
-       /* if no detected link */
-       if (!sata->link)
-               return -1;
-
-       id = (u16 *)malloc(ATA_ID_WORDS * 2);
-       if (!id) {
-               printf("id malloc failed\n\r");
-               return -1;
-       }
-
-       /* Identify device to get information */
-       fsl_sata_identify(dev, id);
-
-       /* Serial number */
-       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-       memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
-
-       /* Firmware version */
-       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
-       memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
-
-       /* Product model */
-       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
-       memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
-
-       /* Totoal sectors */
-       n_sectors = ata_id_n_sectors(id);
-       sata_dev_desc[dev].lba = (u32)n_sectors;
-
-#ifdef CONFIG_LBA48
-       /* Check if support LBA48 */
-       if (ata_id_has_lba48(id)) {
-               sata->lba48 = 1;
-               debug("Device support LBA48\n\r");
-       } else
-               debug("Device supports LBA28\n\r");
-#endif
-
-       /* Get the NCQ queue depth from device */
-       sata->queue_depth = ata_id_queue_depth(id);
-
-       /* Get the xfer mode from device */
-       fsl_sata_xfer_mode(dev, id);
-
-       /* Get the write cache status from device */
-       fsl_sata_init_wcache(dev, id);
-
-       /* Set the xfer mode to highest speed */
-       fsl_sata_set_features(dev);
-#ifdef DEBUG
-       fsl_sata_identify(dev, id);
-       ata_dump_id(id);
-#endif
-       free((void *)id);
-       return 0;
-}
diff --git a/drivers/block/fsl_sata.h b/drivers/block/fsl_sata.h
deleted file mode 100644 (file)
index 18d679e..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Freescale Semiconductor, Inc.
- *             Dave Liu <daveliu@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __FSL_SATA_H__
-#define __FSL_SATA_H__
-
-#define SATA_HC_MAX_NUM                4 /* Max host controller numbers */
-#define SATA_HC_MAX_CMD                16 /* Max command queue depth per host controller */
-#define SATA_HC_MAX_PORT       16 /* Max port number per host controller */
-
-/*
-* SATA Host Controller Registers
-*/
-typedef struct fsl_sata_reg {
-       /* SATA command registers */
-       u32 cqr;                /* Command queue register */
-       u8 res1[0x4];
-       u32 car;                /* Command active register */
-       u8 res2[0x4];
-       u32 ccr;                /* Command completed register */
-       u8 res3[0x4];
-       u32 cer;                /* Command error register */
-       u8 res4[0x4];
-       u32 der;                /* Device error register */
-       u32 chba;               /* Command header base address */
-       u32 hstatus;            /* Host status register */
-       u32 hcontrol;           /* Host control register */
-       u32 cqpmp;              /* Port number queue register */
-       u32 sig;                /* Signature register */
-       u32 icc;                /* Interrupt coalescing control register */
-       u8 res5[0xc4];
-
-       /* SATA supperset registers */
-       u32 sstatus;            /* SATA interface status register */
-       u32 serror;             /* SATA interface error register */
-       u32 scontrol;           /* SATA interface control register */
-       u32 snotification;      /* SATA interface notification register */
-       u8 res6[0x30];
-
-       /* SATA control status registers */
-       u32 transcfg;           /* Transport layer configuration */
-       u32 transstatus;        /* Transport layer status */
-       u32 linkcfg;            /* Link layer configuration */
-       u32 linkcfg1;           /* Link layer configuration1 */
-       u32 linkcfg2;           /* Link layer configuration2 */
-       u32 linkstatus;         /* Link layer status */
-       u32 linkstatus1;        /* Link layer status1 */
-       u32 phyctrlcfg;         /* PHY control configuration */
-       u8 res7[0x2b0];
-
-       /* SATA system control registers */
-       u32 syspr;              /* System priority register - big endian */
-       u8 res8[0xbec];
-} __attribute__ ((packed)) fsl_sata_reg_t;
-
-/* HStatus register
-*/
-#define HSTATUS_ONOFF                  0x80000000 /* Online/offline status */
-#define HSTATUS_FORCE_OFFLINE          0x40000000 /* In process going offline */
-#define HSTATUS_BIST_ERR               0x20000000
-
-/* Fatal error */
-#define HSTATUS_MASTER_ERR             0x00004000
-#define HSTATUS_DATA_UNDERRUN          0x00002000
-#define HSTATUS_DATA_OVERRUN           0x00001000
-#define HSTATUS_CRC_ERR_TX             0x00000800
-#define HSTATUS_CRC_ERR_RX             0x00000400
-#define HSTATUS_FIFO_OVERFLOW_TX       0x00000200
-#define HSTATUS_FIFO_OVERFLOW_RX       0x00000100
-#define HSTATUS_FATAL_ERR_ALL          (HSTATUS_MASTER_ERR | \
-                                       HSTATUS_DATA_UNDERRUN | \
-                                       HSTATUS_DATA_OVERRUN | \
-                                       HSTATUS_CRC_ERR_TX | \
-                                       HSTATUS_CRC_ERR_RX | \
-                                       HSTATUS_FIFO_OVERFLOW_TX | \
-                                       HSTATUS_FIFO_OVERFLOW_RX)
-/* Interrupt status */
-#define HSTATUS_FATAL_ERR              0x00000020
-#define HSTATUS_PHY_RDY                        0x00000010
-#define HSTATUS_SIGNATURE              0x00000008
-#define HSTATUS_SNOTIFY                        0x00000004
-#define HSTATUS_DEVICE_ERR             0x00000002
-#define HSTATUS_CMD_COMPLETE           0x00000001
-
-/* HControl register
-*/
-#define HCONTROL_ONOFF                 0x80000000 /* Online or offline request */
-#define HCONTROL_FORCE_OFFLINE         0x40000000 /* Force offline request */
-#define HCONTROL_ENTERPRISE_EN         0x10000000 /* Enterprise mode enabled */
-#define HCONTROL_HDR_SNOOP             0x00000400 /* Command header snoop */
-#define HCONTROL_PMP_ATTACHED          0x00000200 /* Port multiplier attached */
-
-/* Interrupt enable */
-#define HCONTROL_FATAL_ERR             0x00000020
-#define HCONTROL_PHY_RDY               0x00000010
-#define HCONTROL_SIGNATURE             0x00000008
-#define HCONTROL_SNOTIFY               0x00000004
-#define HCONTROL_DEVICE_ERR            0x00000002
-#define HCONTROL_CMD_COMPLETE          0x00000001
-
-#define HCONTROL_INT_EN_ALL            (HCONTROL_FATAL_ERR | \
-                                       HCONTROL_PHY_RDY | \
-                                       HCONTROL_SIGNATURE | \
-                                       HCONTROL_SNOTIFY | \
-                                       HCONTROL_DEVICE_ERR | \
-                                       HCONTROL_CMD_COMPLETE)
-
-/* SStatus register
-*/
-#define SSTATUS_IPM_MASK               0x00000780
-#define SSTATUS_IPM_NOPRESENT          0x00000000
-#define SSTATUS_IPM_ACTIVE             0x00000080
-#define SSTATUS_IPM_PATIAL             0x00000100
-#define SSTATUS_IPM_SLUMBER            0x00000300
-
-#define SSTATUS_SPD_MASK               0x000000f0
-#define SSTATUS_SPD_GEN1               0x00000010
-#define SSTATUS_SPD_GEN2               0x00000020
-
-#define SSTATUS_DET_MASK               0x0000000f
-#define SSTATUS_DET_NODEVICE           0x00000000
-#define SSTATUS_DET_DISCONNECT         0x00000001
-#define SSTATUS_DET_CONNECT            0x00000003
-#define SSTATUS_DET_PHY_OFFLINE                0x00000004
-
-/* SControl register
-*/
-#define SCONTROL_SPM_MASK              0x0000f000
-#define SCONTROL_SPM_GO_PARTIAL                0x00001000
-#define SCONTROL_SPM_GO_SLUMBER                0x00002000
-#define SCONTROL_SPM_GO_ACTIVE         0x00004000
-
-#define SCONTROL_IPM_MASK              0x00000f00
-#define SCONTROL_IPM_NO_RESTRICT       0x00000000
-#define SCONTROL_IPM_PARTIAL           0x00000100
-#define SCONTROL_IPM_SLUMBER           0x00000200
-#define SCONTROL_IPM_PART_SLUM         0x00000300
-
-#define SCONTROL_SPD_MASK              0x000000f0
-#define SCONTROL_SPD_NO_RESTRICT       0x00000000
-#define SCONTROL_SPD_GEN1              0x00000010
-#define SCONTROL_SPD_GEN2              0x00000020
-
-#define SCONTROL_DET_MASK              0x0000000f
-#define SCONTROL_DET_HRESET            0x00000001
-#define SCONTROL_DET_DISABLE           0x00000004
-
-/* TransCfg register
-*/
-#define TRANSCFG_DFIS_SIZE_SHIFT       16
-#define TRANSCFG_RX_WATER_MARK_MASK    0x0000001f
-
-/* PhyCtrlCfg register
-*/
-#define PHYCTRLCFG_FPRFTI_MASK         0x00000018
-#define PHYCTRLCFG_LOOPBACK_MASK       0x0000000e
-
-/*
-* Command Header Entry
-*/
-typedef struct cmd_hdr_entry {
-       __le32 cda;             /* Command Descriptor Address,
-                                  4 bytes aligned */
-       __le32 prde_fis_len;    /* Number of PRD entries and FIS length */
-       __le32 ttl;             /* Total transfer length */
-       __le32 attribute;       /* the attribute of command */
-} __attribute__ ((packed)) cmd_hdr_entry_t;
-
-#define SATA_HC_CMD_HDR_ENTRY_SIZE     sizeof(struct cmd_hdr_entry)
-
-/* cda
-*/
-#define CMD_HDR_CDA_ALIGN      4
-
-/* prde_fis_len
-*/
-#define CMD_HDR_PRD_ENTRY_SHIFT        16
-#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
-#define CMD_HDR_FIS_LEN_SHIFT  2
-
-/* attribute
-*/
-#define CMD_HDR_ATTR_RES       0x00000800 /* Reserved bit, should be 1 */
-#define CMD_HDR_ATTR_VBIST     0x00000400 /* Vendor BIST */
-#define CMD_HDR_ATTR_SNOOP     0x00000200 /* Snoop enable for all descriptor */
-#define CMD_HDR_ATTR_FPDMA     0x00000100 /* FPDMA queued command */
-#define CMD_HDR_ATTR_RESET     0x00000080 /* Reset - a SRST or device reset */
-#define CMD_HDR_ATTR_BIST      0x00000040 /* BIST - require the host to enter BIST mode */
-#define CMD_HDR_ATTR_ATAPI     0x00000020 /* ATAPI command */
-#define CMD_HDR_ATTR_TAG       0x0000001f /* TAG mask */
-
-/* command type
-*/
-enum cmd_type {
-       CMD_VENDOR_BIST,
-       CMD_BIST,
-       CMD_RESET,      /* SRST or device reset */
-       CMD_ATAPI,
-       CMD_NCQ,
-       CMD_ATA,        /* None of all above */
-};
-
-/*
-* Command Header Table
-*/
-typedef struct cmd_hdr_tbl {
-       cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD];
-} __attribute__ ((packed)) cmd_hdr_tbl_t;
-
-#define SATA_HC_CMD_HDR_TBL_SIZE       sizeof(struct cmd_hdr_tbl)
-#define SATA_HC_CMD_HDR_TBL_ALIGN      4
-
-/*
-* PRD entry - Physical Region Descriptor entry
-*/
-typedef struct prd_entry {
-       __le32 dba;     /* Data base address, 4 bytes aligned */
-       u32 res1;
-       u32 res2;
-       __le32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */
-} __attribute__ ((packed)) prd_entry_t;
-
-#define SATA_HC_CMD_DESC_PRD_SIZE      sizeof(struct prd_entry)
-
-/* dba
-*/
-#define PRD_ENTRY_DBA_ALIGN    4
-
-/* ext_c_ddc
-*/
-#define PRD_ENTRY_EXT          0x80000000 /* extension flag */
-#ifdef CONFIG_FSL_SATA_V2
-#define PRD_ENTRY_DATA_SNOOP   0x10000000 /* Data snoop enable */
-#else
-#define PRD_ENTRY_DATA_SNOOP   0x00400000 /* Data snoop enable */
-#endif
-#define PRD_ENTRY_LEN_MASK     0x003fffff /* Data word count */
-
-#define PRD_ENTRY_MAX_XFER_SZ  (PRD_ENTRY_LEN_MASK + 1)
-
-/*
- * This SATA host controller supports a max of 16 direct PRD entries, but if use
- * chained indirect PRD entries, then the contollers supports upto a max of 63
- * entries including direct and indirect PRD entries.
- * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15
- * will be setup as an indirect descriptor, pointing to it's next (contigious)
- * PRD entries#16.
- */
-#define SATA_HC_MAX_PRD                63 /* Max PRD entry numbers per command */
-#define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */
-#define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1)
-#define SATA_HC_MAX_XFER_LEN   0x4000000
-
-/*
-* PRDT - Physical Region Descriptor Table
-*/
-typedef struct prdt {
-       prd_entry_t prdt[SATA_HC_MAX_PRD];
-} __attribute__ ((packed)) prdt_t;
-
-/*
-* Command Descriptor
-*/
-#define SATA_HC_CMD_DESC_CFIS_SIZE     32 /* bytes */
-#define SATA_HC_CMD_DESC_SFIS_SIZE     32 /* bytes */
-#define SATA_HC_CMD_DESC_ACMD_SIZE     16 /* bytes */
-#define SATA_HC_CMD_DESC_RES           16 /* bytes */
-
-typedef struct cmd_desc {
-       u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE];
-       u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE];
-       u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE];
-       u8 res[SATA_HC_CMD_DESC_RES];
-       prd_entry_t prdt[SATA_HC_MAX_PRD];
-} __attribute__ ((packed)) cmd_desc_t;
-
-#define SATA_HC_CMD_DESC_SIZE          sizeof(struct cmd_desc)
-#define SATA_HC_CMD_DESC_ALIGN         4
-
-/*
- * SATA device driver info
- */
-typedef struct fsl_sata_info {
-       u32     sata_reg_base;
-       u32     flags;
-} fsl_sata_info_t;
-
-#define FLAGS_DMA      0x00000000
-#define FLAGS_FPDMA    0x00000001
-
-/*
- * SATA device driver struct
- */
-typedef struct fsl_sata {
-       char            name[12];
-       fsl_sata_reg_t  *reg_base;              /* the base address of controller register */
-       void            *cmd_hdr_tbl_offset;    /* alloc address of command header table */
-       cmd_hdr_tbl_t   *cmd_hdr;               /* aligned address of command header table */
-       void            *cmd_desc_offset;       /* alloc address of command descriptor */
-       cmd_desc_t      *cmd_desc;              /* aligned address of command descriptor */
-       int             link;                   /* PHY link status */
-       /* device attribute */
-       int             ata_device_type;        /* device type */
-       int             lba48;
-       int             queue_depth;            /* Max NCQ queue depth */
-       u16             pio;
-       u16             mwdma;
-       u16             udma;
-       int             wcache;
-       int             flush;
-       int             flush_ext;
-} fsl_sata_t;
-
-#define READ_CMD       0
-#define WRITE_CMD      1
-
-#endif /* __FSL_SATA_H__ */
diff --git a/drivers/block/libata.c b/drivers/block/libata.c
deleted file mode 100644 (file)
index d684270..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2008 Freescale Semiconductor, Inc.
- *             Dave Liu <daveliu@freescale.com>
- *             port from the libata of linux kernel
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <libata.h>
-
-u64 ata_id_n_sectors(u16 *id)
-{
-       if (ata_id_has_lba(id)) {
-               if (ata_id_has_lba48(id))
-                       return ata_id_u64(id, ATA_ID_LBA48_SECTORS);
-               else
-                       return ata_id_u32(id, ATA_ID_LBA_SECTORS);
-       } else {
-               return 0;
-       }
-}
-
-u32 ata_dev_classify(u32 sig)
-{
-       u8 lbam, lbah;
-
-       lbam = (sig >> 16) & 0xff;
-       lbah = (sig >> 24) & 0xff;
-
-       if (((lbam == 0) && (lbah == 0)) ||
-               ((lbam == 0x3c) && (lbah == 0xc3)))
-               return ATA_DEV_ATA;
-
-       if ((lbam == 0x14) && (lbah == 0xeb))
-               return ATA_DEV_ATAPI;
-
-       if ((lbam == 0x69) && (lbah == 0x96))
-               return ATA_DEV_PMP;
-
-       return ATA_DEV_UNKNOWN;
-}
-
-static void ata_id_string(const u16 *id, unsigned char *s,
-                        unsigned int ofs, unsigned int len)
-{
-       unsigned int c;
-
-       while (len > 0) {
-               c = id[ofs] >> 8;
-               *s = c;
-               s++;
-
-               c = id[ofs] & 0xff;
-               *s = c;
-               s++;
-
-               ofs++;
-               len -= 2;
-       }
-}
-
-void ata_id_c_string(const u16 *id, unsigned char *s,
-                        unsigned int ofs, unsigned int len)
-{
-       unsigned char *p;
-
-       ata_id_string(id, s, ofs, len - 1);
-
-       p = s + strnlen((char *)s, len - 1);
-       while (p > s && p[-1] == ' ')
-               p--;
-       *p = '\0';
-}
-
-void ata_dump_id(u16 *id)
-{
-       unsigned char serial[ATA_ID_SERNO_LEN + 1];
-       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
-       unsigned char product[ATA_ID_PROD_LEN + 1];
-       u64 n_sectors;
-
-       /* Serial number */
-       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-       printf("S/N: %s\n\r", serial);
-
-       /* Firmware version */
-       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
-       printf("Firmware version: %s\n\r", firmware);
-
-       /* Product model */
-       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
-       printf("Product model number: %s\n\r", product);
-
-       /* Total sectors of device  */
-       n_sectors = ata_id_n_sectors(id);
-       printf("Capablity: %lld sectors\n\r", n_sectors);
-
-       printf ("id[49]: capabilities = 0x%04x\n"
-               "id[53]: field valid = 0x%04x\n"
-               "id[63]: mwdma = 0x%04x\n"
-               "id[64]: pio = 0x%04x\n"
-               "id[75]: queue depth = 0x%04x\n",
-               id[49],
-               id[53],
-               id[63],
-               id[64],
-               id[75]);
-
-       printf ("id[76]: sata capablity = 0x%04x\n"
-               "id[78]: sata features supported = 0x%04x\n"
-               "id[79]: sata features enable = 0x%04x\n",
-               id[76],
-               id[78],
-               id[79]);
-
-       printf ("id[80]: major version = 0x%04x\n"
-               "id[81]: minor version = 0x%04x\n"
-               "id[82]: command set supported 1 = 0x%04x\n"
-               "id[83]: command set supported 2 = 0x%04x\n"
-               "id[84]: command set extension = 0x%04x\n",
-               id[80],
-               id[81],
-               id[82],
-               id[83],
-               id[84]);
-       printf ("id[85]: command set enable 1 = 0x%04x\n"
-               "id[86]: command set enable 2 = 0x%04x\n"
-               "id[87]: command set default = 0x%04x\n"
-               "id[88]: udma = 0x%04x\n"
-               "id[93]: hardware reset result = 0x%04x\n",
-               id[85],
-               id[86],
-               id[87],
-               id[88],
-               id[93]);
-}
-
-void ata_swap_buf_le16(u16 *buf, unsigned int buf_words)
-{
-       unsigned int i;
-
-       for (i = 0; i < buf_words; i++)
-               buf[i] = le16_to_cpu(buf[i]);
-}
diff --git a/drivers/block/mvsata_ide.c b/drivers/block/mvsata_ide.c
deleted file mode 100644 (file)
index 7b6a155..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
- *
- * Written-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-
-#if defined(CONFIG_ORION5X)
-#include <asm/arch/orion5x.h>
-#elif defined(CONFIG_KIRKWOOD)
-#include <asm/arch/soc.h>
-#elif defined(CONFIG_ARCH_MVEBU)
-#include <linux/mbus.h>
-#endif
-
-/* SATA port registers */
-struct mvsata_port_registers {
-       u32 reserved0[10];
-       u32 edma_cmd;
-       u32 reserved1[181];
-       /* offset 0x300 : ATA Interface registers */
-       u32 sstatus;
-       u32 serror;
-       u32 scontrol;
-       u32 ltmode;
-       u32 phymode3;
-       u32 phymode4;
-       u32 reserved2[5];
-       u32 phymode1;
-       u32 phymode2;
-       u32 bist_cr;
-       u32 bist_dw1;
-       u32 bist_dw2;
-       u32 serrorintrmask;
-};
-
-/*
- * Sanity checks:
- * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR.
- * - for ide_preinit to make sense, we need at least one of
- *   CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET;
- * - for ide_preinit to be called, we need CONFIG_IDE_PREINIT.
- * Fail with an explanation message if these conditions are not met.
- * This is particularly important for CONFIG_IDE_PREINIT, because
- * its lack would not cause a build error.
- */
-
-#if !defined(CONFIG_SYS_ATA_BASE_ADDR)
-#error CONFIG_SYS_ATA_BASE_ADDR must be defined
-#elif !defined(CONFIG_SYS_ATA_IDE0_OFFSET) \
-   && !defined(CONFIG_SYS_ATA_IDE1_OFFSET)
-#error CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET \
-   must be defined
-#elif !defined(CONFIG_IDE_PREINIT)
-#error CONFIG_IDE_PREINIT must be defined
-#endif
-
-/*
- * Masks and values for SControl DETection and Interface Power Management,
- * and for SStatus DETection.
- */
-
-#define MVSATA_EDMA_CMD_ATA_RST                0x00000004
-#define MVSATA_SCONTROL_DET_MASK               0x0000000F
-#define MVSATA_SCONTROL_DET_NONE               0x00000000
-#define MVSATA_SCONTROL_DET_INIT               0x00000001
-#define MVSATA_SCONTROL_IPM_MASK               0x00000F00
-#define MVSATA_SCONTROL_IPM_NO_LP_ALLOWED      0x00000300
-#define MVSATA_SCONTROL_MASK \
-       (MVSATA_SCONTROL_DET_MASK|MVSATA_SCONTROL_IPM_MASK)
-#define MVSATA_PORT_INIT \
-       (MVSATA_SCONTROL_DET_INIT|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
-#define MVSATA_PORT_USE \
-       (MVSATA_SCONTROL_DET_NONE|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
-#define MVSATA_SSTATUS_DET_MASK                        0x0000000F
-#define MVSATA_SSTATUS_DET_DEVCOMM             0x00000003
-
-/*
- * Status codes to return to client callers. Currently, callers ignore
- * exact value and only care for zero or nonzero, so no need to make this
- * public, it is only #define'd for clarity.
- * If/when standard negative codes are implemented in U-Boot, then these
- * #defines should be moved to, or replaced by ones from, the common list
- * of status codes.
- */
-
-#define MVSATA_STATUS_OK       0
-#define MVSATA_STATUS_TIMEOUT  -1
-
-/*
- * Registers for SATA MBUS memory windows
- */
-
-#define MVSATA_WIN_CONTROL(w)  (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
-#define MVSATA_WIN_BASE(w)     (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
-
-/*
- * Initialize SATA memory windows for Armada XP
- */
-
-#ifdef CONFIG_ARCH_MVEBU
-static void mvsata_ide_conf_mbus_windows(void)
-{
-       const struct mbus_dram_target_info *dram;
-       int i;
-
-       dram = mvebu_mbus_dram_info();
-
-       /* Disable windows, Set Size/Base to 0  */
-       for (i = 0; i < 4; i++) {
-               writel(0, MVSATA_WIN_CONTROL(i));
-               writel(0, MVSATA_WIN_BASE(i));
-       }
-
-       for (i = 0; i < dram->num_cs; i++) {
-               const struct mbus_dram_window *cs = dram->cs + i;
-               writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
-                               (dram->mbus_dram_target_id << 4) | 1,
-                               MVSATA_WIN_CONTROL(i));
-               writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
-       }
-}
-#endif
-
-/*
- * Initialize one MVSATAHC port: set SControl's IPM to "always active"
- * and DET to "reset", then wait for SStatus's DET to become "device and
- * comm ok" (or time out after 50 us if no device), then set SControl's
- * DET back to "no action".
- */
-
-static int mvsata_ide_initialize_port(struct mvsata_port_registers *port)
-{
-       u32 control;
-       u32 status;
-       u32 timeleft = 10000; /* wait at most 10 ms for SATA reset to complete */
-
-       /* Hard reset */
-       writel(MVSATA_EDMA_CMD_ATA_RST, &port->edma_cmd);
-       udelay(25); /* taken from original marvell port */
-       writel(0, &port->edma_cmd);
-
-       /* Set control IPM to 3 (no low power) and DET to 1 (initialize) */
-       control = readl(&port->scontrol);
-       control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT;
-       writel(control, &port->scontrol);
-       /* Toggle control DET back to 0 (normal operation) */
-       control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE;
-       writel(control, &port->scontrol);
-       /* wait for status DET to become 3 (device and communication OK) */
-       while (--timeleft) {
-               status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK;
-               if (status == MVSATA_SSTATUS_DET_DEVCOMM)
-                       break;
-               udelay(1);
-       }
-       /* return success or time-out error depending on time left */
-       if (!timeleft)
-               return MVSATA_STATUS_TIMEOUT;
-       return MVSATA_STATUS_OK;
-}
-
-/*
- * ide_preinit() will be called by ide_init in cmd_ide.c and will
- * reset the MVSTATHC ports needed by the board.
- */
-
-int ide_preinit(void)
-{
-       int ret = MVSATA_STATUS_TIMEOUT;
-       int status;
-
-#ifdef CONFIG_ARCH_MVEBU
-       mvsata_ide_conf_mbus_windows();
-#endif
-
-       /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */
-#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
-       status = mvsata_ide_initialize_port(
-               (struct mvsata_port_registers *)
-               (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET));
-       if (status == MVSATA_STATUS_OK)
-               ret = MVSATA_STATUS_OK;
-#endif
-       /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */
-#if defined(CONFIG_SYS_ATA_IDE1_OFFSET)
-       status = mvsata_ide_initialize_port(
-               (struct mvsata_port_registers *)
-               (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET));
-       if (status == MVSATA_STATUS_OK)
-               ret = MVSATA_STATUS_OK;
-#endif
-       /* Return success if at least one port initialization succeeded */
-       return ret;
-}
diff --git a/drivers/block/mxc_ata.c b/drivers/block/mxc_ata.c
deleted file mode 100644 (file)
index 44bb406..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Freescale iMX51 ATA driver
- *
- * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
- *
- * Based on code by:
- *     Mahesh Mahadevan <mahesh.mahadevan@freescale.com>
- *
- * Based on code from original FSL ATA driver, which is
- * part of eCos, the Embedded Configurable Operating System.
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <command.h>
-#include <config.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <ide.h>
-
-#include <asm/arch/imx-regs.h>
-#include <asm/arch/clock.h>
-
-/* MXC ATA register offsets */
-struct mxc_ata_config_regs {
-       u8      time_off;       /* 0x00 */
-       u8      time_on;
-       u8      time_1;
-       u8      time_2w;
-       u8      time_2r;
-       u8      time_ax;
-       u8      time_pio_rdx;
-       u8      time_4;
-       u8      time_9;
-       u8      time_m;
-       u8      time_jn;
-       u8      time_d;
-       u8      time_k;
-       u8      time_ack;
-       u8      time_env;
-       u8      time_udma_rdx;
-       u8      time_zah;       /* 0x10 */
-       u8      time_mlix;
-       u8      time_dvh;
-       u8      time_dzfs;
-       u8      time_dvs;
-       u8      time_cvh;
-       u8      time_ss;
-       u8      time_cyc;
-       u32     fifo_data_32;   /* 0x18 */
-       u32     fifo_data_16;
-       u32     fifo_fill;
-       u32     ata_control;
-       u32     interrupt_pending;
-       u32     interrupt_enable;
-       u32     interrupt_clear;
-       u32     fifo_alarm;
-};
-
-struct mxc_data_hdd_regs {
-       u32     drive_data;     /* 0xa0 */
-       u32     drive_features;
-       u32     drive_sector_count;
-       u32     drive_sector_num;
-       u32     drive_cyl_low;
-       u32     drive_cyl_high;
-       u32     drive_dev_head;
-       u32     command;
-       u32     status;
-       u32     alt_status;
-};
-
-/* PIO timing table */
-#define        NR_PIO_SPECS    5
-static uint16_t pio_t1[NR_PIO_SPECS]   = { 70,  50,  30,  30,  25 };
-static uint16_t pio_t2_8[NR_PIO_SPECS] = { 290, 290, 290, 80,  70 };
-static uint16_t pio_t4[NR_PIO_SPECS]   = { 30,  20,  15,  10,  10 };
-static uint16_t pio_t9[NR_PIO_SPECS]   = { 20,  15,  10,  10,  10 };
-static uint16_t pio_tA[NR_PIO_SPECS]   = { 50,  50,  50,  50,  50 };
-
-#define        REG2OFF(reg)    ((((uint32_t)reg) & 0x3) * 8)
-static void set_ata_bus_timing(unsigned char mode)
-{
-       uint32_t T = 1000000000 / mxc_get_clock(MXC_IPG_CLK);
-
-       struct mxc_ata_config_regs *ata_regs;
-       ata_regs = (struct mxc_ata_config_regs *)CONFIG_SYS_ATA_BASE_ADDR;
-
-       if (mode >= NR_PIO_SPECS)
-               return;
-
-       /* Write TIME_OFF/ON/1/2W */
-       writeb(3, &ata_regs->time_off);
-       writeb(3, &ata_regs->time_on);
-       writeb((pio_t1[mode] + T) / T, &ata_regs->time_1);
-       writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2w);
-
-       /* Write TIME_2R/AX/RDX/4 */
-       writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2r);
-       writeb((pio_tA[mode] + T) / T + 2, &ata_regs->time_ax);
-       writeb(1, &ata_regs->time_pio_rdx);
-       writeb((pio_t4[mode] + T) / T, &ata_regs->time_4);
-
-       /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */
-       writeb((pio_t9[mode] + T) / T, &ata_regs->time_9);
-}
-
-int ide_preinit(void)
-{
-       struct mxc_ata_config_regs *ata_regs;
-       ata_regs = (struct mxc_ata_config_regs *)CONFIG_SYS_ATA_BASE_ADDR;
-
-       /* 46.3.3.4 @ FSL iMX51 manual */
-       /* FIFO normal op., drive reset */
-       writel(0x80, &ata_regs->ata_control);
-       /* FIFO normal op., drive not reset */
-       writel(0xc0, &ata_regs->ata_control);
-
-       /* Configure the PIO timing */
-       set_ata_bus_timing(CONFIG_MXC_ATA_PIO_MODE);
-
-       /* 46.3.3.4 @ FSL iMX51 manual */
-       /* Drive not reset, IORDY handshake */
-       writel(0x41, &ata_regs->ata_control);
-
-       return 0;
-}
diff --git a/drivers/block/sata_ceva.c b/drivers/block/sata_ceva.c
deleted file mode 100644 (file)
index 0c24fce..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * (C) Copyright 2015 - 2016 Xilinx, Inc.
- * Michal Simek <michal.simek@xilinx.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-#include <common.h>
-#include <dm.h>
-#include <ahci.h>
-#include <scsi.h>
-#include <asm/arch/hardware.h>
-
-#include <asm/io.h>
-
-/* Vendor Specific Register Offsets */
-#define AHCI_VEND_PCFG  0xA4
-#define AHCI_VEND_PPCFG 0xA8
-#define AHCI_VEND_PP2C  0xAC
-#define AHCI_VEND_PP3C  0xB0
-#define AHCI_VEND_PP4C  0xB4
-#define AHCI_VEND_PP5C  0xB8
-#define AHCI_VEND_PAXIC 0xC0
-#define AHCI_VEND_PTC   0xC8
-
-/* Vendor Specific Register bit definitions */
-#define PAXIC_ADBW_BW64 0x1
-#define PAXIC_MAWIDD   (1 << 8)
-#define PAXIC_MARIDD   (1 << 16)
-#define PAXIC_OTL      (0x4 << 20)
-
-#define PCFG_TPSS_VAL  (0x32 << 16)
-#define PCFG_TPRS_VAL  (0x2 << 12)
-#define PCFG_PAD_VAL   0x2
-
-#define PPCFG_TTA      0x1FFFE
-#define PPCFG_PSSO_EN  (1 << 28)
-#define PPCFG_PSS_EN   (1 << 29)
-#define PPCFG_ESDF_EN  (1 << 31)
-
-#define PP2C_CIBGMN    0x0F
-#define PP2C_CIBGMX    (0x25 << 8)
-#define PP2C_CIBGN     (0x18 << 16)
-#define PP2C_CINMP     (0x29 << 24)
-
-#define PP3C_CWBGMN    0x04
-#define PP3C_CWBGMX    (0x0B << 8)
-#define PP3C_CWBGN     (0x08 << 16)
-#define PP3C_CWNMP     (0x0F << 24)
-
-#define PP4C_BMX       0x0a
-#define PP4C_BNM       (0x08 << 8)
-#define PP4C_SFD       (0x4a << 16)
-#define PP4C_PTST      (0x06 << 24)
-
-#define PP5C_RIT       0x60216
-#define PP5C_RCT       (0x7f0 << 20)
-
-#define PTC_RX_WM_VAL  0x40
-#define PTC_RSVD       (1 << 27)
-
-#define PORT0_BASE     0x100
-#define PORT1_BASE     0x180
-
-/* Port Control Register Bit Definitions */
-#define PORT_SCTL_SPD_GEN3     (0x3 << 4)
-#define PORT_SCTL_SPD_GEN2     (0x2 << 4)
-#define PORT_SCTL_SPD_GEN1     (0x1 << 4)
-#define PORT_SCTL_IPM          (0x3 << 8)
-
-#define PORT_BASE      0x100
-#define PORT_OFFSET    0x80
-#define NR_PORTS       2
-#define DRV_NAME       "ahci-ceva"
-#define CEVA_FLAG_BROKEN_GEN2  1
-
-static int ceva_init_sata(ulong mmio)
-{
-       ulong tmp;
-       int i;
-
-       /*
-        * AXI Data bus width to 64
-        * Set Mem Addr Read, Write ID for data transfers
-        * Transfer limit to 72 DWord
-        */
-       tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL;
-       writel(tmp, mmio + AHCI_VEND_PAXIC);
-
-       /* Set AHCI Enable */
-       tmp = readl(mmio + HOST_CTL);
-       tmp |= HOST_AHCI_EN;
-       writel(tmp, mmio + HOST_CTL);
-
-       for (i = 0; i < NR_PORTS; i++) {
-               /* TPSS TPRS scalars, CISE and Port Addr */
-               tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i);
-               writel(tmp, mmio + AHCI_VEND_PCFG);
-
-               /* Port Phy Cfg register enables */
-               tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN;
-               writel(tmp, mmio + AHCI_VEND_PPCFG);
-
-               /* Rx Watermark setting  */
-               tmp = PTC_RX_WM_VAL | PTC_RSVD;
-               writel(tmp, mmio + AHCI_VEND_PTC);
-
-               /* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */
-               tmp = PORT_SCTL_SPD_GEN3 | PORT_SCTL_IPM;
-               writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i);
-       }
-       return 0;
-}
-
-static int sata_ceva_probe(struct udevice *dev)
-{
-       struct scsi_platdata *plat = dev_get_platdata(dev);
-
-       ceva_init_sata(plat->base);
-       return 0;
-}
-
-static const struct udevice_id sata_ceva_ids[] = {
-       { .compatible = "ceva,ahci-1v84" },
-       { }
-};
-
-static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
-{
-       struct scsi_platdata *plat = dev_get_platdata(dev);
-
-       plat->base = devfdt_get_addr(dev);
-       if (plat->base == FDT_ADDR_T_NONE)
-               return -EINVAL;
-
-       /* Hardcode number for ceva sata controller */
-       plat->max_lun = 1; /* Actually two but untested */
-       plat->max_id = 2;
-
-       return 0;
-}
-
-U_BOOT_DRIVER(ceva_host_blk) = {
-       .name = "ceva_sata",
-       .id = UCLASS_SCSI,
-       .of_match = sata_ceva_ids,
-       .probe = sata_ceva_probe,
-       .ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
-       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
-};
diff --git a/drivers/block/sata_dwc.c b/drivers/block/sata_dwc.c
deleted file mode 100644 (file)
index a226ca2..0000000
+++ /dev/null
@@ -1,2076 +0,0 @@
-/*
- * sata_dwc.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
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-/*
- * SATA support based on the chip canyonlands.
- *
- * 04-17-2009
- *             The local version of this driver for the canyonlands board
- *             does not use interrupts but polls the chip instead.
- */
-
-#include <common.h>
-#include <command.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <linux/errno.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <ata.h>
-#include <sata.h>
-#include <linux/ctype.h>
-
-#include "sata_dwc.h"
-
-#define DMA_NUM_CHANS                  1
-#define DMA_NUM_CHAN_REGS              8
-
-#define AHB_DMA_BRST_DFLT              16
-
-struct dmareg {
-       u32 low;
-       u32 high;
-};
-
-struct dma_chan_regs {
-       struct dmareg sar;
-       struct dmareg dar;
-       struct dmareg llp;
-       struct dmareg ctl;
-       struct dmareg sstat;
-       struct dmareg dstat;
-       struct dmareg sstatar;
-       struct dmareg dstatar;
-       struct dmareg cfg;
-       struct dmareg sgr;
-       struct dmareg dsr;
-};
-
-struct dma_interrupt_regs {
-       struct dmareg tfr;
-       struct dmareg block;
-       struct dmareg srctran;
-       struct dmareg dsttran;
-       struct dmareg error;
-};
-
-struct ahb_dma_regs {
-       struct dma_chan_regs    chan_regs[DMA_NUM_CHAN_REGS];
-       struct dma_interrupt_regs       interrupt_raw;
-       struct dma_interrupt_regs       interrupt_status;
-       struct dma_interrupt_regs       interrupt_mask;
-       struct dma_interrupt_regs       interrupt_clear;
-       struct dmareg                   statusInt;
-       struct dmareg                   rq_srcreg;
-       struct dmareg                   rq_dstreg;
-       struct dmareg                   rq_sgl_srcreg;
-       struct dmareg                   rq_sgl_dstreg;
-       struct dmareg                   rq_lst_srcreg;
-       struct dmareg                   rq_lst_dstreg;
-       struct dmareg                   dma_cfg;
-       struct dmareg                   dma_chan_en;
-       struct dmareg                   dma_id;
-       struct dmareg                   dma_test;
-       struct dmareg                   res1;
-       struct dmareg                   res2;
-       /* DMA Comp Params
-        * Param 6 = dma_param[0], Param 5 = dma_param[1],
-        * Param 4 = dma_param[2] ...
-        */
-       struct dmareg                   dma_params[6];
-};
-
-#define DMA_EN                 0x00000001
-#define DMA_DI                 0x00000000
-#define DMA_CHANNEL(ch)                (0x00000001 << (ch))
-#define DMA_ENABLE_CHAN(ch)    ((0x00000001 << (ch)) | \
-                               ((0x000000001 << (ch)) << 8))
-#define DMA_DISABLE_CHAN(ch)   (0x00000000 |   \
-                               ((0x000000001 << (ch)) << 8))
-
-#define SATA_DWC_MAX_PORTS     1
-#define SATA_DWC_SCR_OFFSET    0x24
-#define SATA_DWC_REG_OFFSET    0x64
-
-struct sata_dwc_regs {
-       u32 fptagr;
-       u32 fpbor;
-       u32 fptcr;
-       u32 dmacr;
-       u32 dbtsr;
-       u32 intpr;
-       u32 intmr;
-       u32 errmr;
-       u32 llcr;
-       u32 phycr;
-       u32 physr;
-       u32 rxbistpd;
-       u32 rxbistpd1;
-       u32 rxbistpd2;
-       u32 txbistpd;
-       u32 txbistpd1;
-       u32 txbistpd2;
-       u32 bistcr;
-       u32 bistfctr;
-       u32 bistsr;
-       u32 bistdecr;
-       u32 res[15];
-       u32 testr;
-       u32 versionr;
-       u32 idr;
-       u32 unimpl[192];
-       u32 dmadr[256];
-};
-
-#define SATA_DWC_TXFIFO_DEPTH          0x01FF
-#define SATA_DWC_RXFIFO_DEPTH          0x01FF
-
-#define SATA_DWC_DBTSR_MWR(size)       ((size / 4) & SATA_DWC_TXFIFO_DEPTH)
-#define SATA_DWC_DBTSR_MRD(size)       (((size / 4) &  \
-                                       SATA_DWC_RXFIFO_DEPTH) << 16)
-#define SATA_DWC_INTPR_DMAT            0x00000001
-#define SATA_DWC_INTPR_NEWFP           0x00000002
-#define SATA_DWC_INTPR_PMABRT          0x00000004
-#define SATA_DWC_INTPR_ERR             0x00000008
-#define SATA_DWC_INTPR_NEWBIST         0x00000010
-#define SATA_DWC_INTPR_IPF             0x10000000
-#define SATA_DWC_INTMR_DMATM           0x00000001
-#define SATA_DWC_INTMR_NEWFPM          0x00000002
-#define SATA_DWC_INTMR_PMABRTM         0x00000004
-#define SATA_DWC_INTMR_ERRM            0x00000008
-#define SATA_DWC_INTMR_NEWBISTM                0x00000010
-
-#define SATA_DWC_DMACR_TMOD_TXCHEN     0x00000004
-#define SATA_DWC_DMACR_TXRXCH_CLEAR    SATA_DWC_DMACR_TMOD_TXCHEN
-
-#define SATA_DWC_QCMD_MAX      32
-
-#define SATA_DWC_SERROR_ERR_BITS       0x0FFF0F03
-
-#define HSDEVP_FROM_AP(ap)     (struct sata_dwc_device_port*)  \
-                               (ap)->private_data
-
-struct sata_dwc_device {
-       struct device           *dev;
-       struct ata_probe_ent    *pe;
-       struct ata_host         *host;
-       u8                      *reg_base;
-       struct sata_dwc_regs    *sata_dwc_regs;
-       int                     irq_dma;
-};
-
-struct sata_dwc_device_port {
-       struct sata_dwc_device  *hsdev;
-       int                     cmd_issued[SATA_DWC_QCMD_MAX];
-       u32                     dma_chan[SATA_DWC_QCMD_MAX];
-       int                     dma_pending[SATA_DWC_QCMD_MAX];
-};
-
-enum {
-       SATA_DWC_CMD_ISSUED_NOT         = 0,
-       SATA_DWC_CMD_ISSUED_PEND        = 1,
-       SATA_DWC_CMD_ISSUED_EXEC        = 2,
-       SATA_DWC_CMD_ISSUED_NODATA      = 3,
-
-       SATA_DWC_DMA_PENDING_NONE       = 0,
-       SATA_DWC_DMA_PENDING_TX         = 1,
-       SATA_DWC_DMA_PENDING_RX         = 2,
-};
-
-#define msleep(a)      udelay(a * 1000)
-#define ssleep(a)      msleep(a * 1000)
-
-static int ata_probe_timeout = (ATA_TMOUT_INTERNAL / 100);
-
-enum sata_dev_state {
-       SATA_INIT = 0,
-       SATA_READY = 1,
-       SATA_NODEVICE = 2,
-       SATA_ERROR = 3,
-};
-enum sata_dev_state dev_state = SATA_INIT;
-
-static struct ahb_dma_regs             *sata_dma_regs = 0;
-static struct ata_host                 *phost;
-static struct ata_port                 ap;
-static struct ata_port                 *pap = &ap;
-static struct ata_device               ata_device;
-static struct sata_dwc_device_port     dwc_devp;
-
-static void    *scr_addr_sstatus;
-static u32     temp_n_block = 0;
-
-static unsigned ata_exec_internal(struct ata_device *dev,
-                       struct ata_taskfile *tf, const u8 *cdb,
-                       int dma_dir, unsigned int buflen,
-                       unsigned long timeout);
-static unsigned int ata_dev_set_feature(struct ata_device *dev,
-                       u8 enable,u8 feature);
-static unsigned int ata_dev_init_params(struct ata_device *dev,
-                       u16 heads, u16 sectors);
-static u8 ata_irq_on(struct ata_port *ap);
-static struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
-                       unsigned int tag);
-static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
-                       u8 status, int in_wq);
-static void ata_tf_to_host(struct ata_port *ap,
-                       const struct ata_taskfile *tf);
-static void ata_exec_command(struct ata_port *ap,
-                       const struct ata_taskfile *tf);
-static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
-static u8 ata_check_altstatus(struct ata_port *ap);
-static u8 ata_check_status(struct ata_port *ap);
-static void ata_dev_select(struct ata_port *ap, unsigned int device,
-                       unsigned int wait, unsigned int can_sleep);
-static void ata_qc_issue(struct ata_queued_cmd *qc);
-static void ata_tf_load(struct ata_port *ap,
-                       const struct ata_taskfile *tf);
-static int ata_dev_read_sectors(unsigned char* pdata,
-                       unsigned long datalen, u32 block, u32 n_block);
-static int ata_dev_write_sectors(unsigned char* pdata,
-                       unsigned long datalen , u32 block, u32 n_block);
-static void ata_std_dev_select(struct ata_port *ap, unsigned int device);
-static void ata_qc_complete(struct ata_queued_cmd *qc);
-static void __ata_qc_complete(struct ata_queued_cmd *qc);
-static void fill_result_tf(struct ata_queued_cmd *qc);
-static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-static void ata_mmio_data_xfer(struct ata_device *dev,
-                       unsigned char *buf,
-                       unsigned int buflen,int do_write);
-static void ata_pio_task(struct ata_port *arg_ap);
-static void __ata_port_freeze(struct ata_port *ap);
-static int ata_port_freeze(struct ata_port *ap);
-static void ata_qc_free(struct ata_queued_cmd *qc);
-static void ata_pio_sectors(struct ata_queued_cmd *qc);
-static void ata_pio_sector(struct ata_queued_cmd *qc);
-static void ata_pio_queue_task(struct ata_port *ap,
-                       void *data,unsigned long delay);
-static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq);
-static int sata_dwc_softreset(struct ata_port *ap);
-static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
-               unsigned int flags, u16 *id);
-static int check_sata_dev_state(void);
-
-static const struct ata_port_info sata_dwc_port_info[] = {
-       {
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                               ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING |
-                               ATA_FLAG_SRST | ATA_FLAG_NCQ,
-               .pio_mask       = 0x1f,
-               .mwdma_mask     = 0x07,
-               .udma_mask      = 0x7f,
-       },
-};
-
-int init_sata(int dev)
-{
-       struct sata_dwc_device hsdev;
-       struct ata_host host;
-       struct ata_port_info pi = sata_dwc_port_info[0];
-       struct ata_link *link;
-       struct sata_dwc_device_port hsdevp = dwc_devp;
-       u8 *base = 0;
-       u8 *sata_dma_regs_addr = 0;
-       u8 status;
-       unsigned long base_addr = 0;
-       int chan = 0;
-       int rc;
-       int i;
-
-       phost = &host;
-
-       base = (u8*)SATA_BASE_ADDR;
-
-       hsdev.sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);
-
-       host.n_ports = SATA_DWC_MAX_PORTS;
-
-       for (i = 0; i < SATA_DWC_MAX_PORTS; i++) {
-               ap.pflags |= ATA_PFLAG_INITIALIZING;
-               ap.flags = ATA_FLAG_DISABLED;
-               ap.print_id = -1;
-               ap.ctl = ATA_DEVCTL_OBS;
-               ap.host = &host;
-               ap.last_ctl = 0xFF;
-
-               link = &ap.link;
-               link->ap = &ap;
-               link->pmp = 0;
-               link->active_tag = ATA_TAG_POISON;
-               link->hw_sata_spd_limit = 0;
-
-               ap.port_no = i;
-               host.ports[i] = &ap;
-       }
-
-       ap.pio_mask = pi.pio_mask;
-       ap.mwdma_mask = pi.mwdma_mask;
-       ap.udma_mask = pi.udma_mask;
-       ap.flags |= pi.flags;
-       ap.link.flags |= pi.link_flags;
-
-       host.ports[0]->ioaddr.cmd_addr = base;
-       host.ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET;
-       scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET;
-
-       base_addr = (unsigned long)base;
-
-       host.ports[0]->ioaddr.cmd_addr = (void *)base_addr + 0x00;
-       host.ports[0]->ioaddr.data_addr = (void *)base_addr + 0x00;
-
-       host.ports[0]->ioaddr.error_addr = (void *)base_addr + 0x04;
-       host.ports[0]->ioaddr.feature_addr = (void *)base_addr + 0x04;
-
-       host.ports[0]->ioaddr.nsect_addr = (void *)base_addr + 0x08;
-
-       host.ports[0]->ioaddr.lbal_addr = (void *)base_addr + 0x0c;
-       host.ports[0]->ioaddr.lbam_addr = (void *)base_addr + 0x10;
-       host.ports[0]->ioaddr.lbah_addr = (void *)base_addr + 0x14;
-
-       host.ports[0]->ioaddr.device_addr = (void *)base_addr + 0x18;
-       host.ports[0]->ioaddr.command_addr = (void *)base_addr + 0x1c;
-       host.ports[0]->ioaddr.status_addr = (void *)base_addr + 0x1c;
-
-       host.ports[0]->ioaddr.altstatus_addr = (void *)base_addr + 0x20;
-       host.ports[0]->ioaddr.ctl_addr = (void *)base_addr + 0x20;
-
-       sata_dma_regs_addr = (u8*)SATA_DMA_REG_ADDR;
-       sata_dma_regs = (void *__iomem)sata_dma_regs_addr;
-
-       status = ata_check_altstatus(&ap);
-
-       if (status == 0x7f) {
-               printf("Hard Disk not found.\n");
-               dev_state = SATA_NODEVICE;
-               rc = false;
-               return rc;
-       }
-
-       printf("Waiting for device...");
-       i = 0;
-       while (1) {
-               udelay(10000);
-
-               status = ata_check_altstatus(&ap);
-
-               if ((status & ATA_BUSY) == 0) {
-                       printf("\n");
-                       break;
-               }
-
-               i++;
-               if (i > (ATA_RESET_TIME * 100)) {
-                       printf("** TimeOUT **\n");
-
-                       dev_state = SATA_NODEVICE;
-                       rc = false;
-                       return rc;
-               }
-               if ((i >= 100) && ((i % 100) == 0))
-                       printf(".");
-       }
-
-       rc = sata_dwc_softreset(&ap);
-
-       if (rc) {
-               printf("sata_dwc : error. soft reset failed\n");
-               return rc;
-       }
-
-       for (chan = 0; chan < DMA_NUM_CHANS; chan++) {
-               out_le32(&(sata_dma_regs->interrupt_mask.error.low),
-                               DMA_DISABLE_CHAN(chan));
-
-               out_le32(&(sata_dma_regs->interrupt_mask.tfr.low),
-                               DMA_DISABLE_CHAN(chan));
-       }
-
-       out_le32(&(sata_dma_regs->dma_cfg.low), DMA_DI);
-
-       out_le32(&hsdev.sata_dwc_regs->intmr,
-               SATA_DWC_INTMR_ERRM |
-               SATA_DWC_INTMR_PMABRTM);
-
-       /* Unmask the error bits that should trigger
-        * an error interrupt by setting the error mask register.
-        */
-       out_le32(&hsdev.sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS);
-
-       hsdev.host = ap.host;
-       memset(&hsdevp, 0, sizeof(hsdevp));
-       hsdevp.hsdev = &hsdev;
-
-       for (i = 0; i < SATA_DWC_QCMD_MAX; i++)
-               hsdevp.cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT;
-
-       out_le32((void __iomem *)scr_addr_sstatus + 4,
-               in_le32((void __iomem *)scr_addr_sstatus + 4));
-
-       rc = 0;
-       return rc;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-static u8 ata_check_altstatus(struct ata_port *ap)
-{
-       u8 val = 0;
-       val = readb(ap->ioaddr.altstatus_addr);
-       return val;
-}
-
-static int sata_dwc_softreset(struct ata_port *ap)
-{
-       u8 nsect,lbal = 0;
-       u8 tmp = 0;
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       in_le32((void *)ap->ioaddr.scr_addr + (SCR_ERROR * 4));
-
-       writeb(0x55, ioaddr->nsect_addr);
-       writeb(0xaa, ioaddr->lbal_addr);
-       writeb(0xaa, ioaddr->nsect_addr);
-       writeb(0x55, ioaddr->lbal_addr);
-       writeb(0x55, ioaddr->nsect_addr);
-       writeb(0xaa, ioaddr->lbal_addr);
-
-       nsect = readb(ioaddr->nsect_addr);
-       lbal = readb(ioaddr->lbal_addr);
-
-       if ((nsect == 0x55) && (lbal == 0xaa)) {
-               printf("Device found\n");
-       } else {
-               printf("No device found\n");
-               dev_state = SATA_NODEVICE;
-               return false;
-       }
-
-       tmp = ATA_DEVICE_OBS;
-       writeb(tmp, ioaddr->device_addr);
-       writeb(ap->ctl, ioaddr->ctl_addr);
-
-       udelay(200);
-
-       writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-
-       udelay(200);
-       writeb(ap->ctl, ioaddr->ctl_addr);
-
-       msleep(150);
-       ata_check_status(ap);
-
-       msleep(50);
-       ata_check_status(ap);
-
-       while (1) {
-               u8 status = ata_check_status(ap);
-
-               if (!(status & ATA_BUSY))
-                       break;
-
-               printf("Hard Disk status is BUSY.\n");
-               msleep(50);
-       }
-
-       tmp = ATA_DEVICE_OBS;
-       writeb(tmp, ioaddr->device_addr);
-
-       nsect = readb(ioaddr->nsect_addr);
-       lbal = readb(ioaddr->lbal_addr);
-
-       return 0;
-}
-
-static u8 ata_check_status(struct ata_port *ap)
-{
-       u8 val = 0;
-       val = readb(ap->ioaddr.status_addr);
-       return val;
-}
-
-static int ata_id_has_hipm(const u16 *id)
-{
-       u16 val = id[76];
-
-       if (val == 0 || val == 0xffff)
-               return -1;
-
-       return val & (1 << 9);
-}
-
-static int ata_id_has_dipm(const u16 *id)
-{
-       u16 val = id[78];
-
-       if (val == 0 || val == 0xffff)
-               return -1;
-
-       return val & (1 << 3);
-}
-
-int scan_sata(int dev)
-{
-       int i;
-       int rc;
-       u8 status;
-       const u16 *id;
-       struct ata_device *ata_dev = &ata_device;
-       unsigned long pio_mask, mwdma_mask;
-       char revbuf[7];
-       u16 iobuf[ATA_SECTOR_WORDS];
-
-       memset(iobuf, 0, sizeof(iobuf));
-
-       if (dev_state == SATA_NODEVICE)
-               return 1;
-
-       printf("Waiting for device...");
-       i = 0;
-       while (1) {
-               udelay(10000);
-
-               status = ata_check_altstatus(&ap);
-
-               if ((status & ATA_BUSY) == 0) {
-                       printf("\n");
-                       break;
-               }
-
-               i++;
-               if (i > (ATA_RESET_TIME * 100)) {
-                       printf("** TimeOUT **\n");
-
-                       dev_state = SATA_NODEVICE;
-                       return 1;
-               }
-               if ((i >= 100) && ((i % 100) == 0))
-                       printf(".");
-       }
-
-       udelay(1000);
-
-       rc = ata_dev_read_id(ata_dev, &ata_dev->class,
-                       ATA_READID_POSTRESET,ata_dev->id);
-       if (rc) {
-               printf("sata_dwc : error. failed sata scan\n");
-               return 1;
-       }
-
-       /* SATA drives indicate we have a bridge. We don't know which
-        * end of the link the bridge is which is a problem
-        */
-       if (ata_id_is_sata(ata_dev->id))
-               ap.cbl = ATA_CBL_SATA;
-
-       id = ata_dev->id;
-
-       ata_dev->flags &= ~ATA_DFLAG_CFG_MASK;
-       ata_dev->max_sectors = 0;
-       ata_dev->cdb_len = 0;
-       ata_dev->n_sectors = 0;
-       ata_dev->cylinders = 0;
-       ata_dev->heads = 0;
-       ata_dev->sectors = 0;
-
-       if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
-               pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
-               pio_mask <<= 3;
-               pio_mask |= 0x7;
-       } else {
-               /* If word 64 isn't valid then Word 51 high byte holds
-                * the PIO timing number for the maximum. Turn it into
-                * a mask.
-                */
-               u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF;
-               if (mode < 5) {
-                       pio_mask = (2 << mode) - 1;
-               } else {
-                       pio_mask = 1;
-               }
-       }
-
-       mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
-
-       if (ata_id_is_cfa(id)) {
-               int pio = id[163] & 0x7;
-               int dma = (id[163] >> 3) & 7;
-
-               if (pio)
-                       pio_mask |= (1 << 5);
-               if (pio > 1)
-                       pio_mask |= (1 << 6);
-               if (dma)
-                       mwdma_mask |= (1 << 3);
-               if (dma > 1)
-                       mwdma_mask |= (1 << 4);
-       }
-
-       if (ata_dev->class == ATA_DEV_ATA) {
-               if (ata_id_is_cfa(id)) {
-                       if (id[162] & 1)
-                               printf("supports DRM functions and may "
-                                       "not be fully accessable.\n");
-                       strcpy(revbuf, "CFA");
-               } else {
-                       if (ata_id_has_tpm(id))
-                               printf("supports DRM functions and may "
-                                               "not be fully accessable.\n");
-               }
-
-               ata_dev->n_sectors = ata_id_n_sectors((u16*)id);
-
-               if (ata_dev->id[59] & 0x100)
-                       ata_dev->multi_count = ata_dev->id[59] & 0xff;
-
-               if (ata_id_has_lba(id)) {
-                       char ncq_desc[20];
-
-                       ata_dev->flags |= ATA_DFLAG_LBA;
-                       if (ata_id_has_lba48(id)) {
-                               ata_dev->flags |= ATA_DFLAG_LBA48;
-
-                               if (ata_dev->n_sectors >= (1UL << 28) &&
-                                       ata_id_has_flush_ext(id))
-                                       ata_dev->flags |= ATA_DFLAG_FLUSH_EXT;
-                       }
-                       if (!ata_id_has_ncq(ata_dev->id))
-                               ncq_desc[0] = '\0';
-
-                       if (ata_dev->horkage & ATA_HORKAGE_NONCQ)
-                               strcpy(ncq_desc, "NCQ (not used)");
-
-                       if (ap.flags & ATA_FLAG_NCQ)
-                               ata_dev->flags |= ATA_DFLAG_NCQ;
-               }
-               ata_dev->cdb_len = 16;
-       }
-       ata_dev->max_sectors = ATA_MAX_SECTORS;
-       if (ata_dev->flags & ATA_DFLAG_LBA48)
-               ata_dev->max_sectors = ATA_MAX_SECTORS_LBA48;
-
-       if (!(ata_dev->horkage & ATA_HORKAGE_IPM)) {
-               if (ata_id_has_hipm(ata_dev->id))
-                       ata_dev->flags |= ATA_DFLAG_HIPM;
-               if (ata_id_has_dipm(ata_dev->id))
-                       ata_dev->flags |= ATA_DFLAG_DIPM;
-       }
-
-       if ((ap.cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ata_dev->id))) {
-               ata_dev->udma_mask &= ATA_UDMA5;
-               ata_dev->max_sectors = ATA_MAX_SECTORS;
-       }
-
-       if (ata_dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
-               printf("Drive reports diagnostics failure."
-                               "This may indicate a drive\n");
-               printf("fault or invalid emulation."
-                               "Contact drive vendor for information.\n");
-       }
-
-       rc = check_sata_dev_state();
-
-       ata_id_c_string(ata_dev->id,
-                       (unsigned char *)sata_dev_desc[dev].revision,
-                        ATA_ID_FW_REV, sizeof(sata_dev_desc[dev].revision));
-       ata_id_c_string(ata_dev->id,
-                       (unsigned char *)sata_dev_desc[dev].vendor,
-                        ATA_ID_PROD, sizeof(sata_dev_desc[dev].vendor));
-       ata_id_c_string(ata_dev->id,
-                       (unsigned char *)sata_dev_desc[dev].product,
-                        ATA_ID_SERNO, sizeof(sata_dev_desc[dev].product));
-
-       sata_dev_desc[dev].lba = (u32) ata_dev->n_sectors;
-
-#ifdef CONFIG_LBA48
-       if (ata_dev->id[83] & (1 << 10)) {
-               sata_dev_desc[dev].lba48 = 1;
-       } else {
-               sata_dev_desc[dev].lba48 = 0;
-       }
-#endif
-
-       return 0;
-}
-
-static u8 ata_busy_wait(struct ata_port *ap,
-               unsigned int bits,unsigned int max)
-{
-       u8 status;
-
-       do {
-               udelay(10);
-               status = ata_check_status(ap);
-               max--;
-       } while (status != 0xff && (status & bits) && (max > 0));
-
-       return status;
-}
-
-static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
-               unsigned int flags, u16 *id)
-{
-       struct ata_port *ap = pap;
-       unsigned int class = *p_class;
-       struct ata_taskfile tf;
-       unsigned int err_mask = 0;
-       const char *reason;
-       int may_fallback = 1, tried_spinup = 0;
-       u8 status;
-       int rc;
-
-       status = ata_busy_wait(ap, ATA_BUSY, 30000);
-       if (status & ATA_BUSY) {
-               printf("BSY = 0 check. timeout.\n");
-               rc = false;
-               return rc;
-       }
-
-       ata_dev_select(ap, dev->devno, 1, 1);
-
-retry:
-       memset(&tf, 0, sizeof(tf));
-       ap->print_id = 1;
-       ap->flags &= ~ATA_FLAG_DISABLED;
-       tf.ctl = ap->ctl;
-       tf.device = ATA_DEVICE_OBS;
-       tf.command = ATA_CMD_ID_ATA;
-       tf.protocol = ATA_PROT_PIO;
-
-       /* Some devices choke if TF registers contain garbage.  Make
-        * sure those are properly initialized.
-        */
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-
-       /* Device presence detection is unreliable on some
-        * controllers.  Always poll IDENTIFY if available.
-        */
-       tf.flags |= ATA_TFLAG_POLLING;
-
-       temp_n_block = 1;
-
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
-                                       sizeof(id[0]) * ATA_ID_WORDS, 0);
-
-       if (err_mask) {
-               if (err_mask & AC_ERR_NODEV_HINT) {
-                       printf("NODEV after polling detection\n");
-                       return -ENOENT;
-               }
-
-               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
-                       /* Device or controller might have reported
-                        * the wrong device class.  Give a shot at the
-                        * other IDENTIFY if the current one is
-                        * aborted by the device.
-                        */
-                       if (may_fallback) {
-                               may_fallback = 0;
-
-                               if (class == ATA_DEV_ATA) {
-                                       class = ATA_DEV_ATAPI;
-                               } else {
-                                       class = ATA_DEV_ATA;
-                               }
-                               goto retry;
-                       }
-                       /* Control reaches here iff the device aborted
-                        * both flavors of IDENTIFYs which happens
-                        * sometimes with phantom devices.
-                        */
-                       printf("both IDENTIFYs aborted, assuming NODEV\n");
-                       return -ENOENT;
-               }
-               rc = -EIO;
-               reason = "I/O error";
-               goto err_out;
-       }
-
-       /* Falling back doesn't make sense if ID data was read
-        * successfully at least once.
-        */
-       may_fallback = 0;
-
-       unsigned int id_cnt;
-
-       for (id_cnt = 0; id_cnt < ATA_ID_WORDS; id_cnt++)
-               id[id_cnt] = le16_to_cpu(id[id_cnt]);
-
-
-       rc = -EINVAL;
-       reason = "device reports invalid type";
-
-       if (class == ATA_DEV_ATA) {
-               if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
-                       goto err_out;
-       } else {
-               if (ata_id_is_ata(id))
-                       goto err_out;
-       }
-       if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
-               tried_spinup = 1;
-               /*
-                * Drive powered-up in standby mode, and requires a specific
-                * SET_FEATURES spin-up subcommand before it will accept
-                * anything other than the original IDENTIFY command.
-                */
-               err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
-               if (err_mask && id[2] != 0x738c) {
-                       rc = -EIO;
-                       reason = "SPINUP failed";
-                       goto err_out;
-               }
-               /*
-                * If the drive initially returned incomplete IDENTIFY info,
-                * we now must reissue the IDENTIFY command.
-                */
-               if (id[2] == 0x37c8)
-                       goto retry;
-       }
-
-       if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
-               /*
-                * The exact sequence expected by certain pre-ATA4 drives is:
-                * SRST RESET
-                * IDENTIFY (optional in early ATA)
-                * INITIALIZE DEVICE PARAMETERS (later IDE and ATA)
-                * anything else..
-                * Some drives were very specific about that exact sequence.
-                *
-                * Note that ATA4 says lba is mandatory so the second check
-                * shoud never trigger.
-                */
-               if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
-                       err_mask = ata_dev_init_params(dev, id[3], id[6]);
-                       if (err_mask) {
-                               rc = -EIO;
-                               reason = "INIT_DEV_PARAMS failed";
-                               goto err_out;
-                       }
-
-                       /* current CHS translation info (id[53-58]) might be
-                        * changed. reread the identify device info.
-                        */
-                       flags &= ~ATA_READID_POSTRESET;
-                       goto retry;
-               }
-       }
-
-       *p_class = class;
-       return 0;
-
-err_out:
-       printf("failed to READ ID (%s, err_mask=0x%x)\n", reason, err_mask);
-       return rc;
-}
-
-static u8 ata_wait_idle(struct ata_port *ap)
-{
-       u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
-       return status;
-}
-
-static void ata_dev_select(struct ata_port *ap, unsigned int device,
-               unsigned int wait, unsigned int can_sleep)
-{
-       if (wait)
-               ata_wait_idle(ap);
-
-       ata_std_dev_select(ap, device);
-
-       if (wait)
-               ata_wait_idle(ap);
-}
-
-static void ata_std_dev_select(struct ata_port *ap, unsigned int device)
-{
-       u8 tmp;
-
-       if (device == 0) {
-               tmp = ATA_DEVICE_OBS;
-       } else {
-               tmp = ATA_DEVICE_OBS | ATA_DEV1;
-       }
-
-       writeb(tmp, ap->ioaddr.device_addr);
-
-       readb(ap->ioaddr.altstatus_addr);
-
-       udelay(1);
-}
-
-static int waiting_for_reg_state(volatile u8 *offset,
-                               int timeout_msec,
-                               u32 sign)
-{
-       int i;
-       u32 status;
-
-       for (i = 0; i < timeout_msec; i++) {
-               status = readl(offset);
-               if ((status & sign) != 0)
-                       break;
-               msleep(1);
-       }
-
-       return (i < timeout_msec) ? 0 : -1;
-}
-
-static void ata_qc_reinit(struct ata_queued_cmd *qc)
-{
-       qc->dma_dir = DMA_NONE;
-       qc->flags = 0;
-       qc->nbytes = qc->extrabytes = qc->curbytes = 0;
-       qc->n_elem = 0;
-       qc->err_mask = 0;
-       qc->sect_size = ATA_SECT_SIZE;
-       qc->nbytes = ATA_SECT_SIZE * temp_n_block;
-
-       memset(&qc->tf, 0, sizeof(qc->tf));
-       qc->tf.ctl = 0;
-       qc->tf.device = ATA_DEVICE_OBS;
-
-       qc->result_tf.command = ATA_DRDY;
-       qc->result_tf.feature = 0;
-}
-
-struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
-                                       unsigned int tag)
-{
-       if (tag < ATA_MAX_QUEUE)
-               return &ap->qcmd[tag];
-       return NULL;
-}
-
-static void __ata_port_freeze(struct ata_port *ap)
-{
-       printf("set port freeze.\n");
-       ap->pflags |= ATA_PFLAG_FROZEN;
-}
-
-static int ata_port_freeze(struct ata_port *ap)
-{
-       __ata_port_freeze(ap);
-       return 0;
-}
-
-unsigned ata_exec_internal(struct ata_device *dev,
-                       struct ata_taskfile *tf, const u8 *cdb,
-                       int dma_dir, unsigned int buflen,
-                       unsigned long timeout)
-{
-       struct ata_link *link = dev->link;
-       struct ata_port *ap = pap;
-       struct ata_queued_cmd *qc;
-       unsigned int tag, preempted_tag;
-       u32 preempted_sactive, preempted_qc_active;
-       int preempted_nr_active_links;
-       unsigned int err_mask;
-       int rc = 0;
-       u8 status;
-
-       status = ata_busy_wait(ap, ATA_BUSY, 300000);
-       if (status & ATA_BUSY) {
-               printf("BSY = 0 check. timeout.\n");
-               rc = false;
-               return rc;
-       }
-
-       if (ap->pflags & ATA_PFLAG_FROZEN)
-               return AC_ERR_SYSTEM;
-
-       tag = ATA_TAG_INTERNAL;
-
-       if (test_and_set_bit(tag, &ap->qc_allocated)) {
-               rc = false;
-               return rc;
-       }
-
-       qc = __ata_qc_from_tag(ap, tag);
-       qc->tag = tag;
-       qc->ap = ap;
-       qc->dev = dev;
-
-       ata_qc_reinit(qc);
-
-       preempted_tag = link->active_tag;
-       preempted_sactive = link->sactive;
-       preempted_qc_active = ap->qc_active;
-       preempted_nr_active_links = ap->nr_active_links;
-       link->active_tag = ATA_TAG_POISON;
-       link->sactive = 0;
-       ap->qc_active = 0;
-       ap->nr_active_links = 0;
-
-       qc->tf = *tf;
-       if (cdb)
-               memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
-       qc->flags |= ATA_QCFLAG_RESULT_TF;
-       qc->dma_dir = dma_dir;
-       qc->private_data = 0;
-
-       ata_qc_issue(qc);
-
-       if (!timeout)
-               timeout = ata_probe_timeout * 1000 / HZ;
-
-       status = ata_busy_wait(ap, ATA_BUSY, 30000);
-       if (status & ATA_BUSY) {
-               printf("BSY = 0 check. timeout.\n");
-               printf("altstatus = 0x%x.\n", status);
-               qc->err_mask |= AC_ERR_OTHER;
-               return qc->err_mask;
-       }
-
-       if (waiting_for_reg_state(ap->ioaddr.altstatus_addr, 1000, 0x8)) {
-               u8 status = 0;
-               u8 errorStatus = 0;
-
-               status = readb(ap->ioaddr.altstatus_addr);
-               if ((status & 0x01) != 0) {
-                       errorStatus = readb(ap->ioaddr.feature_addr);
-                       if (errorStatus == 0x04 &&
-                               qc->tf.command == ATA_CMD_PIO_READ_EXT){
-                               printf("Hard Disk doesn't support LBA48\n");
-                               dev_state = SATA_ERROR;
-                               qc->err_mask |= AC_ERR_OTHER;
-                               return qc->err_mask;
-                       }
-               }
-               qc->err_mask |= AC_ERR_OTHER;
-               return qc->err_mask;
-       }
-
-       status = ata_busy_wait(ap, ATA_BUSY, 10);
-       if (status & ATA_BUSY) {
-               printf("BSY = 0 check. timeout.\n");
-               qc->err_mask |= AC_ERR_OTHER;
-               return qc->err_mask;
-       }
-
-       ata_pio_task(ap);
-
-       if (!rc) {
-               if (qc->flags & ATA_QCFLAG_ACTIVE) {
-                       qc->err_mask |= AC_ERR_TIMEOUT;
-                       ata_port_freeze(ap);
-               }
-       }
-
-       if (qc->flags & ATA_QCFLAG_FAILED) {
-               if (qc->result_tf.command & (ATA_ERR | ATA_DF))
-                       qc->err_mask |= AC_ERR_DEV;
-
-               if (!qc->err_mask)
-                       qc->err_mask |= AC_ERR_OTHER;
-
-               if (qc->err_mask & ~AC_ERR_OTHER)
-                       qc->err_mask &= ~AC_ERR_OTHER;
-       }
-
-       *tf = qc->result_tf;
-       err_mask = qc->err_mask;
-       ata_qc_free(qc);
-       link->active_tag = preempted_tag;
-       link->sactive = preempted_sactive;
-       ap->qc_active = preempted_qc_active;
-       ap->nr_active_links = preempted_nr_active_links;
-
-       if (ap->flags & ATA_FLAG_DISABLED) {
-               err_mask |= AC_ERR_SYSTEM;
-               ap->flags &= ~ATA_FLAG_DISABLED;
-       }
-
-       return err_mask;
-}
-
-static void ata_qc_issue(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct ata_link *link = qc->dev->link;
-       u8 prot = qc->tf.protocol;
-
-       if (ata_is_ncq(prot)) {
-               if (!link->sactive)
-                       ap->nr_active_links++;
-               link->sactive |= 1 << qc->tag;
-       } else {
-               ap->nr_active_links++;
-               link->active_tag = qc->tag;
-       }
-
-       qc->flags |= ATA_QCFLAG_ACTIVE;
-       ap->qc_active |= 1 << qc->tag;
-
-       if (qc->dev->flags & ATA_DFLAG_SLEEPING) {
-               msleep(1);
-               return;
-       }
-
-       qc->err_mask |= ata_qc_issue_prot(qc);
-       if (qc->err_mask)
-               goto err;
-
-       return;
-err:
-       ata_qc_complete(qc);
-}
-
-static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-
-       if (ap->flags & ATA_FLAG_PIO_POLLING) {
-               switch (qc->tf.protocol) {
-               case ATA_PROT_PIO:
-               case ATA_PROT_NODATA:
-               case ATAPI_PROT_PIO:
-               case ATAPI_PROT_NODATA:
-                       qc->tf.flags |= ATA_TFLAG_POLLING;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       ata_dev_select(ap, qc->dev->devno, 1, 0);
-
-       switch (qc->tf.protocol) {
-       case ATA_PROT_PIO:
-               if (qc->tf.flags & ATA_TFLAG_POLLING)
-                       qc->tf.ctl |= ATA_NIEN;
-
-               ata_tf_to_host(ap, &qc->tf);
-
-               ap->hsm_task_state = HSM_ST;
-
-               if (qc->tf.flags & ATA_TFLAG_POLLING)
-                       ata_pio_queue_task(ap, qc, 0);
-
-               break;
-
-       default:
-               return AC_ERR_SYSTEM;
-       }
-
-       return 0;
-}
-
-static void ata_tf_to_host(struct ata_port *ap,
-                       const struct ata_taskfile *tf)
-{
-       ata_tf_load(ap, tf);
-       ata_exec_command(ap, tf);
-}
-
-static void ata_tf_load(struct ata_port *ap,
-                       const struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               if (ioaddr->ctl_addr)
-                       writeb(tf->ctl, ioaddr->ctl_addr);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               writeb(tf->hob_feature, ioaddr->feature_addr);
-               writeb(tf->hob_nsect, ioaddr->nsect_addr);
-               writeb(tf->hob_lbal, ioaddr->lbal_addr);
-               writeb(tf->hob_lbam, ioaddr->lbam_addr);
-               writeb(tf->hob_lbah, ioaddr->lbah_addr);
-       }
-
-       if (is_addr) {
-               writeb(tf->feature, ioaddr->feature_addr);
-               writeb(tf->nsect, ioaddr->nsect_addr);
-               writeb(tf->lbal, ioaddr->lbal_addr);
-               writeb(tf->lbam, ioaddr->lbam_addr);
-               writeb(tf->lbah, ioaddr->lbah_addr);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE)
-               writeb(tf->device, ioaddr->device_addr);
-
-       ata_wait_idle(ap);
-}
-
-static void ata_exec_command(struct ata_port *ap,
-                       const struct ata_taskfile *tf)
-{
-       writeb(tf->command, ap->ioaddr.command_addr);
-
-       readb(ap->ioaddr.altstatus_addr);
-
-       udelay(1);
-}
-
-static void ata_pio_queue_task(struct ata_port *ap,
-                       void *data,unsigned long delay)
-{
-       ap->port_task_data = data;
-}
-
-static unsigned int ac_err_mask(u8 status)
-{
-       if (status & (ATA_BUSY | ATA_DRQ))
-               return AC_ERR_HSM;
-       if (status & (ATA_ERR | ATA_DF))
-               return AC_ERR_DEV;
-       return 0;
-}
-
-static unsigned int __ac_err_mask(u8 status)
-{
-       unsigned int mask = ac_err_mask(status);
-       if (mask == 0)
-               return AC_ERR_OTHER;
-       return mask;
-}
-
-static void ata_pio_task(struct ata_port *arg_ap)
-{
-       struct ata_port *ap = arg_ap;
-       struct ata_queued_cmd *qc = ap->port_task_data;
-       u8 status;
-       int poll_next;
-
-fsm_start:
-       /*
-        * This is purely heuristic.  This is a fast path.
-        * Sometimes when we enter, BSY will be cleared in
-        * a chk-status or two.  If not, the drive is probably seeking
-        * or something.  Snooze for a couple msecs, then
-        * chk-status again.  If still busy, queue delayed work.
-        */
-       status = ata_busy_wait(ap, ATA_BUSY, 5);
-       if (status & ATA_BUSY) {
-               msleep(2);
-               status = ata_busy_wait(ap, ATA_BUSY, 10);
-               if (status & ATA_BUSY) {
-                       ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
-                       return;
-               }
-       }
-
-       poll_next = ata_hsm_move(ap, qc, status, 1);
-
-       /* another command or interrupt handler
-        * may be running at this point.
-        */
-       if (poll_next)
-               goto fsm_start;
-}
-
-static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
-                       u8 status, int in_wq)
-{
-       int poll_next;
-
-fsm_start:
-       switch (ap->hsm_task_state) {
-       case HSM_ST_FIRST:
-               poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
-
-               if ((status & ATA_DRQ) == 0) {
-                       if (status & (ATA_ERR | ATA_DF)) {
-                               qc->err_mask |= AC_ERR_DEV;
-                       } else {
-                               qc->err_mask |= AC_ERR_HSM;
-                       }
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-
-               /* Device should not ask for data transfer (DRQ=1)
-                * when it finds something wrong.
-                * We ignore DRQ here and stop the HSM by
-                * changing hsm_task_state to HSM_ST_ERR and
-                * let the EH abort the command or reset the device.
-                */
-               if (status & (ATA_ERR | ATA_DF)) {
-                       if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
-                               printf("DRQ=1 with device error, "
-                                       "dev_stat 0x%X\n", status);
-                               qc->err_mask |= AC_ERR_HSM;
-                               ap->hsm_task_state = HSM_ST_ERR;
-                               goto fsm_start;
-                       }
-               }
-
-               if (qc->tf.protocol == ATA_PROT_PIO) {
-                       /* PIO data out protocol.
-                        * send first data block.
-                        */
-                       /* ata_pio_sectors() might change the state
-                        * to HSM_ST_LAST. so, the state is changed here
-                        * before ata_pio_sectors().
-                        */
-                       ap->hsm_task_state = HSM_ST;
-                       ata_pio_sectors(qc);
-               } else {
-                       printf("protocol is not ATA_PROT_PIO \n");
-               }
-               break;
-
-       case HSM_ST:
-               if ((status & ATA_DRQ) == 0) {
-                       if (status & (ATA_ERR | ATA_DF)) {
-                               qc->err_mask |= AC_ERR_DEV;
-                       } else {
-                               /* HSM violation. Let EH handle this.
-                                * Phantom devices also trigger this
-                                * condition.  Mark hint.
-                                */
-                               qc->err_mask |= AC_ERR_HSM | AC_ERR_NODEV_HINT;
-                       }
-
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-               /* For PIO reads, some devices may ask for
-                * data transfer (DRQ=1) alone with ERR=1.
-                * We respect DRQ here and transfer one
-                * block of junk data before changing the
-                * hsm_task_state to HSM_ST_ERR.
-                *
-                * For PIO writes, ERR=1 DRQ=1 doesn't make
-                * sense since the data block has been
-                * transferred to the device.
-                */
-               if (status & (ATA_ERR | ATA_DF)) {
-                       qc->err_mask |= AC_ERR_DEV;
-
-                       if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
-                               ata_pio_sectors(qc);
-                               status = ata_wait_idle(ap);
-                       }
-
-                       if (status & (ATA_BUSY | ATA_DRQ))
-                               qc->err_mask |= AC_ERR_HSM;
-
-                       /* ata_pio_sectors() might change the
-                        * state to HSM_ST_LAST. so, the state
-                        * is changed after ata_pio_sectors().
-                        */
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-
-               ata_pio_sectors(qc);
-               if (ap->hsm_task_state == HSM_ST_LAST &&
-                       (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
-                       status = ata_wait_idle(ap);
-                       goto fsm_start;
-               }
-
-               poll_next = 1;
-               break;
-
-       case HSM_ST_LAST:
-               if (!ata_ok(status)) {
-                       qc->err_mask |= __ac_err_mask(status);
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-
-               ap->hsm_task_state = HSM_ST_IDLE;
-
-               ata_hsm_qc_complete(qc, in_wq);
-
-               poll_next = 0;
-               break;
-
-       case HSM_ST_ERR:
-               /* make sure qc->err_mask is available to
-                * know what's wrong and recover
-                */
-               ap->hsm_task_state = HSM_ST_IDLE;
-
-               ata_hsm_qc_complete(qc, in_wq);
-
-               poll_next = 0;
-               break;
-       default:
-               poll_next = 0;
-       }
-
-       return poll_next;
-}
-
-static void ata_pio_sectors(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap;
-       ap = pap;
-       qc->pdata = ap->pdata;
-
-       ata_pio_sector(qc);
-
-       readb(qc->ap->ioaddr.altstatus_addr);
-       udelay(1);
-}
-
-static void ata_pio_sector(struct ata_queued_cmd *qc)
-{
-       int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-       struct ata_port *ap = qc->ap;
-       unsigned int offset;
-       unsigned char *buf;
-       char temp_data_buf[512];
-
-       if (qc->curbytes == qc->nbytes - qc->sect_size)
-               ap->hsm_task_state = HSM_ST_LAST;
-
-       offset = qc->curbytes;
-
-       switch (qc->tf.command) {
-       case ATA_CMD_ID_ATA:
-               buf = (unsigned char *)&ata_device.id[0];
-               break;
-       case ATA_CMD_PIO_READ_EXT:
-       case ATA_CMD_PIO_READ:
-       case ATA_CMD_PIO_WRITE_EXT:
-       case ATA_CMD_PIO_WRITE:
-               buf = qc->pdata + offset;
-               break;
-       default:
-               buf = (unsigned char *)&temp_data_buf[0];
-       }
-
-       ata_mmio_data_xfer(qc->dev, buf, qc->sect_size, do_write);
-
-       qc->curbytes += qc->sect_size;
-
-}
-
-static void ata_mmio_data_xfer(struct ata_device *dev, unsigned char *buf,
-                               unsigned int buflen, int do_write)
-{
-       struct ata_port *ap = pap;
-       void __iomem *data_addr = ap->ioaddr.data_addr;
-       unsigned int words = buflen >> 1;
-       u16 *buf16 = (u16 *)buf;
-       unsigned int i = 0;
-
-       udelay(100);
-       if (do_write) {
-               for (i = 0; i < words; i++)
-                       writew(le16_to_cpu(buf16[i]), data_addr);
-       } else {
-               for (i = 0; i < words; i++)
-                       buf16[i] = cpu_to_le16(readw(data_addr));
-       }
-
-       if (buflen & 0x01) {
-               __le16 align_buf[1] = { 0 };
-               unsigned char *trailing_buf = buf + buflen - 1;
-
-               if (do_write) {
-                       memcpy(align_buf, trailing_buf, 1);
-                       writew(le16_to_cpu(align_buf[0]), data_addr);
-               } else {
-                       align_buf[0] = cpu_to_le16(readw(data_addr));
-                       memcpy(trailing_buf, align_buf, 1);
-               }
-       }
-}
-
-static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
-{
-       struct ata_port *ap = qc->ap;
-
-       if (in_wq) {
-               /* EH might have kicked in while host lock is
-                * released.
-                */
-               qc = &ap->qcmd[qc->tag];
-               if (qc) {
-                       if (!(qc->err_mask & AC_ERR_HSM)) {
-                               ata_irq_on(ap);
-                               ata_qc_complete(qc);
-                       } else {
-                               ata_port_freeze(ap);
-                       }
-               }
-       } else {
-               if (!(qc->err_mask & AC_ERR_HSM)) {
-                       ata_qc_complete(qc);
-               } else {
-                       ata_port_freeze(ap);
-               }
-       }
-}
-
-static u8 ata_irq_on(struct ata_port *ap)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       u8 tmp;
-
-       ap->ctl &= ~ATA_NIEN;
-       ap->last_ctl = ap->ctl;
-
-       if (ioaddr->ctl_addr)
-               writeb(ap->ctl, ioaddr->ctl_addr);
-
-       tmp = ata_wait_idle(ap);
-
-       return tmp;
-}
-
-static unsigned int ata_tag_internal(unsigned int tag)
-{
-       return tag == ATA_MAX_QUEUE - 1;
-}
-
-static void ata_qc_complete(struct ata_queued_cmd *qc)
-{
-       struct ata_device *dev = qc->dev;
-       if (qc->err_mask)
-               qc->flags |= ATA_QCFLAG_FAILED;
-
-       if (qc->flags & ATA_QCFLAG_FAILED) {
-               if (!ata_tag_internal(qc->tag)) {
-                       fill_result_tf(qc);
-                       return;
-               }
-       }
-       if (qc->flags & ATA_QCFLAG_RESULT_TF)
-               fill_result_tf(qc);
-
-       /* Some commands need post-processing after successful
-        * completion.
-        */
-       switch (qc->tf.command) {
-       case ATA_CMD_SET_FEATURES:
-               if (qc->tf.feature != SETFEATURES_WC_ON &&
-                               qc->tf.feature != SETFEATURES_WC_OFF)
-                       break;
-       case ATA_CMD_INIT_DEV_PARAMS:
-       case ATA_CMD_SET_MULTI:
-               break;
-
-       case ATA_CMD_SLEEP:
-               dev->flags |= ATA_DFLAG_SLEEPING;
-               break;
-       }
-
-       __ata_qc_complete(qc);
-}
-
-static void fill_result_tf(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-
-       qc->result_tf.flags = qc->tf.flags;
-       ata_tf_read(ap, &qc->result_tf);
-}
-
-static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       tf->command = ata_check_status(ap);
-       tf->feature = readb(ioaddr->error_addr);
-       tf->nsect = readb(ioaddr->nsect_addr);
-       tf->lbal = readb(ioaddr->lbal_addr);
-       tf->lbam = readb(ioaddr->lbam_addr);
-       tf->lbah = readb(ioaddr->lbah_addr);
-       tf->device = readb(ioaddr->device_addr);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               if (ioaddr->ctl_addr) {
-                       writeb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
-
-                       tf->hob_feature = readb(ioaddr->error_addr);
-                       tf->hob_nsect = readb(ioaddr->nsect_addr);
-                       tf->hob_lbal = readb(ioaddr->lbal_addr);
-                       tf->hob_lbam = readb(ioaddr->lbam_addr);
-                       tf->hob_lbah = readb(ioaddr->lbah_addr);
-
-                       writeb(tf->ctl, ioaddr->ctl_addr);
-                       ap->last_ctl = tf->ctl;
-               } else {
-                       printf("sata_dwc warnning register read.\n");
-               }
-       }
-}
-
-static void __ata_qc_complete(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct ata_link *link = qc->dev->link;
-
-       link->active_tag = ATA_TAG_POISON;
-       ap->nr_active_links--;
-
-       if (qc->flags & ATA_QCFLAG_CLEAR_EXCL && ap->excl_link == link)
-               ap->excl_link = NULL;
-
-       qc->flags &= ~ATA_QCFLAG_ACTIVE;
-       ap->qc_active &= ~(1 << qc->tag);
-}
-
-static void ata_qc_free(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int tag;
-       qc->flags = 0;
-       tag = qc->tag;
-       if (tag < ATA_MAX_QUEUE) {
-               qc->tag = ATA_TAG_POISON;
-               clear_bit(tag, &ap->qc_allocated);
-       }
-}
-
-static int check_sata_dev_state(void)
-{
-       unsigned long datalen;
-       unsigned char *pdata;
-       int ret = 0;
-       int i = 0;
-       char temp_data_buf[512];
-
-       while (1) {
-               udelay(10000);
-
-               pdata = (unsigned char*)&temp_data_buf[0];
-               datalen = 512;
-
-               ret = ata_dev_read_sectors(pdata, datalen, 0, 1);
-
-               if (ret == true)
-                       break;
-
-               i++;
-               if (i > (ATA_RESET_TIME * 100)) {
-                       printf("** TimeOUT **\n");
-                       dev_state = SATA_NODEVICE;
-                       return false;
-               }
-
-               if ((i >= 100) && ((i % 100) == 0))
-                       printf(".");
-       }
-
-       dev_state = SATA_READY;
-
-       return true;
-}
-
-static unsigned int ata_dev_set_feature(struct ata_device *dev,
-                               u8 enable, u8 feature)
-{
-       struct ata_taskfile tf;
-       struct ata_port *ap;
-       ap = pap;
-       unsigned int err_mask;
-
-       memset(&tf, 0, sizeof(tf));
-       tf.ctl = ap->ctl;
-
-       tf.device = ATA_DEVICE_OBS;
-       tf.command = ATA_CMD_SET_FEATURES;
-       tf.feature = enable;
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       tf.protocol = ATA_PROT_NODATA;
-       tf.nsect = feature;
-
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
-
-       return err_mask;
-}
-
-static unsigned int ata_dev_init_params(struct ata_device *dev,
-                               u16 heads, u16 sectors)
-{
-       struct ata_taskfile tf;
-       struct ata_port *ap;
-       ap = pap;
-       unsigned int err_mask;
-
-       if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
-               return AC_ERR_INVALID;
-
-       memset(&tf, 0, sizeof(tf));
-       tf.ctl = ap->ctl;
-       tf.device = ATA_DEVICE_OBS;
-       tf.command = ATA_CMD_INIT_DEV_PARAMS;
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       tf.protocol = ATA_PROT_NODATA;
-       tf.nsect = sectors;
-       tf.device |= (heads - 1) & 0x0f;
-
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
-
-       if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
-               err_mask = 0;
-
-       return err_mask;
-}
-
-#if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
-#define SATA_MAX_READ_BLK 0xFF
-#else
-#define SATA_MAX_READ_BLK 0xFFFF
-#endif
-
-ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       ulong start,blks, buf_addr;
-       unsigned short smallblks;
-       unsigned long datalen;
-       unsigned char *pdata;
-       device &= 0xff;
-
-       u32 block = 0;
-       u32 n_block = 0;
-
-       if (dev_state != SATA_READY)
-               return 0;
-
-       buf_addr = (unsigned long)buffer;
-       start = blknr;
-       blks = blkcnt;
-       do {
-               pdata = (unsigned char *)buf_addr;
-               if (blks > SATA_MAX_READ_BLK) {
-                       datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
-                       smallblks = SATA_MAX_READ_BLK;
-
-                       block = (u32)start;
-                       n_block = (u32)smallblks;
-
-                       start += SATA_MAX_READ_BLK;
-                       blks -= SATA_MAX_READ_BLK;
-               } else {
-                       datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
-                       datalen = sata_dev_desc[device].blksz * blks;
-                       smallblks = (unsigned short)blks;
-
-                       block = (u32)start;
-                       n_block = (u32)smallblks;
-
-                       start += blks;
-                       blks = 0;
-               }
-
-               if (ata_dev_read_sectors(pdata, datalen, block, n_block) != true) {
-                       printf("sata_dwc : Hard disk read error.\n");
-                       blkcnt -= blks;
-                       break;
-               }
-               buf_addr += datalen;
-       } while (blks != 0);
-
-       return (blkcnt);
-}
-
-static int ata_dev_read_sectors(unsigned char *pdata, unsigned long datalen,
-                                               u32 block, u32 n_block)
-{
-       struct ata_port *ap = pap;
-       struct ata_device *dev = &ata_device;
-       struct ata_taskfile tf;
-       unsigned int class = ATA_DEV_ATA;
-       unsigned int err_mask = 0;
-       const char *reason;
-       int may_fallback = 1;
-
-       if (dev_state == SATA_ERROR)
-               return false;
-
-       ata_dev_select(ap, dev->devno, 1, 1);
-
-retry:
-       memset(&tf, 0, sizeof(tf));
-       tf.ctl = ap->ctl;
-       ap->print_id = 1;
-       ap->flags &= ~ATA_FLAG_DISABLED;
-
-       ap->pdata = pdata;
-
-       tf.device = ATA_DEVICE_OBS;
-
-       temp_n_block = n_block;
-
-#ifdef CONFIG_LBA48
-       tf.command = ATA_CMD_PIO_READ_EXT;
-       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
-
-       tf.hob_feature = 31;
-       tf.feature = 31;
-       tf.hob_nsect = (n_block >> 8) & 0xff;
-       tf.nsect = n_block & 0xff;
-
-       tf.hob_lbah = 0x0;
-       tf.hob_lbam = 0x0;
-       tf.hob_lbal = (block >> 24) & 0xff;
-       tf.lbah = (block >> 16) & 0xff;
-       tf.lbam = (block >> 8) & 0xff;
-       tf.lbal = block & 0xff;
-
-       tf.device = 1 << 6;
-       if (tf.flags & ATA_TFLAG_FUA)
-               tf.device |= 1 << 7;
-#else
-       tf.command = ATA_CMD_PIO_READ;
-       tf.flags |= ATA_TFLAG_LBA ;
-
-       tf.feature = 31;
-       tf.nsect = n_block & 0xff;
-
-       tf.lbah = (block >> 16) & 0xff;
-       tf.lbam = (block >> 8) & 0xff;
-       tf.lbal = block & 0xff;
-
-       tf.device = (block >> 24) & 0xf;
-
-       tf.device |= 1 << 6;
-       if (tf.flags & ATA_TFLAG_FUA)
-               tf.device |= 1 << 7;
-
-#endif
-
-       tf.protocol = ATA_PROT_PIO;
-
-       /* Some devices choke if TF registers contain garbage.  Make
-        * sure those are properly initialized.
-        */
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       tf.flags |= ATA_TFLAG_POLLING;
-
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
-
-       if (err_mask) {
-               if (err_mask & AC_ERR_NODEV_HINT) {
-                       printf("READ_SECTORS NODEV after polling detection\n");
-                       return -ENOENT;
-               }
-
-               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
-                       /* Device or controller might have reported
-                        * the wrong device class.  Give a shot at the
-                        * other IDENTIFY if the current one is
-                        * aborted by the device.
-                        */
-                       if (may_fallback) {
-                               may_fallback = 0;
-
-                               if (class == ATA_DEV_ATA) {
-                                       class = ATA_DEV_ATAPI;
-                               } else {
-                                       class = ATA_DEV_ATA;
-                               }
-                               goto retry;
-                       }
-                       /* Control reaches here iff the device aborted
-                        * both flavors of IDENTIFYs which happens
-                        * sometimes with phantom devices.
-                        */
-                       printf("both IDENTIFYs aborted, assuming NODEV\n");
-                       return -ENOENT;
-               }
-
-               reason = "I/O error";
-               goto err_out;
-       }
-
-       return true;
-
-err_out:
-       printf("failed to READ SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
-       return false;
-}
-
-#if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
-#define SATA_MAX_WRITE_BLK 0xFF
-#else
-#define SATA_MAX_WRITE_BLK 0xFFFF
-#endif
-
-ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       ulong start,blks, buf_addr;
-       unsigned short smallblks;
-       unsigned long datalen;
-       unsigned char *pdata;
-       device &= 0xff;
-
-
-       u32 block = 0;
-       u32 n_block = 0;
-
-       if (dev_state != SATA_READY)
-               return 0;
-
-       buf_addr = (unsigned long)buffer;
-       start = blknr;
-       blks = blkcnt;
-       do {
-               pdata = (unsigned char *)buf_addr;
-               if (blks > SATA_MAX_WRITE_BLK) {
-                       datalen = sata_dev_desc[device].blksz * SATA_MAX_WRITE_BLK;
-                       smallblks = SATA_MAX_WRITE_BLK;
-
-                       block = (u32)start;
-                       n_block = (u32)smallblks;
-
-                       start += SATA_MAX_WRITE_BLK;
-                       blks -= SATA_MAX_WRITE_BLK;
-               } else {
-                       datalen = sata_dev_desc[device].blksz * blks;
-                       smallblks = (unsigned short)blks;
-
-                       block = (u32)start;
-                       n_block = (u32)smallblks;
-
-                       start += blks;
-                       blks = 0;
-               }
-
-               if (ata_dev_write_sectors(pdata, datalen, block, n_block) != true) {
-                       printf("sata_dwc : Hard disk read error.\n");
-                       blkcnt -= blks;
-                       break;
-               }
-               buf_addr += datalen;
-       } while (blks != 0);
-
-       return (blkcnt);
-}
-
-static int ata_dev_write_sectors(unsigned char* pdata, unsigned long datalen,
-                                               u32 block, u32 n_block)
-{
-       struct ata_port *ap = pap;
-       struct ata_device *dev = &ata_device;
-       struct ata_taskfile tf;
-       unsigned int class = ATA_DEV_ATA;
-       unsigned int err_mask = 0;
-       const char *reason;
-       int may_fallback = 1;
-
-       if (dev_state == SATA_ERROR)
-               return false;
-
-       ata_dev_select(ap, dev->devno, 1, 1);
-
-retry:
-       memset(&tf, 0, sizeof(tf));
-       tf.ctl = ap->ctl;
-       ap->print_id = 1;
-       ap->flags &= ~ATA_FLAG_DISABLED;
-
-       ap->pdata = pdata;
-
-       tf.device = ATA_DEVICE_OBS;
-
-       temp_n_block = n_block;
-
-
-#ifdef CONFIG_LBA48
-       tf.command = ATA_CMD_PIO_WRITE_EXT;
-       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48 | ATA_TFLAG_WRITE;
-
-       tf.hob_feature = 31;
-       tf.feature = 31;
-       tf.hob_nsect = (n_block >> 8) & 0xff;
-       tf.nsect = n_block & 0xff;
-
-       tf.hob_lbah = 0x0;
-       tf.hob_lbam = 0x0;
-       tf.hob_lbal = (block >> 24) & 0xff;
-       tf.lbah = (block >> 16) & 0xff;
-       tf.lbam = (block >> 8) & 0xff;
-       tf.lbal = block & 0xff;
-
-       tf.device = 1 << 6;
-       if (tf.flags & ATA_TFLAG_FUA)
-               tf.device |= 1 << 7;
-#else
-       tf.command = ATA_CMD_PIO_WRITE;
-       tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_WRITE;
-
-       tf.feature = 31;
-       tf.nsect = n_block & 0xff;
-
-       tf.lbah = (block >> 16) & 0xff;
-       tf.lbam = (block >> 8) & 0xff;
-       tf.lbal = block & 0xff;
-
-       tf.device = (block >> 24) & 0xf;
-
-       tf.device |= 1 << 6;
-       if (tf.flags & ATA_TFLAG_FUA)
-               tf.device |= 1 << 7;
-
-#endif
-
-       tf.protocol = ATA_PROT_PIO;
-
-       /* Some devices choke if TF registers contain garbage.  Make
-        * sure those are properly initialized.
-        */
-       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       tf.flags |= ATA_TFLAG_POLLING;
-
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
-
-       if (err_mask) {
-               if (err_mask & AC_ERR_NODEV_HINT) {
-                       printf("READ_SECTORS NODEV after polling detection\n");
-                       return -ENOENT;
-               }
-
-               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
-                       /* Device or controller might have reported
-                        * the wrong device class.  Give a shot at the
-                        * other IDENTIFY if the current one is
-                        * aborted by the device.
-                        */
-                       if (may_fallback) {
-                               may_fallback = 0;
-
-                               if (class == ATA_DEV_ATA) {
-                                       class = ATA_DEV_ATAPI;
-                               } else {
-                                       class = ATA_DEV_ATA;
-                               }
-                               goto retry;
-                       }
-                       /* Control reaches here iff the device aborted
-                        * both flavors of IDENTIFYs which happens
-                        * sometimes with phantom devices.
-                        */
-                       printf("both IDENTIFYs aborted, assuming NODEV\n");
-                       return -ENOENT;
-               }
-
-               reason = "I/O error";
-               goto err_out;
-       }
-
-       return true;
-
-err_out:
-       printf("failed to WRITE SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
-       return false;
-}
diff --git a/drivers/block/sata_dwc.h b/drivers/block/sata_dwc.h
deleted file mode 100644 (file)
index e2d9e0c..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * sata_dwc.h
- *
- * 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
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-/*
- * SATA support based on the chip canyonlands.
- *
- * 04-17-2009
- *             The local version of this driver for the canyonlands board
- *             does not use interrupts but polls the chip instead.
- */
-
-
-#ifndef _SATA_DWC_H_
-#define _SATA_DWC_H_
-
-#define __U_BOOT__
-
-#define HZ 100
-#define READ 0
-#define WRITE 1
-
-enum {
-       ATA_READID_POSTRESET    = (1 << 0),
-
-       ATA_DNXFER_PIO          = 0,
-       ATA_DNXFER_DMA          = 1,
-       ATA_DNXFER_40C          = 2,
-       ATA_DNXFER_FORCE_PIO    = 3,
-       ATA_DNXFER_FORCE_PIO0   = 4,
-
-       ATA_DNXFER_QUIET        = (1 << 31),
-};
-
-enum hsm_task_states {
-       HSM_ST_IDLE,
-       HSM_ST_FIRST,
-       HSM_ST,
-       HSM_ST_LAST,
-       HSM_ST_ERR,
-};
-
-#define        ATA_SHORT_PAUSE         ((HZ >> 6) + 1)
-
-struct ata_queued_cmd {
-       struct ata_port         *ap;
-       struct ata_device       *dev;
-
-       struct ata_taskfile     tf;
-       u8                      cdb[ATAPI_CDB_LEN];
-       unsigned long           flags;
-       unsigned int            tag;
-       unsigned int            n_elem;
-
-       int                     dma_dir;
-       unsigned int            sect_size;
-
-       unsigned int            nbytes;
-       unsigned int            extrabytes;
-       unsigned int            curbytes;
-
-       unsigned int            err_mask;
-       struct ata_taskfile     result_tf;
-
-       void                    *private_data;
-#ifndef __U_BOOT__
-       void                    *lldd_task;
-#endif
-       unsigned char           *pdata;
-};
-
-typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
-
-#define ATA_TAG_POISON 0xfafbfcfdU
-
-enum {
-       LIBATA_MAX_PRD          = ATA_MAX_PRD / 2,
-       LIBATA_DUMB_MAX_PRD     = ATA_MAX_PRD / 4,
-       ATA_MAX_PORTS           = 8,
-       ATA_DEF_QUEUE           = 1,
-       ATA_MAX_QUEUE           = 32,
-       ATA_TAG_INTERNAL        = ATA_MAX_QUEUE - 1,
-       ATA_MAX_BUS             = 2,
-       ATA_DEF_BUSY_WAIT       = 10000,
-
-       ATAPI_MAX_DRAIN         = 16 << 10,
-
-       ATA_SHT_EMULATED        = 1,
-       ATA_SHT_CMD_PER_LUN     = 1,
-       ATA_SHT_THIS_ID         = -1,
-       ATA_SHT_USE_CLUSTERING  = 1,
-
-       ATA_DFLAG_LBA           = (1 << 0),
-       ATA_DFLAG_LBA48         = (1 << 1),
-       ATA_DFLAG_CDB_INTR      = (1 << 2),
-       ATA_DFLAG_NCQ           = (1 << 3),
-       ATA_DFLAG_FLUSH_EXT     = (1 << 4),
-       ATA_DFLAG_ACPI_PENDING  = (1 << 5),
-       ATA_DFLAG_ACPI_FAILED   = (1 << 6),
-       ATA_DFLAG_AN            = (1 << 7),
-       ATA_DFLAG_HIPM          = (1 << 8),
-       ATA_DFLAG_DIPM          = (1 << 9),
-       ATA_DFLAG_DMADIR        = (1 << 10),
-       ATA_DFLAG_CFG_MASK      = (1 << 12) - 1,
-
-       ATA_DFLAG_PIO           = (1 << 12),
-       ATA_DFLAG_NCQ_OFF       = (1 << 13),
-       ATA_DFLAG_SPUNDOWN      = (1 << 14),
-       ATA_DFLAG_SLEEPING      = (1 << 15),
-       ATA_DFLAG_DUBIOUS_XFER  = (1 << 16),
-       ATA_DFLAG_INIT_MASK     = (1 << 24) - 1,
-
-       ATA_DFLAG_DETACH        = (1 << 24),
-       ATA_DFLAG_DETACHED      = (1 << 25),
-
-       ATA_LFLAG_HRST_TO_RESUME        = (1 << 0),
-       ATA_LFLAG_SKIP_D2H_BSY          = (1 << 1),
-       ATA_LFLAG_NO_SRST               = (1 << 2),
-       ATA_LFLAG_ASSUME_ATA            = (1 << 3),
-       ATA_LFLAG_ASSUME_SEMB           = (1 << 4),
-       ATA_LFLAG_ASSUME_CLASS = ATA_LFLAG_ASSUME_ATA | ATA_LFLAG_ASSUME_SEMB,
-       ATA_LFLAG_NO_RETRY              = (1 << 5),
-       ATA_LFLAG_DISABLED              = (1 << 6),
-
-       ATA_FLAG_SLAVE_POSS     = (1 << 0),
-       ATA_FLAG_SATA           = (1 << 1),
-       ATA_FLAG_NO_LEGACY      = (1 << 2),
-       ATA_FLAG_MMIO           = (1 << 3),
-       ATA_FLAG_SRST           = (1 << 4),
-       ATA_FLAG_SATA_RESET     = (1 << 5),
-       ATA_FLAG_NO_ATAPI       = (1 << 6),
-       ATA_FLAG_PIO_DMA        = (1 << 7),
-       ATA_FLAG_PIO_LBA48      = (1 << 8),
-       ATA_FLAG_PIO_POLLING    = (1 << 9),
-       ATA_FLAG_NCQ            = (1 << 10),
-       ATA_FLAG_DEBUGMSG       = (1 << 13),
-       ATA_FLAG_IGN_SIMPLEX    = (1 << 15),
-       ATA_FLAG_NO_IORDY       = (1 << 16),
-       ATA_FLAG_ACPI_SATA      = (1 << 17),
-       ATA_FLAG_AN             = (1 << 18),
-       ATA_FLAG_PMP            = (1 << 19),
-       ATA_FLAG_IPM            = (1 << 20),
-
-       ATA_FLAG_DISABLED       = (1 << 23),
-
-       ATA_PFLAG_EH_PENDING            = (1 << 0),
-       ATA_PFLAG_EH_IN_PROGRESS        = (1 << 1),
-       ATA_PFLAG_FROZEN                = (1 << 2),
-       ATA_PFLAG_RECOVERED             = (1 << 3),
-       ATA_PFLAG_LOADING               = (1 << 4),
-       ATA_PFLAG_UNLOADING             = (1 << 5),
-       ATA_PFLAG_SCSI_HOTPLUG          = (1 << 6),
-       ATA_PFLAG_INITIALIZING          = (1 << 7),
-       ATA_PFLAG_RESETTING             = (1 << 8),
-       ATA_PFLAG_SUSPENDED             = (1 << 17),
-       ATA_PFLAG_PM_PENDING            = (1 << 18),
-
-       ATA_QCFLAG_ACTIVE       = (1 << 0),
-       ATA_QCFLAG_DMAMAP       = (1 << 1),
-       ATA_QCFLAG_IO           = (1 << 3),
-       ATA_QCFLAG_RESULT_TF    = (1 << 4),
-       ATA_QCFLAG_CLEAR_EXCL   = (1 << 5),
-       ATA_QCFLAG_QUIET        = (1 << 6),
-
-       ATA_QCFLAG_FAILED       = (1 << 16),
-       ATA_QCFLAG_SENSE_VALID  = (1 << 17),
-       ATA_QCFLAG_EH_SCHEDULED = (1 << 18),
-
-       ATA_HOST_SIMPLEX        = (1 << 0),
-       ATA_HOST_STARTED        = (1 << 1),
-
-       ATA_TMOUT_BOOT                  = 30 * 100,
-       ATA_TMOUT_BOOT_QUICK            = 7 * 100,
-       ATA_TMOUT_INTERNAL              = 30 * 100,
-       ATA_TMOUT_INTERNAL_QUICK        = 5 * 100,
-
-       /* FIXME: GoVault needs 2s but we can't afford that without
-        * parallel probing.  800ms is enough for iVDR disk
-        * HHD424020F7SV00.  Increase to 2secs when parallel probing
-        * is in place.
-        */
-       ATA_TMOUT_FF_WAIT       = 4 * 100 / 5,
-
-       BUS_UNKNOWN             = 0,
-       BUS_DMA                 = 1,
-       BUS_IDLE                = 2,
-       BUS_NOINTR              = 3,
-       BUS_NODATA              = 4,
-       BUS_TIMER               = 5,
-       BUS_PIO                 = 6,
-       BUS_EDD                 = 7,
-       BUS_IDENTIFY            = 8,
-       BUS_PACKET              = 9,
-
-       PORT_UNKNOWN            = 0,
-       PORT_ENABLED            = 1,
-       PORT_DISABLED           = 2,
-
-       /* encoding various smaller bitmaps into a single
-        * unsigned long bitmap
-        */
-       ATA_NR_PIO_MODES        = 7,
-       ATA_NR_MWDMA_MODES      = 5,
-       ATA_NR_UDMA_MODES       = 8,
-
-       ATA_SHIFT_PIO           = 0,
-       ATA_SHIFT_MWDMA         = ATA_SHIFT_PIO + ATA_NR_PIO_MODES,
-       ATA_SHIFT_UDMA          = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES,
-
-       ATA_DMA_PAD_SZ          = 4,
-
-       ATA_ERING_SIZE          = 32,
-
-       ATA_DEFER_LINK          = 1,
-       ATA_DEFER_PORT          = 2,
-
-       ATA_EH_DESC_LEN         = 80,
-
-       ATA_EH_REVALIDATE       = (1 << 0),
-       ATA_EH_SOFTRESET        = (1 << 1),
-       ATA_EH_HARDRESET        = (1 << 2),
-       ATA_EH_ENABLE_LINK      = (1 << 3),
-       ATA_EH_LPM              = (1 << 4),
-
-       ATA_EH_RESET_MASK       = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
-       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
-
-       ATA_EHI_HOTPLUGGED      = (1 << 0),
-       ATA_EHI_RESUME_LINK     = (1 << 1),
-       ATA_EHI_NO_AUTOPSY      = (1 << 2),
-       ATA_EHI_QUIET           = (1 << 3),
-
-       ATA_EHI_DID_SOFTRESET   = (1 << 16),
-       ATA_EHI_DID_HARDRESET   = (1 << 17),
-       ATA_EHI_PRINTINFO       = (1 << 18),
-       ATA_EHI_SETMODE         = (1 << 19),
-       ATA_EHI_POST_SETMODE    = (1 << 20),
-
-       ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
-       ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
-
-       ATA_EH_MAX_TRIES        = 5,
-
-       ATA_PROBE_MAX_TRIES     = 3,
-       ATA_EH_DEV_TRIES        = 3,
-       ATA_EH_PMP_TRIES        = 5,
-       ATA_EH_PMP_LINK_TRIES   = 3,
-
-       SATA_PMP_SCR_TIMEOUT    = 250,
-
-       /* Horkage types. May be set by libata or controller on drives
-       (some horkage may be drive/controller pair dependant */
-
-       ATA_HORKAGE_DIAGNOSTIC  = (1 << 0),
-       ATA_HORKAGE_NODMA       = (1 << 1),
-       ATA_HORKAGE_NONCQ       = (1 << 2),
-       ATA_HORKAGE_MAX_SEC_128 = (1 << 3),
-       ATA_HORKAGE_BROKEN_HPA  = (1 << 4),
-       ATA_HORKAGE_SKIP_PM     = (1 << 5),
-       ATA_HORKAGE_HPA_SIZE    = (1 << 6),
-       ATA_HORKAGE_IPM         = (1 << 7),
-       ATA_HORKAGE_IVB         = (1 << 8),
-       ATA_HORKAGE_STUCK_ERR   = (1 << 9),
-
-       ATA_DMA_MASK_ATA        = (1 << 0),
-       ATA_DMA_MASK_ATAPI      = (1 << 1),
-       ATA_DMA_MASK_CFA        = (1 << 2),
-
-       ATAPI_READ              = 0,
-       ATAPI_WRITE             = 1,
-       ATAPI_READ_CD           = 2,
-       ATAPI_PASS_THRU         = 3,
-       ATAPI_MISC              = 4,
-};
-
-enum ata_completion_errors {
-       AC_ERR_DEV              = (1 << 0),
-       AC_ERR_HSM              = (1 << 1),
-       AC_ERR_TIMEOUT          = (1 << 2),
-       AC_ERR_MEDIA            = (1 << 3),
-       AC_ERR_ATA_BUS          = (1 << 4),
-       AC_ERR_HOST_BUS         = (1 << 5),
-       AC_ERR_SYSTEM           = (1 << 6),
-       AC_ERR_INVALID          = (1 << 7),
-       AC_ERR_OTHER            = (1 << 8),
-       AC_ERR_NODEV_HINT       = (1 << 9),
-       AC_ERR_NCQ              = (1 << 10),
-};
-
-enum ata_xfer_mask {
-       ATA_MASK_PIO    = ((1LU << ATA_NR_PIO_MODES) - 1) << ATA_SHIFT_PIO,
-       ATA_MASK_MWDMA  = ((1LU << ATA_NR_MWDMA_MODES) - 1) << ATA_SHIFT_MWDMA,
-       ATA_MASK_UDMA   = ((1LU << ATA_NR_UDMA_MODES) - 1) << ATA_SHIFT_UDMA,
-};
-
-struct ata_port_info {
-#ifndef __U_BOOT__
-       struct scsi_host_template       *sht;
-#endif
-       unsigned long                   flags;
-       unsigned long                   link_flags;
-       unsigned long                   pio_mask;
-       unsigned long                   mwdma_mask;
-       unsigned long                   udma_mask;
-#ifndef __U_BOOT__
-       const struct ata_port_operations *port_ops;
-       void                            *private_data;
-#endif
-};
-
-struct ata_ioports {
-       void __iomem            *cmd_addr;
-       void __iomem            *data_addr;
-       void __iomem            *error_addr;
-       void __iomem            *feature_addr;
-       void __iomem            *nsect_addr;
-       void __iomem            *lbal_addr;
-       void __iomem            *lbam_addr;
-       void __iomem            *lbah_addr;
-       void __iomem            *device_addr;
-       void __iomem            *status_addr;
-       void __iomem            *command_addr;
-       void __iomem            *altstatus_addr;
-       void __iomem            *ctl_addr;
-#ifndef __U_BOOT__
-       void __iomem            *bmdma_addr;
-#endif
-       void __iomem            *scr_addr;
-};
-
-struct ata_host {
-#ifndef __U_BOOT__
-       void __iomem * const    *iomap;
-       void                    *private_data;
-       const struct ata_port_operations *ops;
-       unsigned long           flags;
-       struct ata_port         *simplex_claimed;
-#endif
-       unsigned int            n_ports;
-       struct ata_port         *ports[0];
-};
-
-#ifndef __U_BOOT__
-struct ata_port_stats {
-       unsigned long           unhandled_irq;
-       unsigned long           idle_irq;
-       unsigned long           rw_reqbuf;
-};
-#endif
-
-struct ata_device {
-       struct ata_link         *link;
-       unsigned int            devno;
-       unsigned long           flags;
-       unsigned int            horkage;
-#ifndef __U_BOOT__
-       struct scsi_device      *sdev;
-#ifdef CONFIG_ATA_ACPI
-       acpi_handle             acpi_handle;
-       union acpi_object       *gtf_cache;
-#endif
-#endif
-       u64                     n_sectors;
-       unsigned int            class;
-
-       union {
-               u16             id[ATA_ID_WORDS];
-               u32             gscr[SATA_PMP_GSCR_DWORDS];
-       };
-#ifndef __U_BOOT__
-       u8                      pio_mode;
-       u8                      dma_mode;
-       u8                      xfer_mode;
-       unsigned int            xfer_shift;
-#endif
-       unsigned int            multi_count;
-       unsigned int            max_sectors;
-       unsigned int            cdb_len;
-#ifndef __U_BOOT__
-       unsigned long           pio_mask;
-       unsigned long           mwdma_mask;
-#endif
-       unsigned long           udma_mask;
-       u16                     cylinders;
-       u16                     heads;
-       u16                     sectors;
-#ifndef __U_BOOT__
-       int                     spdn_cnt;
-#endif
-};
-
-enum dma_data_direction {
-       DMA_BIDIRECTIONAL = 0,
-       DMA_TO_DEVICE = 1,
-       DMA_FROM_DEVICE = 2,
-       DMA_NONE = 3,
-};
-
-struct ata_link {
-       struct ata_port         *ap;
-       int                     pmp;
-       unsigned int            active_tag;
-       u32                     sactive;
-       unsigned int            flags;
-       unsigned int            hw_sata_spd_limit;
-#ifndef __U_BOOT__
-       unsigned int            sata_spd_limit;
-       unsigned int            sata_spd;
-       struct ata_device       device[2];
-#endif
-};
-
-struct ata_port {
-       unsigned long           flags;
-       unsigned int            pflags;
-       unsigned int            print_id;
-       unsigned int            port_no;
-
-       struct ata_ioports      ioaddr;
-
-       u8                      ctl;
-       u8                      last_ctl;
-       unsigned int            pio_mask;
-       unsigned int            mwdma_mask;
-       unsigned int            udma_mask;
-       unsigned int            cbl;
-
-       struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE];
-       unsigned long           qc_allocated;
-       unsigned int            qc_active;
-       int                     nr_active_links;
-
-       struct ata_link         link;
-#ifndef __U_BOOT__
-       int                     nr_pmp_links;
-       struct ata_link         *pmp_link;
-#endif
-       struct ata_link         *excl_link;
-       int                     nr_pmp_links;
-#ifndef __U_BOOT__
-       struct ata_port_stats   stats;
-       struct device           *dev;
-       u32                     msg_enable;
-#endif
-       struct ata_host         *host;
-       void                    *port_task_data;
-
-       unsigned int            hsm_task_state;
-       void                    *private_data;
-       unsigned char           *pdata;
-};
-
-#endif
diff --git a/drivers/block/sata_mv.c b/drivers/block/sata_mv.c
deleted file mode 100644 (file)
index 78e3da4..0000000
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright (C) Excito Elektronik i Skåne AB, 2010.
- * Author: Tor Krill <tor@excito.com>
- *
- * Copyright (C) 2015 Stefan Roese <sr@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-/*
- * This driver supports the SATA controller of some Mavell SoC's.
- * Here a (most likely incomplete) list of the supported SoC's:
- * - Kirkwood
- * - Armada 370
- * - Armada XP
- *
- * This driver implementation is an alternative to the already available
- * driver via the "ide" commands interface (drivers/block/mvsata_ide.c).
- * But this driver only supports PIO mode and as this new driver also
- * supports transfer via DMA, its much faster.
- *
- * Please note, that the newer SoC's (e.g. Armada 38x) are not supported
- * by this driver. As they have an AHCI compatible SATA controller
- * integrated.
- */
-
-/*
- * TODO:
- * Better error recovery
- * No support for using PRDs (Thus max 64KB transfers)
- * No NCQ support
- * No port multiplier support
- */
-
-#include <common.h>
-#include <fis.h>
-#include <libata.h>
-#include <malloc.h>
-#include <sata.h>
-#include <linux/errno.h>
-#include <asm/io.h>
-#include <linux/mbus.h>
-
-#if defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
-#define SATAHC_BASE            KW_SATA_BASE
-#else
-#include <asm/arch/soc.h>
-#define SATAHC_BASE            MVEBU_AXP_SATA_BASE
-#endif
-
-#define SATA0_BASE             (SATAHC_BASE + 0x2000)
-#define SATA1_BASE             (SATAHC_BASE + 0x4000)
-
-/* EDMA registers */
-#define EDMA_CFG               0x000
-#define EDMA_CFG_NCQ           (1 << 5)
-#define EDMA_CFG_EQUE          (1 << 9)
-#define EDMA_TIMER             0x004
-#define EDMA_IECR              0x008
-#define EDMA_IEMR              0x00c
-#define EDMA_RQBA_HI           0x010
-#define EDMA_RQIPR             0x014
-#define EDMA_RQIPR_IPMASK      (0x1f << 5)
-#define EDMA_RQIPR_IPSHIFT     5
-#define EDMA_RQOPR             0x018
-#define EDMA_RQOPR_OPMASK      (0x1f << 5)
-#define EDMA_RQOPR_OPSHIFT     5
-#define EDMA_RSBA_HI           0x01c
-#define EDMA_RSIPR             0x020
-#define EDMA_RSIPR_IPMASK      (0x1f << 3)
-#define EDMA_RSIPR_IPSHIFT     3
-#define        EDMA_RSOPR              0x024
-#define EDMA_RSOPR_OPMASK      (0x1f << 3)
-#define EDMA_RSOPR_OPSHIFT     3
-#define EDMA_CMD               0x028
-#define EDMA_CMD_ENEDMA                (0x01 << 0)
-#define EDMA_CMD_DISEDMA       (0x01 << 1)
-#define EDMA_CMD_ATARST                (0x01 << 2)
-#define EDMA_CMD_FREEZE                (0x01 << 4)
-#define EDMA_TEST_CTL          0x02c
-#define EDMA_STATUS            0x030
-#define EDMA_IORTO             0x034
-#define EDMA_CDTR              0x040
-#define EDMA_HLTCND            0x060
-#define EDMA_NTSR              0x094
-
-/* Basic DMA registers */
-#define BDMA_CMD               0x224
-#define BDMA_STATUS            0x228
-#define BDMA_DTLB              0x22c
-#define BDMA_DTHB              0x230
-#define BDMA_DRL               0x234
-#define BDMA_DRH               0x238
-
-/* SATA Interface registers */
-#define SIR_ICFG               0x050
-#define SIR_CFG_GEN2EN         (0x1 << 7)
-#define SIR_PLL_CFG            0x054
-#define SIR_SSTATUS            0x300
-#define SSTATUS_DET_MASK       (0x0f << 0)
-#define SIR_SERROR             0x304
-#define SIR_SCONTROL           0x308
-#define SIR_SCONTROL_DETEN     (0x01 << 0)
-#define SIR_LTMODE             0x30c
-#define SIR_LTMODE_NELBE       (0x01 << 7)
-#define SIR_PHYMODE3           0x310
-#define SIR_PHYMODE4           0x314
-#define SIR_PHYMODE1           0x32c
-#define SIR_PHYMODE2           0x330
-#define SIR_BIST_CTRL          0x334
-#define SIR_BIST_DW1           0x338
-#define SIR_BIST_DW2           0x33c
-#define SIR_SERR_IRQ_MASK      0x340
-#define SIR_SATA_IFCTRL                0x344
-#define SIR_SATA_TESTCTRL      0x348
-#define SIR_SATA_IFSTATUS      0x34c
-#define SIR_VEND_UNIQ          0x35c
-#define SIR_FIS_CFG            0x360
-#define SIR_FIS_IRQ_CAUSE      0x364
-#define SIR_FIS_IRQ_MASK       0x368
-#define SIR_FIS_DWORD0         0x370
-#define SIR_FIS_DWORD1         0x374
-#define SIR_FIS_DWORD2         0x378
-#define SIR_FIS_DWORD3         0x37c
-#define SIR_FIS_DWORD4         0x380
-#define SIR_FIS_DWORD5         0x384
-#define SIR_FIS_DWORD6         0x388
-#define SIR_PHYM9_GEN2         0x398
-#define SIR_PHYM9_GEN1         0x39c
-#define SIR_PHY_CFG            0x3a0
-#define SIR_PHYCTL             0x3a4
-#define SIR_PHYM10             0x3a8
-#define SIR_PHYM12             0x3b0
-
-/* Shadow registers */
-#define        PIO_DATA                0x100
-#define PIO_ERR_FEATURES       0x104
-#define PIO_SECTOR_COUNT       0x108
-#define PIO_LBA_LOW            0x10c
-#define PIO_LBA_MID            0x110
-#define PIO_LBA_HI             0x114
-#define PIO_DEVICE             0x118
-#define PIO_CMD_STATUS         0x11c
-#define PIO_STATUS_ERR         (0x01 << 0)
-#define PIO_STATUS_DRQ         (0x01 << 3)
-#define PIO_STATUS_DF          (0x01 << 5)
-#define PIO_STATUS_DRDY                (0x01 << 6)
-#define PIO_STATUS_BSY         (0x01 << 7)
-#define PIO_CTRL_ALTSTAT       0x120
-
-/* SATAHC arbiter registers */
-#define SATAHC_CFG             0x000
-#define SATAHC_RQOP            0x004
-#define SATAHC_RQIP            0x008
-#define SATAHC_ICT             0x00c
-#define SATAHC_ITT             0x010
-#define SATAHC_ICR             0x014
-#define SATAHC_ICR_PORT0       (0x01 << 0)
-#define SATAHC_ICR_PORT1       (0x01 << 1)
-#define SATAHC_MIC             0x020
-#define SATAHC_MIM             0x024
-#define SATAHC_LED_CFG         0x02c
-
-#define REQUEST_QUEUE_SIZE     32
-#define RESPONSE_QUEUE_SIZE    REQUEST_QUEUE_SIZE
-
-struct crqb {
-       u32 dtb_low;            /* DW0 */
-       u32 dtb_high;           /* DW1 */
-       u32 control_flags;      /* DW2 */
-       u32 drb_count;          /* DW3 */
-       u32 ata_cmd_feat;       /* DW4 */
-       u32 ata_addr;           /* DW5 */
-       u32 ata_addr_exp;       /* DW6 */
-       u32 ata_sect_count;     /* DW7 */
-};
-
-#define CRQB_ALIGN                     0x400
-
-#define CRQB_CNTRLFLAGS_DIR            (0x01 << 0)
-#define CRQB_CNTRLFLAGS_DQTAGMASK      (0x1f << 1)
-#define CRQB_CNTRLFLAGS_DQTAGSHIFT     1
-#define CRQB_CNTRLFLAGS_PMPORTMASK     (0x0f << 12)
-#define CRQB_CNTRLFLAGS_PMPORTSHIFT    12
-#define CRQB_CNTRLFLAGS_PRDMODE                (0x01 << 16)
-#define CRQB_CNTRLFLAGS_HQTAGMASK      (0x1f << 17)
-#define CRQB_CNTRLFLAGS_HQTAGSHIFT     17
-
-#define CRQB_CMDFEAT_CMDMASK           (0xff << 16)
-#define CRQB_CMDFEAT_CMDSHIFT          16
-#define CRQB_CMDFEAT_FEATMASK          (0xff << 16)
-#define CRQB_CMDFEAT_FEATSHIFT         24
-
-#define CRQB_ADDR_LBA_LOWMASK          (0xff << 0)
-#define CRQB_ADDR_LBA_LOWSHIFT         0
-#define CRQB_ADDR_LBA_MIDMASK          (0xff << 8)
-#define CRQB_ADDR_LBA_MIDSHIFT         8
-#define CRQB_ADDR_LBA_HIGHMASK         (0xff << 16)
-#define CRQB_ADDR_LBA_HIGHSHIFT                16
-#define CRQB_ADDR_DEVICE_MASK          (0xff << 24)
-#define CRQB_ADDR_DEVICE_SHIFT         24
-
-#define CRQB_ADDR_LBA_LOW_EXP_MASK     (0xff << 0)
-#define CRQB_ADDR_LBA_LOW_EXP_SHIFT    0
-#define CRQB_ADDR_LBA_MID_EXP_MASK     (0xff << 8)
-#define CRQB_ADDR_LBA_MID_EXP_SHIFT    8
-#define CRQB_ADDR_LBA_HIGH_EXP_MASK    (0xff << 16)
-#define CRQB_ADDR_LBA_HIGH_EXP_SHIFT   16
-#define CRQB_ADDR_FEATURE_EXP_MASK     (0xff << 24)
-#define CRQB_ADDR_FEATURE_EXP_SHIFT    24
-
-#define CRQB_SECTCOUNT_COUNT_MASK      (0xff << 0)
-#define CRQB_SECTCOUNT_COUNT_SHIFT     0
-#define CRQB_SECTCOUNT_COUNT_EXP_MASK  (0xff << 8)
-#define CRQB_SECTCOUNT_COUNT_EXP_SHIFT 8
-
-#define MVSATA_WIN_CONTROL(w)  (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
-#define MVSATA_WIN_BASE(w)     (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
-
-struct eprd {
-       u32 phyaddr_low;
-       u32 bytecount_eot;
-       u32 phyaddr_hi;
-       u32 reserved;
-};
-
-#define EPRD_PHYADDR_MASK      0xfffffffe
-#define EPRD_BYTECOUNT_MASK    0x0000ffff
-#define EPRD_EOT               (0x01 << 31)
-
-struct crpb {
-       u32 id;
-       u32 flags;
-       u32 timestamp;
-};
-
-#define CRPB_ALIGN             0x100
-
-#define READ_CMD               0
-#define WRITE_CMD              1
-
-/*
- * Since we don't use PRDs yet max transfer size
- * is 64KB
- */
-#define MV_ATA_MAX_SECTORS     (65535 / ATA_SECT_SIZE)
-
-/* Keep track if hw is initialized or not */
-static u32 hw_init;
-
-struct mv_priv {
-       char name[12];
-       u32 link;
-       u32 regbase;
-       u32 queue_depth;
-       u16 pio;
-       u16 mwdma;
-       u16 udma;
-
-       void *crqb_alloc;
-       struct crqb *request;
-
-       void *crpb_alloc;
-       struct crpb *response;
-};
-
-static int ata_wait_register(u32 *addr, u32 mask, u32 val, u32 timeout_msec)
-{
-       ulong start;
-
-       start = get_timer(0);
-       do {
-               if ((in_le32(addr) & mask) == val)
-                       return 0;
-       } while (get_timer(start) < timeout_msec);
-
-       return -ETIMEDOUT;
-}
-
-/* Cut from sata_mv in linux kernel */
-static int mv_stop_edma_engine(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       int i;
-
-       /* Disable eDMA. The disable bit auto clears. */
-       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_DISEDMA);
-
-       /* Wait for the chip to confirm eDMA is off. */
-       for (i = 10000; i > 0; i--) {
-               u32 reg = in_le32(priv->regbase + EDMA_CMD);
-               if (!(reg & EDMA_CMD_ENEDMA)) {
-                       debug("EDMA stop on port %d succesful\n", port);
-                       return 0;
-               }
-               udelay(10);
-       }
-       debug("EDMA stop on port %d failed\n", port);
-       return -1;
-}
-
-static int mv_start_edma_engine(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       /* Check preconditions */
-       tmp = in_le32(priv->regbase + SIR_SSTATUS);
-       if ((tmp & SSTATUS_DET_MASK) != 0x03) {
-               printf("Device error on port: %d\n", port);
-               return -1;
-       }
-
-       tmp = in_le32(priv->regbase + PIO_CMD_STATUS);
-       if (tmp & (ATA_BUSY | ATA_DRQ)) {
-               printf("Device not ready on port: %d\n", port);
-               return -1;
-       }
-
-       /* Clear interrupt cause */
-       out_le32(priv->regbase + EDMA_IECR, 0x0);
-
-       tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
-       tmp &= ~(port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1);
-       out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
-
-       /* Configure edma operation */
-       tmp = in_le32(priv->regbase + EDMA_CFG);
-       tmp &= ~EDMA_CFG_NCQ;   /* No NCQ */
-       tmp &= ~EDMA_CFG_EQUE;  /* Dont queue operations */
-       out_le32(priv->regbase + EDMA_CFG, tmp);
-
-       out_le32(priv->regbase + SIR_FIS_IRQ_CAUSE, 0x0);
-
-       /* Configure fis, set all to no-wait for now */
-       out_le32(priv->regbase + SIR_FIS_CFG, 0x0);
-
-       /* Setup request queue */
-       out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
-       out_le32(priv->regbase + EDMA_RQIPR, priv->request);
-       out_le32(priv->regbase + EDMA_RQOPR, 0x0);
-
-       /* Setup response queue */
-       out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
-       out_le32(priv->regbase + EDMA_RSOPR, priv->response);
-       out_le32(priv->regbase + EDMA_RSIPR, 0x0);
-
-       /* Start edma */
-       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ENEDMA);
-
-       return 0;
-}
-
-static int mv_reset_channel(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-
-       /* Make sure edma is stopped  */
-       mv_stop_edma_engine(port);
-
-       out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ATARST);
-       udelay(25);             /* allow reset propagation */
-       out_le32(priv->regbase + EDMA_CMD, 0);
-       mdelay(10);
-
-       return 0;
-}
-
-static void mv_reset_port(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-
-       mv_reset_channel(port);
-
-       out_le32(priv->regbase + EDMA_CMD, 0x0);
-       out_le32(priv->regbase + EDMA_CFG, 0x101f);
-       out_le32(priv->regbase + EDMA_IECR, 0x0);
-       out_le32(priv->regbase + EDMA_IEMR, 0x0);
-       out_le32(priv->regbase + EDMA_RQBA_HI, 0x0);
-       out_le32(priv->regbase + EDMA_RQIPR, 0x0);
-       out_le32(priv->regbase + EDMA_RQOPR, 0x0);
-       out_le32(priv->regbase + EDMA_RSBA_HI, 0x0);
-       out_le32(priv->regbase + EDMA_RSIPR, 0x0);
-       out_le32(priv->regbase + EDMA_RSOPR, 0x0);
-       out_le32(priv->regbase + EDMA_IORTO, 0xfa);
-}
-
-static void mv_reset_one_hc(void)
-{
-       out_le32(SATAHC_BASE + SATAHC_ICT, 0x00);
-       out_le32(SATAHC_BASE + SATAHC_ITT, 0x00);
-       out_le32(SATAHC_BASE + SATAHC_ICR, 0x00);
-}
-
-static int probe_port(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       int tries, tries2, set15 = 0;
-       u32 tmp;
-
-       debug("Probe port: %d\n", port);
-
-       for (tries = 0; tries < 2; tries++) {
-               /* Clear SError */
-               out_le32(priv->regbase + SIR_SERROR, 0x0);
-
-               /* trigger com-init */
-               tmp = in_le32(priv->regbase + SIR_SCONTROL);
-               tmp = (tmp & 0x0f0) | 0x300 | SIR_SCONTROL_DETEN;
-               out_le32(priv->regbase + SIR_SCONTROL, tmp);
-
-               mdelay(1);
-
-               tmp = in_le32(priv->regbase + SIR_SCONTROL);
-               tries2 = 5;
-               do {
-                       tmp = (tmp & 0x0f0) | 0x300;
-                       out_le32(priv->regbase + SIR_SCONTROL, tmp);
-                       mdelay(10);
-                       tmp = in_le32(priv->regbase + SIR_SCONTROL);
-               } while ((tmp & 0xf0f) != 0x300 && tries2--);
-
-               mdelay(10);
-
-               for (tries2 = 0; tries2 < 200; tries2++) {
-                       tmp = in_le32(priv->regbase + SIR_SSTATUS);
-                       if ((tmp & SSTATUS_DET_MASK) == 0x03) {
-                               debug("Found device on port\n");
-                               return 0;
-                       }
-                       mdelay(1);
-               }
-
-               if ((tmp & SSTATUS_DET_MASK) == 0) {
-                       debug("No device attached on port %d\n", port);
-                       return -ENODEV;
-               }
-
-               if (!set15) {
-                       /* Try on 1.5Gb/S */
-                       debug("Try 1.5Gb link\n");
-                       set15 = 1;
-                       out_le32(priv->regbase + SIR_SCONTROL, 0x304);
-
-                       tmp = in_le32(priv->regbase + SIR_ICFG);
-                       tmp &= ~SIR_CFG_GEN2EN;
-                       out_le32(priv->regbase + SIR_ICFG, tmp);
-
-                       mv_reset_channel(port);
-               }
-       }
-
-       debug("Failed to probe port\n");
-       return -1;
-}
-
-/* Get request queue in pointer */
-static int get_reqip(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       tmp = in_le32(priv->regbase + EDMA_RQIPR) & EDMA_RQIPR_IPMASK;
-       tmp = tmp >> EDMA_RQIPR_IPSHIFT;
-
-       return tmp;
-}
-
-static void set_reqip(int port, int reqin)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       tmp = in_le32(priv->regbase + EDMA_RQIPR) & ~EDMA_RQIPR_IPMASK;
-       tmp |= ((reqin << EDMA_RQIPR_IPSHIFT) & EDMA_RQIPR_IPMASK);
-       out_le32(priv->regbase + EDMA_RQIPR, tmp);
-}
-
-/* Get next available slot, ignoring possible overwrite */
-static int get_next_reqip(int port)
-{
-       int slot = get_reqip(port);
-       slot = (slot + 1) % REQUEST_QUEUE_SIZE;
-       return slot;
-}
-
-/* Get response queue in pointer */
-static int get_rspip(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       tmp = in_le32(priv->regbase + EDMA_RSIPR) & EDMA_RSIPR_IPMASK;
-       tmp = tmp >> EDMA_RSIPR_IPSHIFT;
-
-       return tmp;
-}
-
-/* Get response queue out pointer */
-static int get_rspop(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       tmp = in_le32(priv->regbase + EDMA_RSOPR) & EDMA_RSOPR_OPMASK;
-       tmp = tmp >> EDMA_RSOPR_OPSHIFT;
-       return tmp;
-}
-
-/* Get next response queue pointer  */
-static int get_next_rspop(int port)
-{
-       return (get_rspop(port) + 1) % RESPONSE_QUEUE_SIZE;
-}
-
-/* Set response queue pointer */
-static void set_rspop(int port, int reqin)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       u32 tmp;
-
-       tmp = in_le32(priv->regbase + EDMA_RSOPR) & ~EDMA_RSOPR_OPMASK;
-       tmp |= ((reqin << EDMA_RSOPR_OPSHIFT) & EDMA_RSOPR_OPMASK);
-
-       out_le32(priv->regbase + EDMA_RSOPR, tmp);
-}
-
-static int wait_dma_completion(int port, int index, u32 timeout_msec)
-{
-       u32 tmp, res;
-
-       tmp = port == 0 ? SATAHC_ICR_PORT0 : SATAHC_ICR_PORT1;
-       res = ata_wait_register((u32 *)(SATAHC_BASE + SATAHC_ICR), tmp,
-                               tmp, timeout_msec);
-       if (res)
-               printf("Failed to wait for completion on port %d\n", port);
-
-       return res;
-}
-
-static void process_responses(int port)
-{
-#ifdef DEBUG
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-#endif
-       u32 tmp;
-       u32 outind = get_rspop(port);
-
-       /* Ack interrupts */
-       tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
-       if (port == 0)
-               tmp &= ~(BIT(0) | BIT(8));
-       else
-               tmp &= ~(BIT(1) | BIT(9));
-       tmp &= ~(BIT(4));
-       out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
-
-       while (get_rspip(port) != outind) {
-#ifdef DEBUG
-               debug("Response index %d flags %08x on port %d\n", outind,
-                     priv->response[outind].flags, port);
-#endif
-               outind = get_next_rspop(port);
-               set_rspop(port, outind);
-       }
-}
-
-static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
-                              u8 *buffer, u32 len, u32 iswrite)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       struct crqb *req;
-       int slot;
-       u32 start;
-
-       if (len >= 64 * 1024) {
-               printf("We only support <64K transfers for now\n");
-               return -1;
-       }
-
-       /* Initialize request */
-       slot = get_reqip(port);
-       memset(&priv->request[slot], 0, sizeof(struct crqb));
-       req = &priv->request[slot];
-
-       req->dtb_low = (u32)buffer;
-
-       /* Dont use PRDs */
-       req->control_flags = CRQB_CNTRLFLAGS_PRDMODE;
-       req->control_flags |= iswrite ? 0 : CRQB_CNTRLFLAGS_DIR;
-       req->control_flags |=
-           ((cfis->pm_port_c << CRQB_CNTRLFLAGS_PMPORTSHIFT)
-            & CRQB_CNTRLFLAGS_PMPORTMASK);
-
-       req->drb_count = len;
-
-       req->ata_cmd_feat = (cfis->command << CRQB_CMDFEAT_CMDSHIFT) &
-               CRQB_CMDFEAT_CMDMASK;
-       req->ata_cmd_feat |= (cfis->features << CRQB_CMDFEAT_FEATSHIFT) &
-               CRQB_CMDFEAT_FEATMASK;
-
-       req->ata_addr = (cfis->lba_low << CRQB_ADDR_LBA_LOWSHIFT) &
-               CRQB_ADDR_LBA_LOWMASK;
-       req->ata_addr |= (cfis->lba_mid << CRQB_ADDR_LBA_MIDSHIFT) &
-               CRQB_ADDR_LBA_MIDMASK;
-       req->ata_addr |= (cfis->lba_high << CRQB_ADDR_LBA_HIGHSHIFT) &
-               CRQB_ADDR_LBA_HIGHMASK;
-       req->ata_addr |= (cfis->device << CRQB_ADDR_DEVICE_SHIFT) &
-               CRQB_ADDR_DEVICE_MASK;
-
-       req->ata_addr_exp = (cfis->lba_low_exp << CRQB_ADDR_LBA_LOW_EXP_SHIFT) &
-               CRQB_ADDR_LBA_LOW_EXP_MASK;
-       req->ata_addr_exp |=
-               (cfis->lba_mid_exp << CRQB_ADDR_LBA_MID_EXP_SHIFT) &
-               CRQB_ADDR_LBA_MID_EXP_MASK;
-       req->ata_addr_exp |=
-               (cfis->lba_high_exp << CRQB_ADDR_LBA_HIGH_EXP_SHIFT) &
-               CRQB_ADDR_LBA_HIGH_EXP_MASK;
-       req->ata_addr_exp |=
-               (cfis->features_exp << CRQB_ADDR_FEATURE_EXP_SHIFT) &
-               CRQB_ADDR_FEATURE_EXP_MASK;
-
-       req->ata_sect_count =
-               (cfis->sector_count << CRQB_SECTCOUNT_COUNT_SHIFT) &
-               CRQB_SECTCOUNT_COUNT_MASK;
-       req->ata_sect_count |=
-               (cfis->sector_count_exp << CRQB_SECTCOUNT_COUNT_EXP_SHIFT) &
-               CRQB_SECTCOUNT_COUNT_EXP_MASK;
-
-       /* Flush data */
-       start = (u32)req & ~(ARCH_DMA_MINALIGN - 1);
-       flush_dcache_range(start,
-                          start + ALIGN(sizeof(*req), ARCH_DMA_MINALIGN));
-
-       /* Trigger operation */
-       slot = get_next_reqip(port);
-       set_reqip(port, slot);
-
-       /* Wait for completion */
-       if (wait_dma_completion(port, slot, 10000)) {
-               printf("ATA operation timed out\n");
-               return -1;
-       }
-
-       process_responses(port);
-
-       /* Invalidate data on read */
-       if (buffer && len) {
-               start = (u32)buffer & ~(ARCH_DMA_MINALIGN - 1);
-               invalidate_dcache_range(start,
-                                       start + ALIGN(len, ARCH_DMA_MINALIGN));
-       }
-
-       return len;
-}
-
-static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt,
-                             u8 *buffer, int is_write)
-{
-       struct sata_fis_h2d cfis;
-       u32 res;
-       u64 block;
-
-       block = (u64)start;
-
-       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis.command = (is_write) ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
-
-       cfis.lba_high_exp = (block >> 40) & 0xff;
-       cfis.lba_mid_exp = (block >> 32) & 0xff;
-       cfis.lba_low_exp = (block >> 24) & 0xff;
-       cfis.lba_high = (block >> 16) & 0xff;
-       cfis.lba_mid = (block >> 8) & 0xff;
-       cfis.lba_low = block & 0xff;
-       cfis.device = ATA_LBA;
-       cfis.sector_count_exp = (blkcnt >> 8) & 0xff;
-       cfis.sector_count = blkcnt & 0xff;
-
-       res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
-                                 is_write);
-
-       return res >= 0 ? blkcnt : res;
-}
-
-static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer,
-                         int is_write)
-{
-       struct sata_fis_h2d cfis;
-       lbaint_t block;
-       u32 res;
-
-       block = start;
-
-       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis.command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
-       cfis.device = ATA_LBA;
-
-       cfis.device |= (block >> 24) & 0xf;
-       cfis.lba_high = (block >> 16) & 0xff;
-       cfis.lba_mid = (block >> 8) & 0xff;
-       cfis.lba_low = block & 0xff;
-       cfis.sector_count = (u8)(blkcnt & 0xff);
-
-       res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
-                                 is_write);
-
-       return res >= 0 ? blkcnt : res;
-}
-
-static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt,
-                           void *buffer, int is_write)
-{
-       lbaint_t start, blks;
-       u8 *addr;
-       int max_blks;
-
-       debug("%s: %ld %ld\n", __func__, blknr, blkcnt);
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = MV_ATA_MAX_SECTORS;
-       do {
-               if (blks > max_blks) {
-                       if (sata_dev_desc[dev].lba48) {
-                               mv_sata_rw_cmd_ext(dev, start, max_blks, addr,
-                                                  is_write);
-                       } else {
-                               mv_sata_rw_cmd(dev, start, max_blks, addr,
-                                              is_write);
-                       }
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       if (sata_dev_desc[dev].lba48) {
-                               mv_sata_rw_cmd_ext(dev, start, blks, addr,
-                                                  is_write);
-                       } else {
-                               mv_sata_rw_cmd(dev, start, blks, addr,
-                                              is_write);
-                       }
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-static int mv_ata_exec_ata_cmd_nondma(int port,
-                                     struct sata_fis_h2d *cfis, u8 *buffer,
-                                     u32 len, u32 iswrite)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       int i;
-       u16 *tp;
-
-       debug("%s\n", __func__);
-
-       out_le32(priv->regbase + PIO_SECTOR_COUNT, cfis->sector_count);
-       out_le32(priv->regbase + PIO_LBA_HI, cfis->lba_high);
-       out_le32(priv->regbase + PIO_LBA_MID, cfis->lba_mid);
-       out_le32(priv->regbase + PIO_LBA_LOW, cfis->lba_low);
-       out_le32(priv->regbase + PIO_ERR_FEATURES, cfis->features);
-       out_le32(priv->regbase + PIO_DEVICE, cfis->device);
-       out_le32(priv->regbase + PIO_CMD_STATUS, cfis->command);
-
-       if (ata_wait_register((u32 *)(priv->regbase + PIO_CMD_STATUS),
-                             ATA_BUSY, 0x0, 10000)) {
-               debug("Failed to wait for completion\n");
-               return -1;
-       }
-
-       if (len > 0) {
-               tp = (u16 *)buffer;
-               for (i = 0; i < len / 2; i++) {
-                       if (iswrite)
-                               out_le16(priv->regbase + PIO_DATA, *tp++);
-                       else
-                               *tp++ = in_le16(priv->regbase + PIO_DATA);
-               }
-       }
-
-       return len;
-}
-
-static int mv_sata_identify(int port, u16 *id)
-{
-       struct sata_fis_h2d h2d;
-
-       memset(&h2d, 0, sizeof(struct sata_fis_h2d));
-
-       h2d.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       h2d.command = ATA_CMD_ID_ATA;
-
-       /* Give device time to get operational */
-       mdelay(10);
-
-       return mv_ata_exec_ata_cmd_nondma(port, &h2d, (u8 *)id,
-                                         ATA_ID_WORDS * 2, READ_CMD);
-}
-
-static void mv_sata_xfer_mode(int port, u16 *id)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-
-       priv->pio = id[ATA_ID_PIO_MODES];
-       priv->mwdma = id[ATA_ID_MWDMA_MODES];
-       priv->udma = id[ATA_ID_UDMA_MODES];
-       debug("pio %04x, mwdma %04x, udma %04x\n", priv->pio, priv->mwdma,
-             priv->udma);
-}
-
-static void mv_sata_set_features(int port)
-{
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-       struct sata_fis_h2d cfis;
-       u8 udma_cap;
-
-       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis.command = ATA_CMD_SET_FEATURES;
-       cfis.features = SETFEATURES_XFER;
-
-       /* First check the device capablity */
-       udma_cap = (u8) (priv->udma & 0xff);
-
-       if (udma_cap == ATA_UDMA6)
-               cfis.sector_count = XFER_UDMA_6;
-       if (udma_cap == ATA_UDMA5)
-               cfis.sector_count = XFER_UDMA_5;
-       if (udma_cap == ATA_UDMA4)
-               cfis.sector_count = XFER_UDMA_4;
-       if (udma_cap == ATA_UDMA3)
-               cfis.sector_count = XFER_UDMA_3;
-
-       mv_ata_exec_ata_cmd_nondma(port, &cfis, NULL, 0, READ_CMD);
-}
-
-int mv_sata_spin_down(int dev)
-{
-       struct sata_fis_h2d cfis;
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
-
-       if (priv->link == 0) {
-               debug("No device on port: %d\n", dev);
-               return 1;
-       }
-
-       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis.command = ATA_CMD_STANDBY;
-
-       return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
-}
-
-int mv_sata_spin_up(int dev)
-{
-       struct sata_fis_h2d cfis;
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
-
-       if (priv->link == 0) {
-               debug("No device on port: %d\n", dev);
-               return 1;
-       }
-
-       memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
-       cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       cfis.command = ATA_CMD_IDLE;
-
-       return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
-}
-
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       return ata_low_level_rw(dev, blknr, blkcnt, buffer, READ_CMD);
-}
-
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       return ata_low_level_rw(dev, blknr, blkcnt, (void *)buffer, WRITE_CMD);
-}
-
-/*
- * Initialize SATA memory windows
- */
-static void mvsata_ide_conf_mbus_windows(void)
-{
-       const struct mbus_dram_target_info *dram;
-       int i;
-
-       dram = mvebu_mbus_dram_info();
-
-       /* Disable windows, Set Size/Base to 0  */
-       for (i = 0; i < 4; i++) {
-               writel(0, MVSATA_WIN_CONTROL(i));
-               writel(0, MVSATA_WIN_BASE(i));
-       }
-
-       for (i = 0; i < dram->num_cs; i++) {
-               const struct mbus_dram_window *cs = dram->cs + i;
-               writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
-                      (dram->mbus_dram_target_id << 4) | 1,
-                      MVSATA_WIN_CONTROL(i));
-               writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
-       }
-}
-
-int init_sata(int dev)
-{
-       struct mv_priv *priv;
-
-       debug("Initialize sata dev: %d\n", dev);
-
-       if (dev < 0 || dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
-               printf("Invalid sata device %d\n", dev);
-               return -1;
-       }
-
-       priv = (struct mv_priv *)malloc(sizeof(struct mv_priv));
-       if (!priv) {
-               printf("Failed to allocate memory for private sata data\n");
-               return -ENOMEM;
-       }
-
-       memset((void *)priv, 0, sizeof(struct mv_priv));
-
-       /* Allocate and align request buffer */
-       priv->crqb_alloc = malloc(sizeof(struct crqb) * REQUEST_QUEUE_SIZE +
-                                 CRQB_ALIGN);
-       if (!priv->crqb_alloc) {
-               printf("Unable to allocate memory for request queue\n");
-               return -ENOMEM;
-       }
-       memset(priv->crqb_alloc, 0,
-              sizeof(struct crqb) * REQUEST_QUEUE_SIZE + CRQB_ALIGN);
-       priv->request = (struct crqb *)(((u32) priv->crqb_alloc + CRQB_ALIGN) &
-                                       ~(CRQB_ALIGN - 1));
-
-       /* Allocate and align response buffer */
-       priv->crpb_alloc = malloc(sizeof(struct crpb) * REQUEST_QUEUE_SIZE +
-                                 CRPB_ALIGN);
-       if (!priv->crpb_alloc) {
-               printf("Unable to allocate memory for response queue\n");
-               return -ENOMEM;
-       }
-       memset(priv->crpb_alloc, 0,
-              sizeof(struct crpb) * REQUEST_QUEUE_SIZE + CRPB_ALIGN);
-       priv->response = (struct crpb *)(((u32) priv->crpb_alloc + CRPB_ALIGN) &
-                                        ~(CRPB_ALIGN - 1));
-
-       sata_dev_desc[dev].priv = (void *)priv;
-
-       sprintf(priv->name, "SATA%d", dev);
-
-       priv->regbase = dev == 0 ? SATA0_BASE : SATA1_BASE;
-
-       if (!hw_init) {
-               debug("Initialize sata hw\n");
-               hw_init = 1;
-               mv_reset_one_hc();
-               mvsata_ide_conf_mbus_windows();
-       }
-
-       mv_reset_port(dev);
-
-       if (probe_port(dev)) {
-               priv->link = 0;
-               return -ENODEV;
-       }
-       priv->link = 1;
-
-       return 0;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-int scan_sata(int port)
-{
-       unsigned char serial[ATA_ID_SERNO_LEN + 1];
-       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
-       unsigned char product[ATA_ID_PROD_LEN + 1];
-       u64 n_sectors;
-       u16 *id;
-       struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
-
-       if (!priv->link)
-               return -ENODEV;
-
-       id = (u16 *)malloc(ATA_ID_WORDS * 2);
-       if (!id) {
-               printf("Failed to malloc id data\n");
-               return -ENOMEM;
-       }
-
-       mv_sata_identify(port, id);
-       ata_swap_buf_le16(id, ATA_ID_WORDS);
-#ifdef DEBUG
-       ata_dump_id(id);
-#endif
-
-       /* Serial number */
-       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-       memcpy(sata_dev_desc[port].product, serial, sizeof(serial));
-
-       /* Firmware version */
-       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
-       memcpy(sata_dev_desc[port].revision, firmware, sizeof(firmware));
-
-       /* Product model */
-       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
-       memcpy(sata_dev_desc[port].vendor, product, sizeof(product));
-
-       /* Total sectors */
-       n_sectors = ata_id_n_sectors(id);
-       sata_dev_desc[port].lba = n_sectors;
-
-       /* Check if support LBA48 */
-       if (ata_id_has_lba48(id)) {
-               sata_dev_desc[port].lba48 = 1;
-               debug("Device support LBA48\n");
-       }
-
-       /* Get the NCQ queue depth from device */
-       priv->queue_depth = ata_id_queue_depth(id);
-
-       /* Get the xfer mode from device */
-       mv_sata_xfer_mode(port, id);
-
-       /* Set the xfer mode to highest speed */
-       mv_sata_set_features(port);
-
-       /* Start up */
-       mv_start_edma_engine(port);
-
-       return 0;
-}
diff --git a/drivers/block/sata_sandbox.c b/drivers/block/sata_sandbox.c
deleted file mode 100644 (file)
index bd967d2..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-
-int init_sata(int dev)
-{
-       return 0;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-int scan_sata(int dev)
-{
-       return 0;
-}
-
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       return 0;
-}
-
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       return 0;
-}
diff --git a/drivers/block/sata_sil.c b/drivers/block/sata_sil.c
deleted file mode 100644 (file)
index daff7d4..0000000
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
- * Author: Tang Yuantian <b29983@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <pci.h>
-#include <command.h>
-#include <asm/byteorder.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <fis.h>
-#include <sata.h>
-#include <libata.h>
-#include <sata.h>
-#include "sata_sil.h"
-
-/* Convert sectorsize to wordsize */
-#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
-#define virt_to_bus(devno, v)  pci_virt_to_mem(devno, (void *) (v))
-
-static struct sata_info sata_info;
-
-static struct pci_device_id supported[] = {
-       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3131},
-       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3132},
-       {PCI_VENDOR_ID_SILICONIMAGE, PCI_DEVICE_ID_SIL3124},
-       {}
-};
-
-static void sil_sata_dump_fis(struct sata_fis_d2h *s)
-{
-       printf("Status FIS dump:\n");
-       printf("fis_type:               %02x\n", s->fis_type);
-       printf("pm_port_i:              %02x\n", s->pm_port_i);
-       printf("status:                 %02x\n", s->status);
-       printf("error:                  %02x\n", s->error);
-       printf("lba_low:                %02x\n", s->lba_low);
-       printf("lba_mid:                %02x\n", s->lba_mid);
-       printf("lba_high:               %02x\n", s->lba_high);
-       printf("device:                 %02x\n", s->device);
-       printf("lba_low_exp:            %02x\n", s->lba_low_exp);
-       printf("lba_mid_exp:            %02x\n", s->lba_mid_exp);
-       printf("lba_high_exp:           %02x\n", s->lba_high_exp);
-       printf("res1:                   %02x\n", s->res1);
-       printf("sector_count:           %02x\n", s->sector_count);
-       printf("sector_count_exp:       %02x\n", s->sector_count_exp);
-}
-
-static const char *sata_spd_string(unsigned int speed)
-{
-       static const char * const spd_str[] = {
-               "1.5 Gbps",
-               "3.0 Gbps",
-               "6.0 Gbps",
-       };
-
-       if ((speed - 1) > 2)
-               return "<unknown>";
-
-       return spd_str[speed - 1];
-}
-
-static u32 ata_wait_register(void *reg, u32 mask,
-                        u32 val, int timeout_msec)
-{
-       u32 tmp;
-
-       tmp = readl(reg);
-       while ((tmp & mask) == val && timeout_msec > 0) {
-               mdelay(1);
-               timeout_msec--;
-               tmp = readl(reg);
-       }
-
-       return tmp;
-}
-
-static void sil_config_port(void *port)
-{
-       /* configure IRQ WoC */
-       writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
-
-       /* zero error counters. */
-       writew(0x8000, port + PORT_DECODE_ERR_THRESH);
-       writew(0x8000, port + PORT_CRC_ERR_THRESH);
-       writew(0x8000, port + PORT_HSHK_ERR_THRESH);
-       writew(0x0000, port + PORT_DECODE_ERR_CNT);
-       writew(0x0000, port + PORT_CRC_ERR_CNT);
-       writew(0x0000, port + PORT_HSHK_ERR_CNT);
-
-       /* always use 64bit activation */
-       writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
-
-       /* clear port multiplier enable and resume bits */
-       writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
-}
-
-static int sil_init_port(void *port)
-{
-       u32 tmp;
-
-       writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
-       ata_wait_register(port + PORT_CTRL_STAT,
-                         PORT_CS_INIT, PORT_CS_INIT, 100);
-       tmp = ata_wait_register(port + PORT_CTRL_STAT,
-                               PORT_CS_RDY, 0, 100);
-
-       if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
-               return 1;
-
-       return 0;
-}
-
-static void sil_read_fis(int dev, int tag, struct sata_fis_d2h *fis)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       void *port = sata->port;
-       struct sil_prb *prb;
-       int i;
-       u32 *src, *dst;
-
-       prb = port + PORT_LRAM + tag * PORT_LRAM_SLOT_SZ;
-       src = (u32 *)&prb->fis;
-       dst = (u32 *)fis;
-       for (i = 0; i < sizeof(struct sata_fis_h2d); i += 4)
-               *dst++ = readl(src++);
-}
-
-static int sil_exec_cmd(int dev, struct sil_cmd_block *pcmd, int tag)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       void *port = sata->port;
-       u64 paddr = virt_to_bus(sata->devno, pcmd);
-       u32 irq_mask, irq_stat;
-       int rc;
-
-       writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR);
-
-       /* better to add momery barrior here */
-       writel((u32)paddr, port + PORT_CMD_ACTIVATE + tag * 8);
-       writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + tag * 8 + 4);
-
-       irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
-       irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask,
-                       0, 10000);
-
-       /* clear IRQs */
-       writel(irq_mask, port + PORT_IRQ_STAT);
-       irq_stat >>= PORT_IRQ_RAW_SHIFT;
-
-       if (irq_stat & PORT_IRQ_COMPLETE)
-               rc = 0;
-       else {
-               /* force port into known state */
-               sil_init_port(port);
-               if (irq_stat & PORT_IRQ_ERROR)
-                       rc = 1; /* error */
-               else
-                       rc = 2; /* busy */
-       }
-
-       return rc;
-}
-
-static int sil_cmd_set_feature(int dev)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-       struct sata_fis_d2h fis;
-       u8 udma_cap;
-       int ret;
-
-       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       pcmd->prb.fis.command = ATA_CMD_SET_FEATURES;
-       pcmd->prb.fis.features = SETFEATURES_XFER;
-
-       /* First check the device capablity */
-       udma_cap = (u8)(sata->udma & 0xff);
-       debug("udma_cap %02x\n", udma_cap);
-
-       if (udma_cap == ATA_UDMA6)
-               pcmd->prb.fis.sector_count = XFER_UDMA_6;
-       if (udma_cap == ATA_UDMA5)
-               pcmd->prb.fis.sector_count = XFER_UDMA_5;
-       if (udma_cap == ATA_UDMA4)
-               pcmd->prb.fis.sector_count = XFER_UDMA_4;
-       if (udma_cap == ATA_UDMA3)
-               pcmd->prb.fis.sector_count = XFER_UDMA_3;
-
-       ret = sil_exec_cmd(dev, pcmd, 0);
-       if (ret) {
-               sil_read_fis(dev, 0, &fis);
-               printf("Err: exe cmd(0x%x).\n",
-                               readl(sata->port + PORT_SERROR));
-               sil_sata_dump_fis(&fis);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int sil_cmd_identify_device(int dev, u16 *id)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-       struct sata_fis_d2h fis;
-       int ret;
-
-       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
-       pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       pcmd->prb.fis.command = ATA_CMD_ID_ATA;
-       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, id));
-       pcmd->sge.cnt = cpu_to_le32(sizeof(id[0]) * ATA_ID_WORDS);
-       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
-
-       ret = sil_exec_cmd(dev, pcmd, 0);
-       if (ret) {
-               sil_read_fis(dev, 0, &fis);
-               printf("Err: id cmd(0x%x).\n", readl(sata->port + PORT_SERROR));
-               sil_sata_dump_fis(&fis);
-               return 1;
-       }
-       ata_swap_buf_le16(id, ATA_ID_WORDS);
-
-       return 0;
-}
-
-static int sil_cmd_soft_reset(int dev)
-{
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       struct sata_fis_d2h fis;
-       void *port = sata->port;
-       int ret;
-
-       /* put the port into known state */
-       if (sil_init_port(port)) {
-               printf("SRST: port %d not ready\n", dev);
-               return 1;
-       }
-
-       memset((void *)&cmdb, 0, sizeof(struct sil_cmd_block));
-
-       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_SRST);
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = 0xf;
-
-       ret = sil_exec_cmd(dev, &cmdb, 0);
-       if (ret) {
-               sil_read_fis(dev, 0, &fis);
-               printf("SRST cmd error.\n");
-               sil_sata_dump_fis(&fis);
-               return 1;
-       }
-
-       return 0;
-}
-
-static ulong sil_sata_rw_cmd(int dev, ulong start, ulong blkcnt,
-               u8 *buffer, int is_write)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-       struct sata_fis_d2h fis;
-       u64 block;
-       int ret;
-
-       block = (u64)start;
-       memset(pcmd, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       if (is_write) {
-               pcmd->prb.fis.command = ATA_CMD_WRITE;
-               pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
-       } else {
-               pcmd->prb.fis.command = ATA_CMD_READ;
-               pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
-       }
-
-       pcmd->prb.fis.device = ATA_LBA;
-       pcmd->prb.fis.device |= (block >> 24) & 0xf;
-       pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
-       pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
-       pcmd->prb.fis.lba_low = block & 0xff;
-       pcmd->prb.fis.sector_count = (u8)blkcnt & 0xff;
-
-       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
-       pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
-       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
-
-       ret = sil_exec_cmd(dev, pcmd, 0);
-       if (ret) {
-               sil_read_fis(dev, 0, &fis);
-               printf("Err: rw cmd(0x%08x).\n",
-                               readl(sata->port + PORT_SERROR));
-               sil_sata_dump_fis(&fis);
-               return 1;
-       }
-
-       return blkcnt;
-}
-
-static ulong sil_sata_rw_cmd_ext(int dev, ulong start, ulong blkcnt,
-               u8 *buffer, int is_write)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-       struct sata_fis_d2h fis;
-       u64 block;
-       int ret;
-
-       block = (u64)start;
-       memset(pcmd, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.ctrl = cpu_to_le16(PRB_CTRL_PROTOCOL);
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       if (is_write) {
-               pcmd->prb.fis.command = ATA_CMD_WRITE_EXT;
-               pcmd->prb.prot = cpu_to_le16(PRB_PROT_WRITE);
-       } else {
-               pcmd->prb.fis.command = ATA_CMD_READ_EXT;
-               pcmd->prb.prot = cpu_to_le16(PRB_PROT_READ);
-       }
-
-       pcmd->prb.fis.lba_high_exp = (block >> 40) & 0xff;
-       pcmd->prb.fis.lba_mid_exp = (block >> 32) & 0xff;
-       pcmd->prb.fis.lba_low_exp = (block >> 24) & 0xff;
-       pcmd->prb.fis.lba_high = (block >> 16) & 0xff;
-       pcmd->prb.fis.lba_mid = (block >> 8) & 0xff;
-       pcmd->prb.fis.lba_low = block & 0xff;
-       pcmd->prb.fis.device = ATA_LBA;
-       pcmd->prb.fis.sector_count_exp = (blkcnt >> 8) & 0xff;
-       pcmd->prb.fis.sector_count = blkcnt & 0xff;
-
-       pcmd->sge.addr = cpu_to_le64(virt_to_bus(sata->devno, buffer));
-       pcmd->sge.cnt = cpu_to_le32(blkcnt * ATA_SECT_SIZE);
-       pcmd->sge.flags = cpu_to_le32(SGE_TRM);
-
-       ret = sil_exec_cmd(dev, pcmd, 0);
-       if (ret) {
-               sil_read_fis(dev, 0, &fis);
-               printf("Err: rw ext cmd(0x%08x).\n",
-                               readl(sata->port + PORT_SERROR));
-               sil_sata_dump_fis(&fis);
-               return 1;
-       }
-
-       return blkcnt;
-}
-
-static ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt,
-                              const void *buffer, int is_write)
-{
-       ulong start, blks, max_blks;
-       u8 *addr;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS;
-       do {
-               if (blks > max_blks) {
-                       sil_sata_rw_cmd(dev, start, max_blks, addr, is_write);
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       sil_sata_rw_cmd(dev, start, blks, addr, is_write);
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-static ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt,
-                              const void *buffer, int is_write)
-{
-       ulong start, blks, max_blks;
-       u8 *addr;
-
-       start = blknr;
-       blks = blkcnt;
-       addr = (u8 *)buffer;
-
-       max_blks = ATA_MAX_SECTORS_LBA48;
-       do {
-               if (blks > max_blks) {
-                       sil_sata_rw_cmd_ext(dev, start, max_blks,
-                                       addr, is_write);
-                       start += max_blks;
-                       blks -= max_blks;
-                       addr += ATA_SECT_SIZE * max_blks;
-               } else {
-                       sil_sata_rw_cmd_ext(dev, start, blks,
-                                       addr, is_write);
-                       start += blks;
-                       blks = 0;
-                       addr += ATA_SECT_SIZE * blks;
-               }
-       } while (blks != 0);
-
-       return blkcnt;
-}
-
-static void sil_sata_cmd_flush_cache(int dev)
-{
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-
-       memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       pcmd->prb.fis.command = ATA_CMD_FLUSH;
-
-       sil_exec_cmd(dev, pcmd, 0);
-}
-
-static void sil_sata_cmd_flush_cache_ext(int dev)
-{
-       struct sil_cmd_block cmdb, *pcmd = &cmdb;
-
-       memset((void *)pcmd, 0, sizeof(struct sil_cmd_block));
-       pcmd->prb.fis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
-       pcmd->prb.fis.pm_port_c = (1 << 7);
-       pcmd->prb.fis.command = ATA_CMD_FLUSH_EXT;
-
-       sil_exec_cmd(dev, pcmd, 0);
-}
-
-static void sil_sata_init_wcache(int dev, u16 *id)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-
-       if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
-               sata->wcache = 1;
-       if (ata_id_has_flush(id))
-               sata->flush = 1;
-       if (ata_id_has_flush_ext(id))
-               sata->flush_ext = 1;
-}
-
-static int sil_sata_get_wcache(int dev)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-
-       return sata->wcache;
-}
-
-static int sil_sata_get_flush(int dev)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-
-       return sata->flush;
-}
-
-static int sil_sata_get_flush_ext(int dev)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-
-       return sata->flush_ext;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       ulong rc;
-
-       if (sata->lba48)
-               rc = sil_sata_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
-       else
-               rc = sil_sata_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
-
-       return rc;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
-       struct sil_sata *sata = sata_dev_desc[dev].priv;
-       ulong rc;
-
-       if (sata->lba48) {
-               rc = sil_sata_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
-               if (sil_sata_get_wcache(dev) && sil_sata_get_flush_ext(dev))
-                       sil_sata_cmd_flush_cache_ext(dev);
-       } else {
-               rc = sil_sata_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD);
-               if (sil_sata_get_wcache(dev) && sil_sata_get_flush(dev))
-                       sil_sata_cmd_flush_cache(dev);
-       }
-
-       return rc;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-int init_sata(int dev)
-{
-       static int init_done, idx;
-       pci_dev_t devno;
-       u16 word;
-
-       if (init_done == 1 && dev < sata_info.maxport)
-               return 0;
-
-       init_done = 1;
-
-       /* Find PCI device(s) */
-       devno = pci_find_devices(supported, idx++);
-       if (devno == -1)
-               return 1;
-
-       pci_read_config_word(devno, PCI_DEVICE_ID, &word);
-
-       /* get the port count */
-       word &= 0xf;
-
-       sata_info.portbase = sata_info.maxport;
-       sata_info.maxport = sata_info.portbase + word;
-       sata_info.devno = devno;
-
-       /* Read out all BARs */
-       sata_info.iobase[0] = (ulong)pci_map_bar(devno,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       sata_info.iobase[1] = (ulong)pci_map_bar(devno,
-                       PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
-       sata_info.iobase[2] = (ulong)pci_map_bar(devno,
-                       PCI_BASE_ADDRESS_4, PCI_REGION_MEM);
-
-       /* mask out the unused bits */
-       sata_info.iobase[0] &= 0xffffff80;
-       sata_info.iobase[1] &= 0xfffffc00;
-       sata_info.iobase[2] &= 0xffffff80;
-
-       /* Enable Bus Mastering and memory region */
-       pci_write_config_word(devno, PCI_COMMAND,
-                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
-       /* Check if mem accesses and Bus Mastering are enabled. */
-       pci_read_config_word(devno, PCI_COMMAND, &word);
-       if (!(word & PCI_COMMAND_MEMORY) ||
-                       (!(word & PCI_COMMAND_MASTER))) {
-               printf("Error: Can not enable MEM access or Bus Mastering.\n");
-               debug("PCI command: %04x\n", word);
-               return 1;
-       }
-
-       /* GPIO off */
-       writel(0, (void *)(sata_info.iobase[0] + HOST_FLASH_CMD));
-       /* clear global reset & mask interrupts during initialization */
-       writel(0, (void *)(sata_info.iobase[0] + HOST_CTRL));
-
-       return 0;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-/*
- * SATA interface between low level driver and command layer
- */
-int scan_sata(int dev)
-{
-       unsigned char serial[ATA_ID_SERNO_LEN + 1];
-       unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
-       unsigned char product[ATA_ID_PROD_LEN + 1];
-       struct sil_sata *sata;
-       void *port;
-       int cnt;
-       u16 *id;
-       u32 tmp;
-
-       if (dev >= sata_info.maxport) {
-               printf("SATA#%d is not present\n", dev);
-               return 1;
-       }
-
-       printf("SATA#%d\n", dev);
-       port = (void *)sata_info.iobase[1] +
-               PORT_REGS_SIZE * (dev - sata_info.portbase);
-
-       /* Initial PHY setting */
-       writel(0x20c, port + PORT_PHY_CFG);
-
-       /* clear port RST */
-       tmp = readl(port + PORT_CTRL_STAT);
-       if (tmp & PORT_CS_PORT_RST) {
-               writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
-               tmp = ata_wait_register(port + PORT_CTRL_STAT,
-                               PORT_CS_PORT_RST, PORT_CS_PORT_RST, 100);
-               if (tmp & PORT_CS_PORT_RST)
-                       printf("Err: Failed to clear port RST\n");
-       }
-
-       /* Check if device is present */
-       for (cnt = 0; cnt < 100; cnt++) {
-               tmp = readl(port + PORT_SSTATUS);
-               if ((tmp & 0xF) == 0x3)
-                       break;
-               mdelay(1);
-       }
-
-       tmp = readl(port + PORT_SSTATUS);
-       if ((tmp & 0xf) != 0x3) {
-               printf("        (No RDY)\n");
-               return 1;
-       }
-
-       /* Wait for port ready */
-       tmp = ata_wait_register(port + PORT_CTRL_STAT,
-                               PORT_CS_RDY, PORT_CS_RDY, 100);
-       if ((tmp & PORT_CS_RDY) != PORT_CS_RDY) {
-               printf("%d port not ready.\n", dev);
-               return 1;
-       }
-
-       /* configure port */
-       sil_config_port(port);
-
-       /* Reset port */
-       writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
-       readl(port + PORT_CTRL_STAT);
-       tmp = ata_wait_register(port + PORT_CTRL_STAT, PORT_CS_DEV_RST,
-                               PORT_CS_DEV_RST, 100);
-       if (tmp & PORT_CS_DEV_RST) {
-               printf("%d port reset failed.\n", dev);
-               return 1;
-       }
-
-       sata = (struct sil_sata *)malloc(sizeof(struct sil_sata));
-       if (!sata) {
-               printf("%d no memory.\n", dev);
-               return 1;
-       }
-       memset((void *)sata, 0, sizeof(struct sil_sata));
-
-       /* turn on port interrupt */
-       tmp = readl((void *)(sata_info.iobase[0] + HOST_CTRL));
-       tmp |= (1 << (dev - sata_info.portbase));
-       writel(tmp, (void *)(sata_info.iobase[0] + HOST_CTRL));
-
-       /* Save the private struct to block device struct */
-       sata_dev_desc[dev].priv = (void *)sata;
-       sata->port = port;
-       sata->devno = sata_info.devno;
-       sprintf(sata->name, "SATA#%d", dev);
-       sil_cmd_soft_reset(dev);
-       tmp = readl(port + PORT_SSTATUS);
-       tmp = (tmp >> 4) & 0xf;
-       printf("        (%s)\n", sata_spd_string(tmp));
-
-       id = (u16 *)malloc(ATA_ID_WORDS * 2);
-       if (!id) {
-               printf("Id malloc failed\n");
-               free((void *)sata);
-               return 1;
-       }
-       sil_cmd_identify_device(dev, id);
-
-#ifdef CONFIG_LBA48
-       /* Check if support LBA48 */
-       if (ata_id_has_lba48(id)) {
-               sata_dev_desc[dev].lba48 = 1;
-               sata->lba48 = 1;
-               debug("Device supports LBA48\n");
-       } else
-               debug("Device supports LBA28\n");
-#endif
-
-       /* Serial number */
-       ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-       memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
-
-       /* Firmware version */
-       ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
-       memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
-
-       /* Product model */
-       ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
-       memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
-
-       /* Totoal sectors */
-       sata_dev_desc[dev].lba = ata_id_n_sectors(id);
-
-       sil_sata_init_wcache(dev, id);
-       sil_cmd_set_feature(dev);
-
-#ifdef DEBUG
-       sil_cmd_identify_device(dev, id);
-       ata_dump_id(id);
-#endif
-       free((void *)id);
-
-       return 0;
-}
diff --git a/drivers/block/sata_sil.h b/drivers/block/sata_sil.h
deleted file mode 100644 (file)
index 55954ef..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
- * Author: Tang Yuantian <b29983@freescale.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef SATA_SIL3132_H
-#define SATA_SIL3132_H
-
-#define READ_CMD       0
-#define WRITE_CMD      1
-
-/*
- * SATA device driver struct for each dev
- */
-struct sil_sata {
-       char    name[12];
-       void    *port;  /* the port base address */
-       int             lba48;
-       u16             pio;
-       u16             mwdma;
-       u16             udma;
-       pci_dev_t devno;
-       int             wcache;
-       int             flush;
-       int             flush_ext;
-};
-
-/* sata info for each controller */
-struct sata_info {
-       ulong iobase[3];
-       pci_dev_t devno;
-       int portbase;
-       int maxport;
-};
-
-/*
- * Scatter gather entry (SGE),MUST 8 bytes aligned
- */
-struct sil_sge {
-       __le64 addr;
-       __le32 cnt;
-       __le32 flags;
-} __attribute__ ((aligned(8), packed));
-
-/*
- * Port request block, MUST 8 bytes aligned
- */
-struct sil_prb {
-       __le16 ctrl;
-       __le16 prot;
-       __le32 rx_cnt;
-       struct sata_fis_h2d fis;
-} __attribute__ ((aligned(8), packed));
-
-struct sil_cmd_block {
-       struct sil_prb prb;
-       struct sil_sge sge;
-};
-
-enum {
-       HOST_SLOT_STAT          = 0x00, /* 32 bit slot stat * 4 */
-       HOST_CTRL               = 0x40,
-       HOST_IRQ_STAT           = 0x44,
-       HOST_PHY_CFG            = 0x48,
-       HOST_BIST_CTRL          = 0x50,
-       HOST_BIST_PTRN          = 0x54,
-       HOST_BIST_STAT          = 0x58,
-       HOST_MEM_BIST_STAT      = 0x5c,
-       HOST_FLASH_CMD          = 0x70,
-               /* 8 bit regs */
-       HOST_FLASH_DATA         = 0x74,
-       HOST_TRANSITION_DETECT  = 0x75,
-       HOST_GPIO_CTRL          = 0x76,
-       HOST_I2C_ADDR           = 0x78, /* 32 bit */
-       HOST_I2C_DATA           = 0x7c,
-       HOST_I2C_XFER_CNT       = 0x7e,
-       HOST_I2C_CTRL           = 0x7f,
-
-       /* HOST_SLOT_STAT bits */
-       HOST_SSTAT_ATTN         = (1 << 31),
-
-       /* HOST_CTRL bits */
-       HOST_CTRL_M66EN         = (1 << 16), /* M66EN PCI bus signal */
-       HOST_CTRL_TRDY          = (1 << 17), /* latched PCI TRDY */
-       HOST_CTRL_STOP          = (1 << 18), /* latched PCI STOP */
-       HOST_CTRL_DEVSEL        = (1 << 19), /* latched PCI DEVSEL */
-       HOST_CTRL_REQ64         = (1 << 20), /* latched PCI REQ64 */
-       HOST_CTRL_GLOBAL_RST    = (1 << 31), /* global reset */
-
-       /*
-        * Port registers
-        * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
-        */
-       PORT_REGS_SIZE          = 0x2000,
-
-       PORT_LRAM               = 0x0000, /* 31 LRAM slots and PMP regs */
-       PORT_LRAM_SLOT_SZ       = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
-
-       PORT_PMP                = 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
-       PORT_PMP_STATUS         = 0x0000, /* port device status offset */
-       PORT_PMP_QACTIVE        = 0x0004, /* port device QActive offset */
-       PORT_PMP_SIZE           = 0x0008, /* 8 bytes per PMP */
-
-       /* 32 bit regs */
-       PORT_CTRL_STAT          = 0x1000, /* write: ctrl-set, read: stat */
-       PORT_CTRL_CLR           = 0x1004, /* write: ctrl-clear */
-       PORT_IRQ_STAT           = 0x1008, /* high: status, low: interrupt */
-       PORT_IRQ_ENABLE_SET     = 0x1010, /* write: enable-set */
-       PORT_IRQ_ENABLE_CLR     = 0x1014, /* write: enable-clear */
-       PORT_ACTIVATE_UPPER_ADDR = 0x101c,
-       PORT_EXEC_FIFO          = 0x1020, /* command execution fifo */
-       PORT_CMD_ERR            = 0x1024, /* command error number */
-       PORT_FIS_CFG            = 0x1028,
-       PORT_FIFO_THRES         = 0x102c,
-
-       /* 16 bit regs */
-       PORT_DECODE_ERR_CNT     = 0x1040,
-       PORT_DECODE_ERR_THRESH  = 0x1042,
-       PORT_CRC_ERR_CNT        = 0x1044,
-       PORT_CRC_ERR_THRESH     = 0x1046,
-       PORT_HSHK_ERR_CNT       = 0x1048,
-       PORT_HSHK_ERR_THRESH    = 0x104a,
-
-       /* 32 bit regs */
-       PORT_PHY_CFG            = 0x1050,
-       PORT_SLOT_STAT          = 0x1800,
-       PORT_CMD_ACTIVATE       = 0x1c00, /* 64 bit cmd activate * 31 */
-       PORT_CONTEXT            = 0x1e04,
-       PORT_EXEC_DIAG          = 0x1e00, /* 32bit exec diag * 16 */
-       PORT_PSD_DIAG           = 0x1e40, /* 32bit psd diag * 16 */
-       PORT_SCONTROL           = 0x1f00,
-       PORT_SSTATUS            = 0x1f04,
-       PORT_SERROR             = 0x1f08,
-       PORT_SACTIVE            = 0x1f0c,
-
-       /* PORT_CTRL_STAT bits */
-       PORT_CS_PORT_RST        = (1 << 0), /* port reset */
-       PORT_CS_DEV_RST         = (1 << 1), /* device reset */
-       PORT_CS_INIT            = (1 << 2), /* port initialize */
-       PORT_CS_IRQ_WOC         = (1 << 3), /* interrupt write one to clear */
-       PORT_CS_CDB16           = (1 << 5), /* 0=12b cdb, 1=16b cdb */
-       PORT_CS_PMP_RESUME      = (1 << 6), /* PMP resume */
-       PORT_CS_32BIT_ACTV      = (1 << 10), /* 32-bit activation */
-       PORT_CS_PMP_EN          = (1 << 13), /* port multiplier enable */
-       PORT_CS_RDY             = (1 << 31), /* port ready to accept commands */
-
-       /* PORT_IRQ_STAT/ENABLE_SET/CLR */
-       /* bits[11:0] are masked */
-       PORT_IRQ_COMPLETE       = (1 << 0), /* command(s) completed */
-       PORT_IRQ_ERROR          = (1 << 1), /* command execution error */
-       PORT_IRQ_PORTRDY_CHG    = (1 << 2), /* port ready change */
-       PORT_IRQ_PWR_CHG        = (1 << 3), /* power management change */
-       PORT_IRQ_PHYRDY_CHG     = (1 << 4), /* PHY ready change */
-       PORT_IRQ_COMWAKE        = (1 << 5), /* COMWAKE received */
-       PORT_IRQ_UNK_FIS        = (1 << 6), /* unknown FIS received */
-       PORT_IRQ_DEV_XCHG       = (1 << 7), /* device exchanged */
-       PORT_IRQ_8B10B          = (1 << 8), /* 8b/10b decode error threshold */
-       PORT_IRQ_CRC            = (1 << 9), /* CRC error threshold */
-       PORT_IRQ_HANDSHAKE      = (1 << 10), /* handshake error threshold */
-       PORT_IRQ_SDB_NOTIFY     = (1 << 11), /* SDB notify received */
-
-       DEF_PORT_IRQ            = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
-                                 PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG |
-                                 PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_NOTIFY,
-
-       /* bits[27:16] are unmasked (raw) */
-       PORT_IRQ_RAW_SHIFT      = 16,
-       PORT_IRQ_MASKED_MASK    = 0x7ff,
-       PORT_IRQ_RAW_MASK       = (0x7ff << PORT_IRQ_RAW_SHIFT),
-
-       /* ENABLE_SET/CLR specific, intr steering - 2 bit field */
-       PORT_IRQ_STEER_SHIFT    = 30,
-       PORT_IRQ_STEER_MASK     = (3 << PORT_IRQ_STEER_SHIFT),
-
-       /* PORT_CMD_ERR constants */
-       PORT_CERR_DEV           = 1, /* Error bit in D2H Register FIS */
-       PORT_CERR_SDB           = 2, /* Error bit in SDB FIS */
-       PORT_CERR_DATA          = 3, /* Error in data FIS not detected by dev */
-       PORT_CERR_SEND          = 4, /* Initial cmd FIS transmission failure */
-       PORT_CERR_INCONSISTENT  = 5, /* Protocol mismatch */
-       PORT_CERR_DIRECTION     = 6, /* Data direction mismatch */
-       PORT_CERR_UNDERRUN      = 7, /* Ran out of SGEs while writing */
-       PORT_CERR_OVERRUN       = 8, /* Ran out of SGEs while reading */
-
-       /* bits of PRB control field */
-       PRB_CTRL_PROTOCOL       = (1 << 0), /* override def. ATA protocol */
-       PRB_CTRL_PACKET_READ    = (1 << 4), /* PACKET cmd read */
-       PRB_CTRL_PACKET_WRITE   = (1 << 5), /* PACKET cmd write */
-       PRB_CTRL_NIEN           = (1 << 6), /* Mask completion irq */
-       PRB_CTRL_SRST           = (1 << 7), /* Soft reset request (ign BSY?) */
-
-       /* PRB protocol field */
-       PRB_PROT_PACKET         = (1 << 0),
-       PRB_PROT_TCQ            = (1 << 1),
-       PRB_PROT_NCQ            = (1 << 2),
-       PRB_PROT_READ           = (1 << 3),
-       PRB_PROT_WRITE          = (1 << 4),
-       PRB_PROT_TRANSPARENT    = (1 << 5),
-
-       /*
-        * Other constants
-        */
-       SGE_TRM                 = (1 << 31), /* Last SGE in chain */
-       SGE_LNK                 = (1 << 30), /* linked list
-                                               Points to SGT, not SGE */
-       SGE_DRD                 = (1 << 29), /* discard data read (/dev/null)
-                                               data address ignored */
-
-       CMD_ERR         = 0x21,
-};
-
-#endif
diff --git a/drivers/block/sata_sil3114.c b/drivers/block/sata_sil3114.c
deleted file mode 100644 (file)
index 61ffb66..0000000
+++ /dev/null
@@ -1,835 +0,0 @@
-/*
- * Copyright (C) Excito Elektronik i Skåne AB, All rights reserved.
- * Author: Tor Krill <tor@excito.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- *
- * This is a driver for Silicon Image sil3114 sata chip modelled on
- * the ata_piix driver
- */
-
-#include <common.h>
-#include <pci.h>
-#include <command.h>
-#include <config.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <ide.h>
-#include <sata.h>
-#include <libata.h>
-#include "sata_sil3114.h"
-
-/* Convert sectorsize to wordsize */
-#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
-
-/* Forwards */
-u8 sil3114_spin_up (int num);
-u8 sil3114_spin_down (int num);
-static int sata_bus_softreset (int num);
-static void sata_identify (int num, int dev);
-static u8 check_power_mode (int num);
-static void sata_port (struct sata_ioports *ioport);
-static void set_Feature_cmd (int num, int dev);
-static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits,
-                         unsigned int max, u8 usealtstatus);
-static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus);
-static void msleep (int count);
-
-static u32 iobase[6] = { 0, 0, 0, 0, 0, 0};    /* PCI BAR registers for device */
-
-static struct sata_port port[CONFIG_SYS_SATA_MAX_DEVICE];
-
-static void output_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words)
-{
-       while (words--) {
-               __raw_writew (*sect_buf++, (void *)ioaddr->data_addr);
-       }
-}
-
-static int input_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words)
-{
-       while (words--) {
-               *sect_buf++ = __raw_readw ((void *)ioaddr->data_addr);
-       }
-       return 0;
-}
-
-static int sata_bus_softreset (int num)
-{
-       u8 status = 0;
-
-       port[num].dev_mask = 1;
-
-       port[num].ctl_reg = 0x08;       /*Default value of control reg */
-       writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
-       udelay (10);
-       writeb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
-       udelay (10);
-       writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
-
-       /* spec mandates ">= 2ms" before checking status.
-        * We wait 150ms, because that was the magic delay used for
-        * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        */
-       msleep (150);
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300, 0);
-       while ((status & ATA_BUSY)) {
-               msleep (100);
-               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3, 0);
-       }
-
-       if (status & ATA_BUSY) {
-               printf ("ata%u is slow to respond,plz be patient\n", num);
-       }
-
-       while ((status & ATA_BUSY)) {
-               msleep (100);
-               status = sata_chk_status (&port[num].ioaddr, 0);
-       }
-
-       if (status & ATA_BUSY) {
-               printf ("ata%u failed to respond : ", num);
-               printf ("bus reset failed\n");
-               port[num].dev_mask = 0;
-               return 1;
-       }
-       return 0;
-}
-
-static void sata_identify (int num, int dev)
-{
-       u8 cmd = 0, status = 0, devno = num;
-       u16 iobuf[ATA_SECTOR_WORDS];
-       u64 n_sectors = 0;
-
-       memset (iobuf, 0, sizeof (iobuf));
-
-       if (!(port[num].dev_mask & 0x01)) {
-               printf ("dev%d is not present on port#%d\n", dev, num);
-               return;
-       }
-
-       debug ("port=%d dev=%d\n", num, dev);
-
-       status = 0;
-       cmd = ATA_CMD_ID_ATA;   /*Device Identify Command */
-       writeb (cmd, port[num].ioaddr.command_addr);
-       readb (port[num].ioaddr.altstatus_addr);
-       udelay (10);
-
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000, 0);
-       if (status & ATA_ERR) {
-               printf ("\ndevice not responding\n");
-               port[num].dev_mask &= ~0x01;
-               return;
-       }
-
-       input_data (&port[num].ioaddr, iobuf, ATA_SECTOR_WORDS);
-
-       ata_swap_buf_le16 (iobuf, ATA_SECTOR_WORDS);
-
-       debug ("Specific config: %x\n", iobuf[2]);
-
-       /* we require LBA and DMA support (bits 8 & 9 of word 49) */
-       if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) {
-               debug ("ata%u: no dma/lba\n", num);
-       }
-#ifdef DEBUG
-       ata_dump_id (iobuf);
-#endif
-       n_sectors = ata_id_n_sectors (iobuf);
-
-       if (n_sectors == 0) {
-               port[num].dev_mask &= ~0x01;
-               return;
-       }
-       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].revision,
-                        ATA_ID_FW_REV, sizeof (sata_dev_desc[devno].revision));
-       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].vendor,
-                        ATA_ID_PROD, sizeof (sata_dev_desc[devno].vendor));
-       ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].product,
-                        ATA_ID_SERNO, sizeof (sata_dev_desc[devno].product));
-
-       /* TODO - atm we asume harddisk ie not removable */
-       sata_dev_desc[devno].removable = 0;
-
-       sata_dev_desc[devno].lba = (u32) n_sectors;
-       debug("lba=0x%lx\n", sata_dev_desc[devno].lba);
-
-#ifdef CONFIG_LBA48
-       if (iobuf[83] & (1 << 10)) {
-               sata_dev_desc[devno].lba48 = 1;
-       } else {
-               sata_dev_desc[devno].lba48 = 0;
-       }
-#endif
-
-       /* assuming HD */
-       sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
-       sata_dev_desc[devno].blksz = ATA_SECT_SIZE;
-       sata_dev_desc[devno].lun = 0;   /* just to fill something in... */
-}
-
-static void set_Feature_cmd (int num, int dev)
-{
-       u8 status = 0;
-
-       if (!(port[num].dev_mask & 0x01)) {
-               debug ("dev%d is not present on port#%d\n", dev, num);
-               return;
-       }
-
-       writeb (SETFEATURES_XFER, port[num].ioaddr.feature_addr);
-       writeb (XFER_PIO_4, port[num].ioaddr.nsect_addr);
-       writeb (0, port[num].ioaddr.lbal_addr);
-       writeb (0, port[num].ioaddr.lbam_addr);
-       writeb (0, port[num].ioaddr.lbah_addr);
-
-       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
-       writeb (ATA_CMD_SET_FEATURES, port[num].ioaddr.command_addr);
-
-       udelay (50);
-       msleep (150);
-
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0);
-       if ((status & (ATA_BUSY | ATA_ERR))) {
-               printf ("Error  : status 0x%02x\n", status);
-               port[num].dev_mask &= ~0x01;
-       }
-}
-
-u8 sil3114_spin_down (int num)
-{
-       u8 status = 0;
-
-       debug ("Spin down disk\n");
-
-       if (!(port[num].dev_mask & 0x01)) {
-               debug ("Device ata%d is not present\n", num);
-               return 1;
-       }
-
-       if ((status = check_power_mode (num)) == 0x00) {
-               debug ("Already in standby\n");
-               return 0;
-       }
-
-       if (status == 0x01) {
-               printf ("Failed to check power mode on ata%d\n", num);
-               return 1;
-       }
-
-       if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) {
-               printf ("Device ata%d not ready\n", num);
-               return 1;
-       }
-
-       writeb (0x00, port[num].ioaddr.feature_addr);
-
-       writeb (0x00, port[num].ioaddr.nsect_addr);
-       writeb (0x00, port[num].ioaddr.lbal_addr);
-       writeb (0x00, port[num].ioaddr.lbam_addr);
-       writeb (0x00, port[num].ioaddr.lbah_addr);
-
-       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
-       writeb (ATA_CMD_STANDBY, port[num].ioaddr.command_addr);
-
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0);
-       if ((status & (ATA_BUSY | ATA_ERR))) {
-               printf ("Error waiting for disk spin down: status 0x%02x\n",
-                       status);
-               port[num].dev_mask &= ~0x01;
-               return 1;
-       }
-       return 0;
-}
-
-u8 sil3114_spin_up (int num)
-{
-       u8 status = 0;
-
-       debug ("Spin up disk\n");
-
-       if (!(port[num].dev_mask & 0x01)) {
-               debug ("Device ata%d is not present\n", num);
-               return 1;
-       }
-
-       if ((status = check_power_mode (num)) != 0x00) {
-               if (status == 0x01) {
-                       printf ("Failed to check power mode on ata%d\n", num);
-                       return 1;
-               } else {
-                       /* should be up and running already */
-                       return 0;
-               }
-       }
-
-       if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) {
-               printf ("Device ata%d not ready\n", num);
-               return 1;
-       }
-
-       debug ("Stautus of device check: %d\n", status);
-
-       writeb (0x00, port[num].ioaddr.feature_addr);
-
-       writeb (0x00, port[num].ioaddr.nsect_addr);
-       writeb (0x00, port[num].ioaddr.lbal_addr);
-       writeb (0x00, port[num].ioaddr.lbam_addr);
-       writeb (0x00, port[num].ioaddr.lbah_addr);
-
-       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
-       writeb (ATA_CMD_IDLE, port[num].ioaddr.command_addr);
-
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0);
-       if ((status & (ATA_BUSY | ATA_ERR))) {
-               printf ("Error waiting for disk spin up: status 0x%02x\n",
-                       status);
-               port[num].dev_mask &= ~0x01;
-               return 1;
-       }
-
-       /* Wait for disk to enter Active state */
-       do {
-               msleep (10);
-               status = check_power_mode (num);
-       } while ((status == 0x00) || (status == 0x80));
-
-       if (status == 0x01) {
-               printf ("Falied waiting for disk to spin up\n");
-               return 1;
-       }
-
-       return 0;
-}
-
-/* Return value is not the usual here
- * 0x00 - Device stand by
- * 0x01 - Operation failed
- * 0x80 - Device idle
- * 0xff - Device active
-*/
-static u8 check_power_mode (int num)
-{
-       u8 status = 0;
-       u8 res = 0;
-       if (!(port[num].dev_mask & 0x01)) {
-               debug ("Device ata%d is not present\n", num);
-               return 1;
-       }
-
-       if (!(sata_chk_status (&port[num].ioaddr, 0) & ATA_DRDY)) {
-               printf ("Device ata%d not ready\n", num);
-               return 1;
-       }
-
-       writeb (0, port[num].ioaddr.feature_addr);
-       writeb (0, port[num].ioaddr.nsect_addr);
-       writeb (0, port[num].ioaddr.lbal_addr);
-       writeb (0, port[num].ioaddr.lbam_addr);
-       writeb (0, port[num].ioaddr.lbah_addr);
-
-       writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
-       writeb (ATA_CMD_CHK_POWER, port[num].ioaddr.command_addr);
-
-       status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0);
-       if ((status & (ATA_BUSY | ATA_ERR))) {
-               printf
-                   ("Error waiting for check power mode complete  : status 0x%02x\n",
-                    status);
-               port[num].dev_mask &= ~0x01;
-               return 1;
-       }
-       res = readb (port[num].ioaddr.nsect_addr);
-       debug ("Check powermode: %d\n", res);
-       return res;
-
-}
-
-static void sata_port (struct sata_ioports *ioport)
-{
-       ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
-       ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
-       ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
-       ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
-       ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
-       ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
-       ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
-       ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
-       ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
-       ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
-}
-
-static u8 wait_for_irq (int num, unsigned int max)
-{
-
-       u32 port = iobase[5];
-       switch (num) {
-       case 0:
-               port += VND_TF_CNST_CH0;
-               break;
-       case 1:
-               port += VND_TF_CNST_CH1;
-               break;
-       case 2:
-               port += VND_TF_CNST_CH2;
-               break;
-       case 3:
-               port += VND_TF_CNST_CH3;
-               break;
-       default:
-               return 1;
-       }
-
-       do {
-               if (readl (port) & VND_TF_CNST_INTST) {
-                       break;
-               }
-               udelay (1000);
-               max--;
-       } while ((max > 0));
-
-       return (max == 0);
-}
-
-static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits,
-                         unsigned int max, u8 usealtstatus)
-{
-       u8 status;
-
-       do {
-               if (!((status = sata_chk_status (ioaddr, usealtstatus)) & bits)) {
-                       break;
-               }
-               udelay (1000);
-               max--;
-       } while ((status & bits) && (max > 0));
-
-       return status;
-}
-
-static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus)
-{
-       if (!usealtstatus) {
-               return readb (ioaddr->status_addr);
-       } else {
-               return readb (ioaddr->altstatus_addr);
-       }
-}
-
-static void msleep (int count)
-{
-       int i;
-
-       for (i = 0; i < count; i++)
-               udelay (1000);
-}
-
-/* Read up to 255 sectors
- *
- * Returns sectors read
-*/
-static u8 do_one_read (int device, ulong block, u8 blkcnt, u16 * buff,
-                      uchar lba48)
-{
-
-       u8 sr = 0;
-       u8 status;
-       u64 blknr = (u64) block;
-
-       if (!(sata_chk_status (&port[device].ioaddr, 0) & ATA_DRDY)) {
-               printf ("Device ata%d not ready\n", device);
-               return 0;
-       }
-
-       /* Set up transfer */
-#ifdef CONFIG_LBA48
-       if (lba48) {
-               /* write high bits */
-               writeb (0, port[device].ioaddr.nsect_addr);
-               writeb ((blknr >> 24) & 0xFF, port[device].ioaddr.lbal_addr);
-               writeb ((blknr >> 32) & 0xFF, port[device].ioaddr.lbam_addr);
-               writeb ((blknr >> 40) & 0xFF, port[device].ioaddr.lbah_addr);
-       }
-#endif
-       writeb (blkcnt, port[device].ioaddr.nsect_addr);
-       writeb (((blknr) >> 0) & 0xFF, port[device].ioaddr.lbal_addr);
-       writeb ((blknr >> 8) & 0xFF, port[device].ioaddr.lbam_addr);
-       writeb ((blknr >> 16) & 0xFF, port[device].ioaddr.lbah_addr);
-
-#ifdef CONFIG_LBA48
-       if (lba48) {
-               writeb (ATA_LBA, port[device].ioaddr.device_addr);
-               writeb (ATA_CMD_PIO_READ_EXT, port[device].ioaddr.command_addr);
-       } else
-#endif
-       {
-               writeb (ATA_LBA | ((blknr >> 24) & 0xF),
-                       port[device].ioaddr.device_addr);
-               writeb (ATA_CMD_PIO_READ, port[device].ioaddr.command_addr);
-       }
-
-       status = sata_busy_wait (&port[device].ioaddr, ATA_BUSY, 10000, 1);
-
-       if (status & ATA_BUSY) {
-               u8 err = 0;
-
-               printf ("Device %d not responding status %d\n", device, status);
-               err = readb (port[device].ioaddr.error_addr);
-               printf ("Error reg = 0x%x\n", err);
-
-               return (sr);
-       }
-       while (blkcnt--) {
-
-               if (wait_for_irq (device, 500)) {
-                       printf ("ata%u irq failed\n", device);
-                       return sr;
-               }
-
-               status = sata_chk_status (&port[device].ioaddr, 0);
-               if (status & ATA_ERR) {
-                       printf ("ata%u error %d\n", device,
-                               readb (port[device].ioaddr.error_addr));
-                       return sr;
-               }
-               /* Read one sector */
-               input_data (&port[device].ioaddr, buff, ATA_SECTOR_WORDS);
-               buff += ATA_SECTOR_WORDS;
-               sr++;
-
-       }
-       return sr;
-}
-
-ulong sata_read (int device, ulong block, lbaint_t blkcnt, void *buff)
-{
-       ulong n = 0, sread;
-       u16 *buffer = (u16 *) buff;
-       u8 status = 0;
-       u64 blknr = (u64) block;
-       unsigned char lba48 = 0;
-
-#ifdef CONFIG_LBA48
-       if (blknr > 0xfffffff) {
-               if (!sata_dev_desc[device].lba48) {
-                       printf ("Drive doesn't support 48-bit addressing\n");
-                       return 0;
-               }
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-
-       while (blkcnt > 0) {
-
-               if (blkcnt > 255) {
-                       sread = 255;
-               } else {
-                       sread = blkcnt;
-               }
-
-               status = do_one_read (device, blknr, sread, buffer, lba48);
-               if (status != sread) {
-                       printf ("Read failed\n");
-                       return n;
-               }
-
-               blkcnt -= sread;
-               blknr += sread;
-               n += sread;
-               buffer += sread * ATA_SECTOR_WORDS;
-       }
-       return n;
-}
-
-ulong sata_write (int device, ulong block, lbaint_t blkcnt, const void *buff)
-{
-       ulong n = 0;
-       u16 *buffer = (u16 *) buff;
-       unsigned char status = 0, num = 0;
-       u64 blknr = (u64) block;
-#ifdef CONFIG_LBA48
-       unsigned char lba48 = 0;
-
-       if (blknr > 0xfffffff) {
-               if (!sata_dev_desc[device].lba48) {
-                       printf ("Drive doesn't support 48-bit addressing\n");
-                       return 0;
-               }
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-       /*Port Number */
-       num = device;
-
-       while (blkcnt-- > 0) {
-               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500, 0);
-               if (status & ATA_BUSY) {
-                       printf ("ata%u failed to respond\n", port[num].port_no);
-                       return n;
-               }
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       /* write high bits */
-                       writeb (0, port[num].ioaddr.nsect_addr);
-                       writeb ((blknr >> 24) & 0xFF,
-                               port[num].ioaddr.lbal_addr);
-                       writeb ((blknr >> 32) & 0xFF,
-                               port[num].ioaddr.lbam_addr);
-                       writeb ((blknr >> 40) & 0xFF,
-                               port[num].ioaddr.lbah_addr);
-               }
-#endif
-               writeb (1, port[num].ioaddr.nsect_addr);
-               writeb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
-               writeb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
-               writeb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       writeb (ATA_LBA, port[num].ioaddr.device_addr);
-                       writeb (ATA_CMD_PIO_WRITE_EXT, port[num].ioaddr.command_addr);
-               } else
-#endif
-               {
-                       writeb (ATA_LBA | ((blknr >> 24) & 0xF),
-                               port[num].ioaddr.device_addr);
-                       writeb (ATA_CMD_PIO_WRITE, port[num].ioaddr.command_addr);
-               }
-
-               msleep (50);
-               /*may take up to 4 sec */
-               status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000, 0);
-               if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) {
-                       printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
-                               device, (ulong) blknr, status);
-                       return (n);
-               }
-
-               output_data (&port[num].ioaddr, buffer, ATA_SECTOR_WORDS);
-               readb (port[num].ioaddr.altstatus_addr);
-               udelay (50);
-
-               ++n;
-               ++blknr;
-               buffer += ATA_SECTOR_WORDS;
-       }
-       return n;
-}
-
-/* Driver implementation */
-static u8 sil_get_device_cache_line (pci_dev_t pdev)
-{
-       u8 cache_line = 0;
-       pci_read_config_byte (pdev, PCI_CACHE_LINE_SIZE, &cache_line);
-       return cache_line;
-}
-
-int init_sata (int dev)
-{
-       static u8 init_done = 0;
-       static int res = 1;
-       pci_dev_t devno;
-       u8 cls = 0;
-       u16 cmd = 0;
-       u32 sconf = 0;
-
-       if (init_done) {
-               return res;
-       }
-
-       init_done = 1;
-
-       if ((devno = pci_find_device (SIL_VEND_ID, SIL3114_DEVICE_ID, 0)) == -1) {
-               res = 1;
-               return res;
-       }
-
-       /* Read out all BARs, even though we only use MMIO from BAR5 */
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase[0]);
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_1, &iobase[1]);
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_2, &iobase[2]);
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_3, &iobase[3]);
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_4, &iobase[4]);
-       pci_read_config_dword (devno, PCI_BASE_ADDRESS_5, &iobase[5]);
-
-       if ((iobase[0] == 0xFFFFFFFF) || (iobase[1] == 0xFFFFFFFF) ||
-           (iobase[2] == 0xFFFFFFFF) || (iobase[3] == 0xFFFFFFFF) ||
-           (iobase[4] == 0xFFFFFFFF) || (iobase[5] == 0xFFFFFFFF)) {
-               printf ("Error no base addr for SATA controller\n");
-               res = 1;
-               return res;
-       }
-
-       /* mask off unused bits */
-       iobase[0] &= 0xfffffffc;
-       iobase[1] &= 0xfffffff8;
-       iobase[2] &= 0xfffffffc;
-       iobase[3] &= 0xfffffff8;
-       iobase[4] &= 0xfffffff0;
-       iobase[5] &= 0xfffffc00;
-
-       /* from sata_sil in Linux kernel */
-       cls = sil_get_device_cache_line (devno);
-       if (cls) {
-               cls >>= 3;
-               cls++;          /* cls = (line_size/8)+1 */
-               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH0);
-               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH1);
-               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH2);
-               writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH3);
-       } else {
-               printf ("Cache line not set. Driver may not function\n");
-       }
-
-       /* Enable operation */
-       pci_read_config_word (devno, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-       pci_write_config_word (devno, PCI_COMMAND, cmd);
-
-       /* Disable interrupt usage */
-       pci_read_config_dword (devno, VND_SYSCONFSTAT, &sconf);
-       sconf |= (VND_SYSCONFSTAT_CHN_0_INTBLOCK | VND_SYSCONFSTAT_CHN_1_INTBLOCK);
-       pci_write_config_dword (devno, VND_SYSCONFSTAT, sconf);
-
-       res = 0;
-       return res;
-}
-
-int reset_sata(int dev)
-{
-       return 0;
-}
-
-/* Check if device is connected to port */
-int sata_bus_probe (int portno)
-{
-       u32 port = iobase[5];
-       u32 val;
-       switch (portno) {
-       case 0:
-               port += VND_SSTATUS_CH0;
-               break;
-       case 1:
-               port += VND_SSTATUS_CH1;
-               break;
-       case 2:
-               port += VND_SSTATUS_CH2;
-               break;
-       case 3:
-               port += VND_SSTATUS_CH3;
-               break;
-       default:
-               return 0;
-       }
-       val = readl (port);
-       if ((val & SATA_DET_PRES) == SATA_DET_PRES) {
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-int sata_phy_reset (int portno)
-{
-       u32 port = iobase[5];
-       u32 val;
-       switch (portno) {
-       case 0:
-               port += VND_SCONTROL_CH0;
-               break;
-       case 1:
-               port += VND_SCONTROL_CH1;
-               break;
-       case 2:
-               port += VND_SCONTROL_CH2;
-               break;
-       case 3:
-               port += VND_SCONTROL_CH3;
-               break;
-       default:
-               return 0;
-       }
-       val = readl (port);
-       writel (val | SATA_SC_DET_RST, port);
-       msleep (150);
-       writel (val & ~SATA_SC_DET_RST, port);
-       return 0;
-}
-
-int scan_sata (int dev)
-{
-       /* A bit brain dead, but the code has a legacy */
-       switch (dev) {
-       case 0:
-               port[0].port_no = 0;
-               port[0].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH0;
-               port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
-                   (iobase[5] + VND_TF2_CH0) | ATA_PCI_CTL_OFS;
-               port[0].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH0;
-               break;
-#if (CONFIG_SYS_SATA_MAX_DEVICE >= 1)
-       case 1:
-               port[1].port_no = 0;
-               port[1].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH1;
-               port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
-                   (iobase[5] + VND_TF2_CH1) | ATA_PCI_CTL_OFS;
-               port[1].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH1;
-               break;
-#elif (CONFIG_SYS_SATA_MAX_DEVICE >= 2)
-       case 2:
-               port[2].port_no = 0;
-               port[2].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH2;
-               port[2].ioaddr.altstatus_addr = port[2].ioaddr.ctl_addr =
-                   (iobase[5] + VND_TF2_CH2) | ATA_PCI_CTL_OFS;
-               port[2].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH2;
-               break;
-#elif (CONFIG_SYS_SATA_MAX_DEVICE >= 3)
-       case 3:
-               port[3].port_no = 0;
-               port[3].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH3;
-               port[3].ioaddr.altstatus_addr = port[3].ioaddr.ctl_addr =
-                   (iobase[5] + VND_TF2_CH3) | ATA_PCI_CTL_OFS;
-               port[3].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH3;
-               break;
-#endif
-       default:
-               printf ("Tried to scan unknown port: ata%d\n", dev);
-               return 1;
-       }
-
-       /* Initialize other registers */
-       sata_port (&port[dev].ioaddr);
-
-       /* Check for attached device */
-       if (!sata_bus_probe (dev)) {
-               port[dev].port_state = 0;
-               debug ("SATA#%d port is not present\n", dev);
-       } else {
-               debug ("SATA#%d port is present\n", dev);
-               if (sata_bus_softreset (dev)) {
-                       /* soft reset failed, try a hard one */
-                       sata_phy_reset (dev);
-                       if (sata_bus_softreset (dev)) {
-                               port[dev].port_state = 0;
-                       } else {
-                               port[dev].port_state = 1;
-                       }
-               } else {
-                       port[dev].port_state = 1;
-               }
-       }
-       if (port[dev].port_state == 1) {
-               /* Probe device and set xfer mode */
-               sata_identify (dev, 0);
-               set_Feature_cmd (dev, 0);
-       }
-
-       return 0;
-}
diff --git a/drivers/block/sata_sil3114.h b/drivers/block/sata_sil3114.h
deleted file mode 100644 (file)
index 091fca1..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) Excito Elektronik i Skåne AB, All rights reserved.
- * Author: Tor Krill <tor@excito.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef SATA_SIL3114_H
-#define SATA_SIL3114_H
-
-struct sata_ioports {
-       unsigned long cmd_addr;
-       unsigned long data_addr;
-       unsigned long error_addr;
-       unsigned long feature_addr;
-       unsigned long nsect_addr;
-       unsigned long lbal_addr;
-       unsigned long lbam_addr;
-       unsigned long lbah_addr;
-       unsigned long device_addr;
-       unsigned long status_addr;
-       unsigned long command_addr;
-       unsigned long altstatus_addr;
-       unsigned long ctl_addr;
-       unsigned long bmdma_addr;
-       unsigned long scr_addr;
-};
-
-struct sata_port {
-       unsigned char port_no;  /* primary=0, secondary=1       */
-       struct sata_ioports ioaddr;     /* ATA cmd/ctl/dma reg blks     */
-       unsigned char ctl_reg;
-       unsigned char last_ctl;
-       unsigned char port_state;       /* 1-port is available and      */
-       /* 0-port is not available      */
-       unsigned char dev_mask;
-};
-
-/* Missing ata defines */
-#define ATA_CMD_STANDBY                        0xE2
-#define ATA_CMD_STANDBYNOW1            0xE0
-#define ATA_CMD_IDLE                   0xE3
-#define ATA_CMD_IDLEIMMEDIATE  0xE1
-
-/* Defines for SIL3114 chip */
-
-/* PCI defines */
-#define SIL_VEND_ID            0x1095
-#define SIL3114_DEVICE_ID      0x3114
-
-/* some vendor specific registers */
-#define        VND_SYSCONFSTAT 0x88    /* System Configuration Status and Command */
-#define VND_SYSCONFSTAT_CHN_0_INTBLOCK (1<<22)
-#define VND_SYSCONFSTAT_CHN_1_INTBLOCK (1<<23)
-#define VND_SYSCONFSTAT_CHN_2_INTBLOCK (1<<24)
-#define VND_SYSCONFSTAT_CHN_3_INTBLOCK (1<<25)
-
-/* internal registers mapped by BAR5 */
-/* SATA Control*/
-#define VND_SCONTROL_CH0       0x100
-#define VND_SCONTROL_CH1       0x180
-#define VND_SCONTROL_CH2       0x300
-#define VND_SCONTROL_CH3       0x380
-
-#define SATA_SC_IPM_T2P                (1<<16)
-#define SATA_SC_IPM_T2S                (2<<16)
-#define SATA_SC_SPD_1_5                (1<<4)
-#define SATA_SC_SPD_3_0                (2<<4)
-#define SATA_SC_DET_RST                (1)     /* ATA Reset sequence */
-#define SATA_SC_DET_PDIS       (4)     /* PHY Disable */
-
-/* SATA Status */
-#define VND_SSTATUS_CH0                0x104
-#define VND_SSTATUS_CH1                0x184
-#define VND_SSTATUS_CH2                0x304
-#define VND_SSTATUS_CH3                0x384
-
-#define SATA_SS_IPM_ACTIVE     (1<<8)
-#define SATA_SS_IPM_PARTIAL    (2<<8)
-#define SATA_SS_IPM_SLUMBER    (6<<8)
-#define SATA_SS_SPD_1_5                (1<<4)
-#define SATA_SS_SPD_3_0                (2<<4)
-#define SATA_DET_P_NOPHY       (1)     /* Device presence but no PHY connection established */
-#define SATA_DET_PRES          (3)     /* Device presence and active PHY */
-#define SATA_DET_OFFLINE       (4)     /* Device offline or in loopback mode */
-
-/* Task file registers in BAR5 mapping */
-#define VND_TF0_CH0                    0x80
-#define VND_TF0_CH1                    0xc0
-#define VND_TF0_CH2                    0x280
-#define VND_TF0_CH3                    0x2c0
-#define VND_TF1_CH0                    0x88
-#define VND_TF1_CH1                    0xc8
-#define VND_TF1_CH2                    0x288
-#define VND_TF1_CH3                    0x2c8
-#define VND_TF2_CH0                    0x88
-#define VND_TF2_CH1                    0xc8
-#define VND_TF2_CH2                    0x288
-#define VND_TF2_CH3                    0x2c8
-
-#define VND_BMDMA_CH0          0x00
-#define VND_BMDMA_CH1          0x08
-#define VND_BMDMA_CH2          0x200
-#define VND_BMDMA_CH3          0x208
-#define VND_BMDMA2_CH0         0x10
-#define VND_BMDMA2_CH1         0x18
-#define VND_BMDMA2_CH2         0x210
-#define VND_BMDMA2_CH3         0x218
-
-/* FIFO control */
-#define        VND_FIFOCFG_CH0         0x40
-#define        VND_FIFOCFG_CH1         0x44
-#define        VND_FIFOCFG_CH2         0x240
-#define        VND_FIFOCFG_CH3         0x244
-
-/* Task File configuration and status */
-#define VND_TF_CNST_CH0                0xa0
-#define VND_TF_CNST_CH1                0xe0
-#define VND_TF_CNST_CH2                0x2a0
-#define VND_TF_CNST_CH3                0x2e0
-
-#define VND_TF_CNST_BFCMD      (1<<1)
-#define VND_TF_CNST_CHNRST     (1<<2)
-#define VND_TF_CNST_VDMA       (1<<10)
-#define VND_TF_CNST_INTST      (1<<11)
-#define VND_TF_CNST_WDTO       (1<<12)
-#define VND_TF_CNST_WDEN       (1<<13)
-#define VND_TF_CNST_WDIEN      (1<<14)
-
-/* for testing */
-#define VND_SSDR                       0x04c   /* System Software Data Register */
-#define VND_FMACS                      0x050   /* Flash Memory Address control and status */
-
-#endif