From: Tang Yuantian b29...@freescale.com
Add the Silicon Image series PCI Express to
Serial ATA controller support, including Sil3132,
Sil3131 and Sil3124.
The SATA controller can be used to load kernel.
The features list:
- Supports 1-lane 2.5 Gbit/s PCI Express
- Supports one/two/four independent Serial ATA channels
- Supports Serial ATA Generation 2 transfer rate of 3.0 Gbit/s
- Supports LBA28 and LBA48
Signed-off-by: Tang Yuantian b29...@freescale.com
Signed-off-by: Aaron Williams aaron.willi...@cavium.com
Tested-by: Lan Chunhe b25...@freescale.com
---
git tree: git://git.denx.de/u-boot.git
branch: master
Test platform:P1022DS, P4080DS
V3:
- remove __IOMEM
- remove force cast
V2:
- add virt_to_bus to translate address
- fix some issues
drivers/block/Makefile |1 +
drivers/block/sata_sil.c | 723 ++
drivers/block/sata_sil.h | 227 +++
include/pci_ids.h|5 +
4 files changed, 956 insertions(+), 0 deletions(-)
create mode 100644 drivers/block/sata_sil.c
create mode 100644 drivers/block/sata_sil.h
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 2efe981..98560ef 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -36,6 +36,7 @@ COBJS-$(CONFIG_MX51_PATA) += mxc_ata.o
COBJS-$(CONFIG_PATA_BFIN) += pata_bfin.o
COBJS-$(CONFIG_SATA_DWC) += sata_dwc.o
COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
+COBJS-$(CONFIG_SATA_SIL) += sata_sil.o
COBJS-$(CONFIG_IDE_SIL680) += sil680.o
COBJS-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
COBJS-$(CONFIG_SYSTEMACE) += systemace.o
diff --git a/drivers/block/sata_sil.c b/drivers/block/sata_sil.c
new file mode 100644
index 000..9ee4adf
--- /dev/null
+++ b/drivers/block/sata_sil.c
@@ -0,0 +1,723 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Author: Tang Yuantian b29...@freescale.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include common.h
+#include pci.h
+#include command.h
+#include asm/byteorder.h
+#include malloc.h
+#include asm/io.h
+#include fis.h
+#include libata.h
+#include sata_sil.h
+
+/* Convert sectorsize to wordsize */
+#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)
+#define mdelay(n) udelay((n)*1000)
+#define virt_to_bus(devno, v) pci_virt_to_mem(devno, (void *) (v))
+
+static struct sata_info sata_info;
+extern block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
+
+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