summaryrefslogtreecommitdiffstats
path: root/recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch
diff options
context:
space:
mode:
authorOtavio Salvador <otavio@ossystems.com.br>2012-05-18 19:39:18 -0300
committerOtavio Salvador <otavio@ossystems.com.br>2012-05-21 13:15:17 -0300
commite55f64563a09cc9b9179c10d41e48495880fdb1a (patch)
treeb77cc8ed1d11d7f3bcd611c5c0d0350b4929aca9 /recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch
parentc6d3499849227666d149bcb607ead699b853b842 (diff)
downloadmeta-fsl-arm-e55f64563a09cc9b9179c10d41e48495880fdb1a.tar.gz
u-boot: add patches required for i.MX and i.MXS families
This adds the set of patches, that will be included in next u-boot release, on top of 2012.04.01 version. Those fix known issues with supported machines. The patches are managed on branch 'patches-2012.04.01' of https://github.com/Freescale/u-boot-imx repository. Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Diffstat (limited to 'recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch')
-rw-r--r--recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch1372
1 files changed, 1372 insertions, 0 deletions
diff --git a/recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch b/recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch
new file mode 100644
index 0000000..e4e93a6
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch
@@ -0,0 +1,1372 @@
1From 160e7d7c3fbbcbb60ba71eb984f633db26494646 Mon Sep 17 00:00:00 2001
2From: Stefano Babic <sbabic@denx.de>
3Date: Wed, 22 Feb 2012 00:24:39 +0000
4Subject: [PATCH 04/56] SATA: add driver for MX5 / MX6 SOCs
5
6This driver is part of Freescale's LTIB for
7MX5 / MX6.
8
9Signed-off-by: Stefano Babic <sbabic@denx.de>
10Signed-off-by: Terry Lv <r65388@freescale.com>
11CC: Fabio Estevam <fabio.estevam@freescale.com>
12CC: Dirk Behme <dirk.behme@de.bosch.com>
13---
14 drivers/block/Makefile | 1 +
15 drivers/block/dwc_ahsata.c | 969 ++++++++++++++++++++++++++++++++++++++++++++
16 drivers/block/dwc_ahsata.h | 335 +++++++++++++++
17 include/ahci.h | 5 +-
18 4 files changed, 1308 insertions(+), 2 deletions(-)
19 create mode 100644 drivers/block/dwc_ahsata.c
20 create mode 100644 drivers/block/dwc_ahsata.h
21
22diff --git a/drivers/block/Makefile b/drivers/block/Makefile
23index 98560ef..b9c2047 100644
24--- a/drivers/block/Makefile
25+++ b/drivers/block/Makefile
26@@ -27,6 +27,7 @@ LIB := $(obj)libblock.o
27
28 COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
29 COBJS-$(CONFIG_ATA_PIIX) += ata_piix.o
30+COBJS-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
31 COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o
32 COBJS-$(CONFIG_IDE_FTIDE020) += ftide020.o
33 COBJS-$(CONFIG_LIBATA) += libata.o
34diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c
35new file mode 100644
36index 0000000..2703d3d
37--- /dev/null
38+++ b/drivers/block/dwc_ahsata.c
39@@ -0,0 +1,969 @@
40+/*
41+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
42+ * Terry Lv <r65388@freescale.com>
43+ *
44+ * See file CREDITS for list of people who contributed to this
45+ * project.
46+ *
47+ * This program is free software; you can redistribute it and/or
48+ * modify it under the terms of the GNU General Public License as
49+ * published by the Free Software Foundation; either version 2 of
50+ * the License, or (at your option) any later version.
51+ *
52+ * This program is distributed in the hope that it will be useful,
53+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
54+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55+ * GNU General Public License for more details.
56+ *
57+ * You should have received a copy of the GNU General Public License
58+ * along with this program; if not, write to the Free Software
59+ * Foundation, Inc.
60+ *
61+ */
62+
63+#include <libata.h>
64+#include <ahci.h>
65+#include <fis.h>
66+
67+#include <common.h>
68+#include <malloc.h>
69+#include <linux/ctype.h>
70+#include <asm/errno.h>
71+#include <asm/io.h>
72+#include <linux/bitops.h>
73+#include <asm/arch/clock.h>
74+#include "dwc_ahsata.h"
75+
76+struct sata_port_regs {
77+ u32 clb;
78+ u32 clbu;
79+ u32 fb;
80+ u32 fbu;
81+ u32 is;
82+ u32 ie;
83+ u32 cmd;
84+ u32 res1[1];
85+ u32 tfd;
86+ u32 sig;
87+ u32 ssts;
88+ u32 sctl;
89+ u32 serr;
90+ u32 sact;
91+ u32 ci;
92+ u32 sntf;
93+ u32 res2[1];
94+ u32 dmacr;
95+ u32 res3[1];
96+ u32 phycr;
97+ u32 physr;
98+};
99+
100+struct sata_host_regs {
101+ u32 cap;
102+ u32 ghc;
103+ u32 is;
104+ u32 pi;
105+ u32 vs;
106+ u32 ccc_ctl;
107+ u32 ccc_ports;
108+ u32 res1[2];
109+ u32 cap2;
110+ u32 res2[30];
111+ u32 bistafr;
112+ u32 bistcr;
113+ u32 bistfctr;
114+ u32 bistsr;
115+ u32 bistdecr;
116+ u32 res3[2];
117+ u32 oobr;
118+ u32 res4[8];
119+ u32 timer1ms;
120+ u32 res5[1];
121+ u32 gparam1r;
122+ u32 gparam2r;
123+ u32 pparamr;
124+ u32 testr;
125+ u32 versionr;
126+ u32 idr;
127+};
128+
129+#define MAX_DATA_BYTES_PER_SG (4 * 1024 * 1024)
130+#define MAX_BYTES_PER_TRANS (AHCI_MAX_SG * MAX_DATA_BYTES_PER_SG)
131+
132+#define writel_with_flush(a, b) do { writel(a, b); readl(b); } while (0)
133+
134+static int is_ready;
135+
136+static inline u32 ahci_port_base(u32 base, u32 port)
137+{
138+ return base + 0x100 + (port * 0x80);
139+}
140+
141+static int waiting_for_cmd_completed(u8 *offset,
142+ int timeout_msec,
143+ u32 sign)
144+{
145+ int i;
146+ u32 status;
147+
148+ for (i = 0;
149+ ((status = readl(offset)) & sign) && i < timeout_msec;
150+ ++i)
151+ mdelay(1);
152+
153+ return (i < timeout_msec) ? 0 : -1;
154+}
155+
156+static int ahci_setup_oobr(struct ahci_probe_ent *probe_ent,
157+ int clk)
158+{
159+ struct sata_host_regs *host_mmio =
160+ (struct sata_host_regs *)probe_ent->mmio_base;
161+
162+ writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr));
163+ writel(0x02060b14, &(host_mmio->oobr));
164+
165+ return 0;
166+}
167+
168+static int ahci_host_init(struct ahci_probe_ent *probe_ent)
169+{
170+ u32 tmp, cap_save, num_ports;
171+ int i, j, timeout = 1000;
172+ struct sata_port_regs *port_mmio = NULL;
173+ struct sata_host_regs *host_mmio =
174+ (struct sata_host_regs *)probe_ent->mmio_base;
175+ int clk = mxc_get_clock(MXC_SATA_CLK);
176+
177+ cap_save = readl(&(host_mmio->cap));
178+ cap_save |= SATA_HOST_CAP_SSS;
179+
180+ /* global controller reset */
181+ tmp = readl(&(host_mmio->ghc));
182+ if ((tmp & SATA_HOST_GHC_HR) == 0)
183+ writel_with_flush(tmp | SATA_HOST_GHC_HR, &(host_mmio->ghc));
184+
185+ while ((readl(&(host_mmio->ghc)) & SATA_HOST_GHC_HR)
186+ && --timeout)
187+ ;
188+
189+ if (timeout <= 0) {
190+ debug("controller reset failed (0x%x)\n", tmp);
191+ return -1;
192+ }
193+
194+ /* Set timer 1ms */
195+ writel(clk / 1000, &(host_mmio->timer1ms));
196+
197+ ahci_setup_oobr(probe_ent, 0);
198+
199+ writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc));
200+ writel(cap_save, &(host_mmio->cap));
201+ num_ports = (cap_save & SATA_HOST_CAP_NP_MASK) + 1;
202+ writel_with_flush((1 << num_ports) - 1,
203+ &(host_mmio->pi));
204+
205+ /*
206+ * Determine which Ports are implemented by the DWC_ahsata,
207+ * by reading the PI register. This bit map value aids the
208+ * software to determine how many Ports are available and
209+ * which Port registers need to be initialized.
210+ */
211+ probe_ent->cap = readl(&(host_mmio->cap));
212+ probe_ent->port_map = readl(&(host_mmio->pi));
213+
214+ /* Determine how many command slots the HBA supports */
215+ probe_ent->n_ports =
216+ (probe_ent->cap & SATA_HOST_CAP_NP_MASK) + 1;
217+
218+ debug("cap 0x%x port_map 0x%x n_ports %d\n",
219+ probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
220+
221+ for (i = 0; i < probe_ent->n_ports; i++) {
222+ probe_ent->port[i].port_mmio =
223+ ahci_port_base((u32)host_mmio, i);
224+ port_mmio =
225+ (struct sata_port_regs *)probe_ent->port[i].port_mmio;
226+
227+ /* Ensure that the DWC_ahsata is in idle state */
228+ tmp = readl(&(port_mmio->cmd));
229+
230+ /*
231+ * When P#CMD.ST, P#CMD.CR, P#CMD.FRE and P#CMD.FR
232+ * are all cleared, the Port is in an idle state.
233+ */
234+ if (tmp & (SATA_PORT_CMD_CR | SATA_PORT_CMD_FR |
235+ SATA_PORT_CMD_FRE | SATA_PORT_CMD_ST)) {
236+
237+ /*
238+ * System software places a Port into the idle state by
239+ * clearing P#CMD.ST and waiting for P#CMD.CR to return
240+ * 0 when read.
241+ */
242+ tmp &= ~SATA_PORT_CMD_ST;
243+ writel_with_flush(tmp, &(port_mmio->cmd));
244+
245+ /*
246+ * spec says 500 msecs for each bit, so
247+ * this is slightly incorrect.
248+ */
249+ mdelay(500);
250+
251+ timeout = 1000;
252+ while ((readl(&(port_mmio->cmd)) & SATA_PORT_CMD_CR)
253+ && --timeout)
254+ ;
255+
256+ if (timeout <= 0) {
257+ debug("port reset failed (0x%x)\n", tmp);
258+ return -1;
259+ }
260+ }
261+
262+ /* Spin-up device */
263+ tmp = readl(&(port_mmio->cmd));
264+ writel((tmp | SATA_PORT_CMD_SUD), &(port_mmio->cmd));
265+
266+ /* Wait for spin-up to finish */
267+ timeout = 1000;
268+ while (!(readl(&(port_mmio->cmd)) | SATA_PORT_CMD_SUD)
269+ && --timeout)
270+ ;
271+ if (timeout <= 0) {
272+ debug("Spin-Up can't finish!\n");
273+ return -1;
274+ }
275+
276+ for (j = 0; j < 100; ++j) {
277+ mdelay(10);
278+ tmp = readl(&(port_mmio->ssts));
279+ if (((tmp & SATA_PORT_SSTS_DET_MASK) == 0x3) ||
280+ ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x1))
281+ break;
282+ }
283+
284+ /* Wait for COMINIT bit 26 (DIAG_X) in SERR */
285+ timeout = 1000;
286+ while (!(readl(&(port_mmio->serr)) | SATA_PORT_SERR_DIAG_X)
287+ && --timeout)
288+ ;
289+ if (timeout <= 0) {
290+ debug("Can't find DIAG_X set!\n");
291+ return -1;
292+ }
293+
294+ /*
295+ * For each implemented Port, clear the P#SERR
296+ * register, by writing ones to each implemented\
297+ * bit location.
298+ */
299+ tmp = readl(&(port_mmio->serr));
300+ debug("P#SERR 0x%x\n",
301+ tmp);
302+ writel(tmp, &(port_mmio->serr));
303+
304+ /* Ack any pending irq events for this port */
305+ tmp = readl(&(host_mmio->is));
306+ debug("IS 0x%x\n", tmp);
307+ if (tmp)
308+ writel(tmp, &(host_mmio->is));
309+
310+ writel(1 << i, &(host_mmio->is));
311+
312+ /* set irq mask (enables interrupts) */
313+ writel(DEF_PORT_IRQ, &(port_mmio->ie));
314+
315+ /* register linkup ports */
316+ tmp = readl(&(port_mmio->ssts));
317+ debug("Port %d status: 0x%x\n", i, tmp);
318+ if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03)
319+ probe_ent->link_port_map |= (0x01 << i);
320+ }
321+
322+ tmp = readl(&(host_mmio->ghc));
323+ debug("GHC 0x%x\n", tmp);
324+ writel(tmp | SATA_HOST_GHC_IE, &(host_mmio->ghc));
325+ tmp = readl(&(host_mmio->ghc));
326+ debug("GHC 0x%x\n", tmp);
327+
328+ return 0;
329+}
330+
331+static void ahci_print_info(struct ahci_probe_ent *probe_ent)
332+{
333+ struct sata_host_regs *host_mmio =
334+ (struct sata_host_regs *)probe_ent->mmio_base;
335+ u32 vers, cap, impl, speed;
336+ const char *speed_s;
337+ const char *scc_s;
338+
339+ vers = readl(&(host_mmio->vs));
340+ cap = probe_ent->cap;
341+ impl = probe_ent->port_map;
342+
343+ speed = (cap & SATA_HOST_CAP_ISS_MASK)
344+ >> SATA_HOST_CAP_ISS_OFFSET;
345+ if (speed == 1)
346+ speed_s = "1.5";
347+ else if (speed == 2)
348+ speed_s = "3";
349+ else
350+ speed_s = "?";
351+
352+ scc_s = "SATA";
353+
354+ printf("AHCI %02x%02x.%02x%02x "
355+ "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
356+ (vers >> 24) & 0xff,
357+ (vers >> 16) & 0xff,
358+ (vers >> 8) & 0xff,
359+ vers & 0xff,
360+ ((cap >> 8) & 0x1f) + 1,
361+ (cap & 0x1f) + 1,
362+ speed_s,
363+ impl,
364+ scc_s);
365+
366+ printf("flags: "
367+ "%s%s%s%s%s%s"
368+ "%s%s%s%s%s%s%s\n",
369+ cap & (1 << 31) ? "64bit " : "",
370+ cap & (1 << 30) ? "ncq " : "",
371+ cap & (1 << 28) ? "ilck " : "",
372+ cap & (1 << 27) ? "stag " : "",
373+ cap & (1 << 26) ? "pm " : "",
374+ cap & (1 << 25) ? "led " : "",
375+ cap & (1 << 24) ? "clo " : "",
376+ cap & (1 << 19) ? "nz " : "",
377+ cap & (1 << 18) ? "only " : "",
378+ cap & (1 << 17) ? "pmp " : "",
379+ cap & (1 << 15) ? "pio " : "",
380+ cap & (1 << 14) ? "slum " : "",
381+ cap & (1 << 13) ? "part " : "");
382+}
383+
384+static int ahci_init_one(int pdev)
385+{
386+ int rc;
387+ struct ahci_probe_ent *probe_ent = NULL;
388+
389+ probe_ent = malloc(sizeof(struct ahci_probe_ent));
390+ memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
391+ probe_ent->dev = pdev;
392+
393+ probe_ent->host_flags = ATA_FLAG_SATA
394+ | ATA_FLAG_NO_LEGACY
395+ | ATA_FLAG_MMIO
396+ | ATA_FLAG_PIO_DMA
397+ | ATA_FLAG_NO_ATAPI;
398+
399+ probe_ent->mmio_base = CONFIG_DWC_AHSATA_BASE_ADDR;
400+
401+ /* initialize adapter */
402+ rc = ahci_host_init(probe_ent);
403+ if (rc)
404+ goto err_out;
405+
406+ ahci_print_info(probe_ent);
407+
408+ /* Save the private struct to block device struct */
409+ sata_dev_desc[pdev].priv = (void *)probe_ent;
410+
411+ return 0;
412+
413+err_out:
414+ return rc;
415+}
416+
417+static int ahci_fill_sg(struct ahci_probe_ent *probe_ent,
418+ u8 port, unsigned char *buf, int buf_len)
419+{
420+ struct ahci_ioports *pp = &(probe_ent->port[port]);
421+ struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
422+ u32 sg_count, max_bytes;
423+ int i;
424+
425+ max_bytes = MAX_DATA_BYTES_PER_SG;
426+ sg_count = ((buf_len - 1) / max_bytes) + 1;
427+ if (sg_count > AHCI_MAX_SG) {
428+ printf("Error:Too much sg!\n");
429+ return -1;
430+ }
431+
432+ for (i = 0; i < sg_count; i++) {
433+ ahci_sg->addr =
434+ cpu_to_le32((u32)buf + i * max_bytes);
435+ ahci_sg->addr_hi = 0;
436+ ahci_sg->flags_size = cpu_to_le32(0x3fffff &
437+ (buf_len < max_bytes
438+ ? (buf_len - 1)
439+ : (max_bytes - 1)));
440+ ahci_sg++;
441+ buf_len -= max_bytes;
442+ }
443+
444+ return sg_count;
445+}
446+
447+static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts)
448+{
449+ struct ahci_cmd_hdr *cmd_hdr = (struct ahci_cmd_hdr *)(pp->cmd_slot +
450+ AHCI_CMD_SLOT_SZ * cmd_slot);
451+
452+ memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ);
453+ cmd_hdr->opts = cpu_to_le32(opts);
454+ cmd_hdr->status = 0;
455+ cmd_hdr->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
456+ cmd_hdr->tbl_addr_hi = 0;
457+}
458+
459+#define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0)
460+
461+static int ahci_exec_ata_cmd(struct ahci_probe_ent *probe_ent,
462+ u8 port, struct sata_fis_h2d *cfis,
463+ u8 *buf, u32 buf_len, s32 is_write)
464+{
465+ struct ahci_ioports *pp = &(probe_ent->port[port]);
466+ struct sata_port_regs *port_mmio =
467+ (struct sata_port_regs *)pp->port_mmio;
468+ u32 opts;
469+ int sg_count = 0, cmd_slot = 0;
470+
471+ cmd_slot = AHCI_GET_CMD_SLOT(readl(&(port_mmio->ci)));
472+ if (32 == cmd_slot) {
473+ printf("Can't find empty command slot!\n");
474+ return 0;
475+ }
476+
477+ /* Check xfer length */
478+ if (buf_len > MAX_BYTES_PER_TRANS) {
479+ printf("Max transfer length is %dB\n\r",
480+ MAX_BYTES_PER_TRANS);
481+ return 0;
482+ }
483+
484+ memcpy((u8 *)(pp->cmd_tbl), cfis, sizeof(struct sata_fis_h2d));
485+ if (buf && buf_len)
486+ sg_count = ahci_fill_sg(probe_ent, port, buf, buf_len);
487+ opts = (sizeof(struct sata_fis_h2d) >> 2) | (sg_count << 16);
488+ if (is_write)
489+ opts |= 0x40;
490+ ahci_fill_cmd_slot(pp, cmd_slot, opts);
491+
492+ writel_with_flush(1 << cmd_slot, &(port_mmio->ci));
493+
494+ if (waiting_for_cmd_completed((u8 *)&(port_mmio->ci),
495+ 10000, 0x1 << cmd_slot)) {
496+ printf("timeout exit!\n");
497+ return -1;
498+ }
499+ debug("ahci_exec_ata_cmd: %d byte transferred.\n",
500+ pp->cmd_slot->status);
501+
502+ return buf_len;
503+}
504+
505+static void ahci_set_feature(u8 dev, u8 port)
506+{
507+ struct ahci_probe_ent *probe_ent =
508+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
509+ struct sata_fis_h2d h2d, *cfis = &h2d;
510+
511+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
512+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
513+ cfis->pm_port_c = 1 << 7;
514+ cfis->command = ATA_CMD_SET_FEATURES;
515+ cfis->features = SETFEATURES_XFER;
516+ cfis->sector_count = ffs(probe_ent->udma_mask + 1) + 0x3e;
517+
518+ ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD);
519+}
520+
521+static int ahci_port_start(struct ahci_probe_ent *probe_ent,
522+ u8 port)
523+{
524+ struct ahci_ioports *pp = &(probe_ent->port[port]);
525+ struct sata_port_regs *port_mmio =
526+ (struct sata_port_regs *)pp->port_mmio;
527+ u32 port_status;
528+ u32 mem;
529+ int timeout = 10000000;
530+
531+ debug("Enter start port: %d\n", port);
532+ port_status = readl(&(port_mmio->ssts));
533+ debug("Port %d status: %x\n", port, port_status);
534+ if ((port_status & 0xf) != 0x03) {
535+ printf("No Link on this port!\n");
536+ return -1;
537+ }
538+
539+ mem = (u32)malloc(AHCI_PORT_PRIV_DMA_SZ + 1024);
540+ if (!mem) {
541+ free(pp);
542+ printf("No mem for table!\n");
543+ return -ENOMEM;
544+ }
545+
546+ mem = (mem + 0x400) & (~0x3ff); /* Aligned to 1024-bytes */
547+ memset((u8 *)mem, 0, AHCI_PORT_PRIV_DMA_SZ);
548+
549+ /*
550+ * First item in chunk of DMA memory: 32-slot command table,
551+ * 32 bytes each in size
552+ */
553+ pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
554+ debug("cmd_slot = 0x%x\n", (unsigned int) pp->cmd_slot);
555+ mem += (AHCI_CMD_SLOT_SZ * DWC_AHSATA_MAX_CMD_SLOTS);
556+
557+ /*
558+ * Second item: Received-FIS area, 256-Byte aligned
559+ */
560+ pp->rx_fis = mem;
561+ mem += AHCI_RX_FIS_SZ;
562+
563+ /*
564+ * Third item: data area for storing a single command
565+ * and its scatter-gather table
566+ */
567+ pp->cmd_tbl = mem;
568+ debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
569+
570+ mem += AHCI_CMD_TBL_HDR;
571+
572+ writel_with_flush(0x00004444, &(port_mmio->dmacr));
573+ pp->cmd_tbl_sg = (struct ahci_sg *)mem;
574+ writel_with_flush((u32)pp->cmd_slot, &(port_mmio->clb));
575+ writel_with_flush(pp->rx_fis, &(port_mmio->fb));
576+
577+ /* Enable FRE */
578+ writel_with_flush((SATA_PORT_CMD_FRE | readl(&(port_mmio->cmd))),
579+ &(port_mmio->cmd));
580+
581+ /* Wait device ready */
582+ while ((readl(&(port_mmio->tfd)) & (SATA_PORT_TFD_STS_ERR |
583+ SATA_PORT_TFD_STS_DRQ | SATA_PORT_TFD_STS_BSY))
584+ && --timeout)
585+ ;
586+ if (timeout <= 0) {
587+ debug("Device not ready for BSY, DRQ and"
588+ "ERR in TFD!\n");
589+ return -1;
590+ }
591+
592+ writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
593+ PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
594+ PORT_CMD_START, &(port_mmio->cmd));
595+
596+ debug("Exit start port %d\n", port);
597+
598+ return 0;
599+}
600+
601+int init_sata(int dev)
602+{
603+ int i;
604+ u32 linkmap;
605+ struct ahci_probe_ent *probe_ent = NULL;
606+
607+ if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
608+ printf("The sata index %d is out of ranges\n\r", dev);
609+ return -1;
610+ }
611+
612+ ahci_init_one(dev);
613+
614+ probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
615+ linkmap = probe_ent->link_port_map;
616+
617+ if (0 == linkmap) {
618+ printf("No port device detected!\n");
619+ return 1;
620+ }
621+
622+ for (i = 0; i < probe_ent->n_ports; i++) {
623+ if ((linkmap >> i) && ((linkmap >> i) & 0x01)) {
624+ if (ahci_port_start(probe_ent, (u8)i)) {
625+ printf("Can not start port %d\n", i);
626+ return 1;
627+ }
628+ probe_ent->hard_port_no = i;
629+ break;
630+ }
631+ }
632+
633+ return 0;
634+}
635+
636+static void dwc_ahsata_print_info(int dev)
637+{
638+ block_dev_desc_t *pdev = &(sata_dev_desc[dev]);
639+
640+ printf("SATA Device Info:\n\r");
641+#ifdef CONFIG_SYS_64BIT_LBA
642+ printf("S/N: %s\n\rProduct model number: %s\n\r"
643+ "Firmware version: %s\n\rCapacity: %lld sectors\n\r",
644+ pdev->product, pdev->vendor, pdev->revision, pdev->lba);
645+#else
646+ printf("S/N: %s\n\rProduct model number: %s\n\r"
647+ "Firmware version: %s\n\rCapacity: %ld sectors\n\r",
648+ pdev->product, pdev->vendor, pdev->revision, pdev->lba);
649+#endif
650+}
651+
652+static void dwc_ahsata_identify(int dev, u16 *id)
653+{
654+ struct ahci_probe_ent *probe_ent =
655+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
656+ struct sata_fis_h2d h2d, *cfis = &h2d;
657+ u8 port = probe_ent->hard_port_no;
658+
659+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
660+
661+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
662+ cfis->pm_port_c = 0x80; /* is command */
663+ cfis->command = ATA_CMD_ID_ATA;
664+
665+ ahci_exec_ata_cmd(probe_ent, port, cfis,
666+ (u8 *)id, ATA_ID_WORDS * 2, READ_CMD);
667+ ata_swap_buf_le16(id, ATA_ID_WORDS);
668+}
669+
670+static void dwc_ahsata_xfer_mode(int dev, u16 *id)
671+{
672+ struct ahci_probe_ent *probe_ent =
673+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
674+
675+ probe_ent->pio_mask = id[ATA_ID_PIO_MODES];
676+ probe_ent->udma_mask = id[ATA_ID_UDMA_MODES];
677+ debug("pio %04x, udma %04x\n\r",
678+ probe_ent->pio_mask, probe_ent->udma_mask);
679+}
680+
681+static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt,
682+ u8 *buffer, int is_write)
683+{
684+ struct ahci_probe_ent *probe_ent =
685+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
686+ struct sata_fis_h2d h2d, *cfis = &h2d;
687+ u8 port = probe_ent->hard_port_no;
688+ u32 block;
689+
690+ block = start;
691+
692+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
693+
694+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
695+ cfis->pm_port_c = 0x80; /* is command */
696+ cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
697+ cfis->device = ATA_LBA;
698+
699+ cfis->device |= (block >> 24) & 0xf;
700+ cfis->lba_high = (block >> 16) & 0xff;
701+ cfis->lba_mid = (block >> 8) & 0xff;
702+ cfis->lba_low = block & 0xff;
703+ cfis->sector_count = (u8)(blkcnt & 0xff);
704+
705+ if (ahci_exec_ata_cmd(probe_ent, port, cfis,
706+ buffer, ATA_SECT_SIZE * blkcnt, is_write) > 0)
707+ return blkcnt;
708+ else
709+ return 0;
710+}
711+
712+void dwc_ahsata_flush_cache(int dev)
713+{
714+ struct ahci_probe_ent *probe_ent =
715+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
716+ struct sata_fis_h2d h2d, *cfis = &h2d;
717+ u8 port = probe_ent->hard_port_no;
718+
719+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
720+
721+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
722+ cfis->pm_port_c = 0x80; /* is command */
723+ cfis->command = ATA_CMD_FLUSH;
724+
725+ ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
726+}
727+
728+static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt,
729+ u8 *buffer, int is_write)
730+{
731+ struct ahci_probe_ent *probe_ent =
732+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
733+ struct sata_fis_h2d h2d, *cfis = &h2d;
734+ u8 port = probe_ent->hard_port_no;
735+ u64 block;
736+
737+ block = (u64)start;
738+
739+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
740+
741+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
742+ cfis->pm_port_c = 0x80; /* is command */
743+
744+ cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
745+ : ATA_CMD_READ_EXT;
746+
747+ cfis->lba_high_exp = (block >> 40) & 0xff;
748+ cfis->lba_mid_exp = (block >> 32) & 0xff;
749+ cfis->lba_low_exp = (block >> 24) & 0xff;
750+ cfis->lba_high = (block >> 16) & 0xff;
751+ cfis->lba_mid = (block >> 8) & 0xff;
752+ cfis->lba_low = block & 0xff;
753+ cfis->device = ATA_LBA;
754+ cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
755+ cfis->sector_count = blkcnt & 0xff;
756+
757+ if (ahci_exec_ata_cmd(probe_ent, port, cfis, buffer,
758+ ATA_SECT_SIZE * blkcnt, is_write) > 0)
759+ return blkcnt;
760+ else
761+ return 0;
762+}
763+
764+u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt,
765+ u8 *buffer, int is_write)
766+{
767+ struct ahci_probe_ent *probe_ent =
768+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
769+ struct sata_fis_h2d h2d, *cfis = &h2d;
770+ u8 port = probe_ent->hard_port_no;
771+ u64 block;
772+
773+ if (sata_dev_desc[dev].lba48 != 1) {
774+ printf("execute FPDMA command on non-LBA48 hard disk\n\r");
775+ return -1;
776+ }
777+
778+ block = (u64)start;
779+
780+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
781+
782+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
783+ cfis->pm_port_c = 0x80; /* is command */
784+
785+ cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
786+ : ATA_CMD_FPDMA_READ;
787+
788+ cfis->lba_high_exp = (block >> 40) & 0xff;
789+ cfis->lba_mid_exp = (block >> 32) & 0xff;
790+ cfis->lba_low_exp = (block >> 24) & 0xff;
791+ cfis->lba_high = (block >> 16) & 0xff;
792+ cfis->lba_mid = (block >> 8) & 0xff;
793+ cfis->lba_low = block & 0xff;
794+
795+ cfis->device = ATA_LBA;
796+ cfis->features_exp = (blkcnt >> 8) & 0xff;
797+ cfis->features = blkcnt & 0xff;
798+
799+ /* Use the latest queue */
800+ ahci_exec_ata_cmd(probe_ent, port, cfis,
801+ buffer, ATA_SECT_SIZE * blkcnt, is_write);
802+
803+ return blkcnt;
804+}
805+
806+void dwc_ahsata_flush_cache_ext(int dev)
807+{
808+ struct ahci_probe_ent *probe_ent =
809+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
810+ struct sata_fis_h2d h2d, *cfis = &h2d;
811+ u8 port = probe_ent->hard_port_no;
812+
813+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
814+
815+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
816+ cfis->pm_port_c = 0x80; /* is command */
817+ cfis->command = ATA_CMD_FLUSH_EXT;
818+
819+ ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0);
820+}
821+
822+static void dwc_ahsata_init_wcache(int dev, u16 *id)
823+{
824+ struct ahci_probe_ent *probe_ent =
825+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
826+
827+ if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
828+ probe_ent->flags |= SATA_FLAG_WCACHE;
829+ if (ata_id_has_flush(id))
830+ probe_ent->flags |= SATA_FLAG_FLUSH;
831+ if (ata_id_has_flush_ext(id))
832+ probe_ent->flags |= SATA_FLAG_FLUSH_EXT;
833+}
834+
835+u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
836+ void *buffer, int is_write)
837+{
838+ u32 start, blks;
839+ u8 *addr;
840+ int max_blks;
841+
842+ start = blknr;
843+ blks = blkcnt;
844+ addr = (u8 *)buffer;
845+
846+ max_blks = ATA_MAX_SECTORS_LBA48;
847+
848+ do {
849+ if (blks > max_blks) {
850+ if (max_blks != dwc_ahsata_rw_cmd_ext(dev, start,
851+ max_blks, addr, is_write))
852+ return 0;
853+ start += max_blks;
854+ blks -= max_blks;
855+ addr += ATA_SECT_SIZE * max_blks;
856+ } else {
857+ if (blks != dwc_ahsata_rw_cmd_ext(dev, start,
858+ blks, addr, is_write))
859+ return 0;
860+ start += blks;
861+ blks = 0;
862+ addr += ATA_SECT_SIZE * blks;
863+ }
864+ } while (blks != 0);
865+
866+ return blkcnt;
867+}
868+
869+u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt,
870+ void *buffer, int is_write)
871+{
872+ u32 start, blks;
873+ u8 *addr;
874+ int max_blks;
875+
876+ start = blknr;
877+ blks = blkcnt;
878+ addr = (u8 *)buffer;
879+
880+ max_blks = ATA_MAX_SECTORS;
881+ do {
882+ if (blks > max_blks) {
883+ if (max_blks != dwc_ahsata_rw_cmd(dev, start,
884+ max_blks, addr, is_write))
885+ return 0;
886+ start += max_blks;
887+ blks -= max_blks;
888+ addr += ATA_SECT_SIZE * max_blks;
889+ } else {
890+ if (blks != dwc_ahsata_rw_cmd(dev, start,
891+ blks, addr, is_write))
892+ return 0;
893+ start += blks;
894+ blks = 0;
895+ addr += ATA_SECT_SIZE * blks;
896+ }
897+ } while (blks != 0);
898+
899+ return blkcnt;
900+}
901+
902+/*
903+ * SATA interface between low level driver and command layer
904+ */
905+ulong sata_read(int dev, unsigned long blknr, lbaint_t blkcnt, void *buffer)
906+{
907+ u32 rc;
908+
909+ if (sata_dev_desc[dev].lba48)
910+ rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
911+ buffer, READ_CMD);
912+ else
913+ rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
914+ buffer, READ_CMD);
915+ return rc;
916+}
917+
918+ulong sata_write(int dev, unsigned long blknr, lbaint_t blkcnt, void *buffer)
919+{
920+ u32 rc;
921+ struct ahci_probe_ent *probe_ent =
922+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
923+ u32 flags = probe_ent->flags;
924+
925+ if (sata_dev_desc[dev].lba48) {
926+ rc = ata_low_level_rw_lba48(dev, blknr, blkcnt,
927+ buffer, WRITE_CMD);
928+ if ((flags & SATA_FLAG_WCACHE) &&
929+ (flags & SATA_FLAG_FLUSH_EXT))
930+ dwc_ahsata_flush_cache_ext(dev);
931+ } else {
932+ rc = ata_low_level_rw_lba28(dev, blknr, blkcnt,
933+ buffer, WRITE_CMD);
934+ if ((flags & SATA_FLAG_WCACHE) &&
935+ (flags & SATA_FLAG_FLUSH))
936+ dwc_ahsata_flush_cache(dev);
937+ }
938+ return rc;
939+}
940+
941+int scan_sata(int dev)
942+{
943+ u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 };
944+ u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 };
945+ u8 product[ATA_ID_PROD_LEN + 1] = { 0 };
946+ u16 *id;
947+ u64 n_sectors;
948+ struct ahci_probe_ent *probe_ent =
949+ (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
950+ u8 port = probe_ent->hard_port_no;
951+ block_dev_desc_t *pdev = &(sata_dev_desc[dev]);
952+
953+ id = (u16 *)malloc(ATA_ID_WORDS * 2);
954+ if (!id) {
955+ printf("id malloc failed\n\r");
956+ return -1;
957+ }
958+
959+ /* Identify device to get information */
960+ dwc_ahsata_identify(dev, id);
961+
962+ /* Serial number */
963+ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
964+ memcpy(pdev->product, serial, sizeof(serial));
965+
966+ /* Firmware version */
967+ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
968+ memcpy(pdev->revision, firmware, sizeof(firmware));
969+
970+ /* Product model */
971+ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
972+ memcpy(pdev->vendor, product, sizeof(product));
973+
974+ /* Totoal sectors */
975+ n_sectors = ata_id_n_sectors(id);
976+ pdev->lba = (u32)n_sectors;
977+
978+ pdev->type = DEV_TYPE_HARDDISK;
979+ pdev->blksz = ATA_SECT_SIZE;
980+ pdev->lun = 0 ;
981+
982+ /* Check if support LBA48 */
983+ if (ata_id_has_lba48(id)) {
984+ pdev->lba48 = 1;
985+ debug("Device support LBA48\n\r");
986+ }
987+
988+ /* Get the NCQ queue depth from device */
989+ probe_ent->flags &= (~SATA_FLAG_Q_DEP_MASK);
990+ probe_ent->flags |= ata_id_queue_depth(id);
991+
992+ /* Get the xfer mode from device */
993+ dwc_ahsata_xfer_mode(dev, id);
994+
995+ /* Get the write cache status from device */
996+ dwc_ahsata_init_wcache(dev, id);
997+
998+ /* Set the xfer mode to highest speed */
999+ ahci_set_feature(dev, port);
1000+
1001+ free((void *)id);
1002+
1003+ dwc_ahsata_print_info(dev);
1004+
1005+ is_ready = 1;
1006+
1007+ return 0;
1008+}
1009diff --git a/drivers/block/dwc_ahsata.h b/drivers/block/dwc_ahsata.h
1010new file mode 100644
1011index 0000000..84860ea
1012--- /dev/null
1013+++ b/drivers/block/dwc_ahsata.h
1014@@ -0,0 +1,335 @@
1015+/*
1016+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
1017+ * Terry Lv <r65388@freescale.com>
1018+ *
1019+ * This program is free software; you can redistribute it and/or
1020+ * modify it under the terms of the GNU General Public License as
1021+ * published by the Free Software Foundation; either version 2 of
1022+ * the License, or (at your option) any later version.
1023+ *
1024+ * This program is distributed in the hope that it will be useful,
1025+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1026+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1027+ * GNU General Public License for more details.
1028+ *
1029+ * You should have received a copy of the GNU General Public License
1030+ * along with this program; if not, write to the Free Software
1031+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
1032+ * MA 02111-1307 USA
1033+ */
1034+
1035+#ifndef __FSL_SATA_H__
1036+#define __FSL_SATA_H__
1037+
1038+#define DWC_AHSATA_MAX_CMD_SLOTS 32
1039+
1040+/* Max host controller numbers */
1041+#define SATA_HC_MAX_NUM 4
1042+/* Max command queue depth per host controller */
1043+#define DWC_AHSATA_HC_MAX_CMD 32
1044+/* Max port number per host controller */
1045+#define SATA_HC_MAX_PORT 16
1046+
1047+/* Generic Host Register */
1048+
1049+/* HBA Capabilities Register */
1050+#define SATA_HOST_CAP_S64A 0x80000000
1051+#define SATA_HOST_CAP_SNCQ 0x40000000
1052+#define SATA_HOST_CAP_SSNTF 0x20000000
1053+#define SATA_HOST_CAP_SMPS 0x10000000
1054+#define SATA_HOST_CAP_SSS 0x08000000
1055+#define SATA_HOST_CAP_SALP 0x04000000
1056+#define SATA_HOST_CAP_SAL 0x02000000
1057+#define SATA_HOST_CAP_SCLO 0x01000000
1058+#define SATA_HOST_CAP_ISS_MASK 0x00f00000
1059+#define SATA_HOST_CAP_ISS_OFFSET 20
1060+#define SATA_HOST_CAP_SNZO 0x00080000
1061+#define SATA_HOST_CAP_SAM 0x00040000
1062+#define SATA_HOST_CAP_SPM 0x00020000
1063+#define SATA_HOST_CAP_PMD 0x00008000
1064+#define SATA_HOST_CAP_SSC 0x00004000
1065+#define SATA_HOST_CAP_PSC 0x00002000
1066+#define SATA_HOST_CAP_NCS 0x00001f00
1067+#define SATA_HOST_CAP_CCCS 0x00000080
1068+#define SATA_HOST_CAP_EMS 0x00000040
1069+#define SATA_HOST_CAP_SXS 0x00000020
1070+#define SATA_HOST_CAP_NP_MASK 0x0000001f
1071+
1072+/* Global HBA Control Register */
1073+#define SATA_HOST_GHC_AE 0x80000000
1074+#define SATA_HOST_GHC_IE 0x00000002
1075+#define SATA_HOST_GHC_HR 0x00000001
1076+
1077+/* Interrupt Status Register */
1078+
1079+/* Ports Implemented Register */
1080+
1081+/* AHCI Version Register */
1082+#define SATA_HOST_VS_MJR_MASK 0xffff0000
1083+#define SATA_HOST_VS_MJR_OFFSET 16
1084+#define SATA_HOST_VS_MJR_MNR 0x0000ffff
1085+
1086+/* Command Completion Coalescing Control */
1087+#define SATA_HOST_CCC_CTL_TV_MASK 0xffff0000
1088+#define SATA_HOST_CCC_CTL_TV_OFFSET 16
1089+#define SATA_HOST_CCC_CTL_CC_MASK 0x0000ff00
1090+#define SATA_HOST_CCC_CTL_CC_OFFSET 8
1091+#define SATA_HOST_CCC_CTL_INT_MASK 0x000000f8
1092+#define SATA_HOST_CCC_CTL_INT_OFFSET 3
1093+#define SATA_HOST_CCC_CTL_EN 0x00000001
1094+
1095+/* Command Completion Coalescing Ports */
1096+
1097+/* HBA Capabilities Extended Register */
1098+#define SATA_HOST_CAP2_APST 0x00000004
1099+
1100+/* BIST Activate FIS Register */
1101+#define SATA_HOST_BISTAFR_NCP_MASK 0x0000ff00
1102+#define SATA_HOST_BISTAFR_NCP_OFFSET 8
1103+#define SATA_HOST_BISTAFR_PD_MASK 0x000000ff
1104+#define SATA_HOST_BISTAFR_PD_OFFSET 0
1105+
1106+/* BIST Control Register */
1107+#define SATA_HOST_BISTCR_FERLB 0x00100000
1108+#define SATA_HOST_BISTCR_TXO 0x00040000
1109+#define SATA_HOST_BISTCR_CNTCLR 0x00020000
1110+#define SATA_HOST_BISTCR_NEALB 0x00010000
1111+#define SATA_HOST_BISTCR_LLC_MASK 0x00000700
1112+#define SATA_HOST_BISTCR_LLC_OFFSET 8
1113+#define SATA_HOST_BISTCR_ERREN 0x00000040
1114+#define SATA_HOST_BISTCR_FLIP 0x00000020
1115+#define SATA_HOST_BISTCR_PV 0x00000010
1116+#define SATA_HOST_BISTCR_PATTERN_MASK 0x0000000f
1117+#define SATA_HOST_BISTCR_PATTERN_OFFSET 0
1118+
1119+/* BIST FIS Count Register */
1120+
1121+/* BIST Status Register */
1122+#define SATA_HOST_BISTSR_FRAMERR_MASK 0x0000ffff
1123+#define SATA_HOST_BISTSR_FRAMERR_OFFSET 0
1124+#define SATA_HOST_BISTSR_BRSTERR_MASK 0x00ff0000
1125+#define SATA_HOST_BISTSR_BRSTERR_OFFSET 16
1126+
1127+/* BIST DWORD Error Count Register */
1128+
1129+/* OOB Register*/
1130+#define SATA_HOST_OOBR_WE 0x80000000
1131+#define SATA_HOST_OOBR_cwMin_MASK 0x7f000000
1132+#define SATA_HOST_OOBR_cwMAX_MASK 0x00ff0000
1133+#define SATA_HOST_OOBR_ciMin_MASK 0x0000ff00
1134+#define SATA_HOST_OOBR_ciMax_MASK 0x000000ff
1135+
1136+/* Timer 1-ms Register */
1137+
1138+/* Global Parameter 1 Register */
1139+#define SATA_HOST_GPARAM1R_ALIGN_M 0x80000000
1140+#define SATA_HOST_GPARAM1R_RX_BUFFER 0x40000000
1141+#define SATA_HOST_GPARAM1R_PHY_DATA_MASK 0x30000000
1142+#define SATA_HOST_GPARAM1R_PHY_RST 0x08000000
1143+#define SATA_HOST_GPARAM1R_PHY_CTRL_MASK 0x07e00000
1144+#define SATA_HOST_GPARAM1R_PHY_STAT_MASK 0x001f8000
1145+#define SATA_HOST_GPARAM1R_LATCH_M 0x00004000
1146+#define SATA_HOST_GPARAM1R_BIST_M 0x00002000
1147+#define SATA_HOST_GPARAM1R_PHY_TYPE 0x00001000
1148+#define SATA_HOST_GPARAM1R_RETURN_ERR 0x00000400
1149+#define SATA_HOST_GPARAM1R_AHB_ENDIAN_MASK 0x00000300
1150+#define SATA_HOST_GPARAM1R_S_HADDR 0X00000080
1151+#define SATA_HOST_GPARAM1R_M_HADDR 0X00000040
1152+
1153+/* Global Parameter 2 Register */
1154+#define SATA_HOST_GPARAM2R_DEV_CP 0x00004000
1155+#define SATA_HOST_GPARAM2R_DEV_MP 0x00002000
1156+#define SATA_HOST_GPARAM2R_DEV_ENCODE_M 0x00001000
1157+#define SATA_HOST_GPARAM2R_RXOOB_CLK_M 0x00000800
1158+#define SATA_HOST_GPARAM2R_RXOOB_M 0x00000400
1159+#define SATA_HOST_GPARAM2R_TX_OOB_M 0x00000200
1160+#define SATA_HOST_GPARAM2R_RXOOB_CLK_MASK 0x000001ff
1161+
1162+/* Port Parameter Register */
1163+#define SATA_HOST_PPARAMR_TX_MEM_M 0x00000200
1164+#define SATA_HOST_PPARAMR_TX_MEM_S 0x00000100
1165+#define SATA_HOST_PPARAMR_RX_MEM_M 0x00000080
1166+#define SATA_HOST_PPARAMR_RX_MEM_S 0x00000040
1167+#define SATA_HOST_PPARAMR_TXFIFO_DEPTH_MASK 0x00000038
1168+#define SATA_HOST_PPARAMR_RXFIFO_DEPTH_MASK 0x00000007
1169+
1170+/* Test Register */
1171+#define SATA_HOST_TESTR_PSEL_MASK 0x00070000
1172+#define SATA_HOST_TESTR_TEST_IF 0x00000001
1173+
1174+/* Port Register Descriptions */
1175+/* Port# Command List Base Address Register */
1176+#define SATA_PORT_CLB_CLB_MASK 0xfffffc00
1177+
1178+/* Port# Command List Base Address Upper 32-Bits Register */
1179+
1180+/* Port# FIS Base Address Register */
1181+#define SATA_PORT_FB_FB_MASK 0xfffffff0
1182+
1183+/* Port# FIS Base Address Upper 32-Bits Register */
1184+
1185+/* Port# Interrupt Status Register */
1186+#define SATA_PORT_IS_CPDS 0x80000000
1187+#define SATA_PORT_IS_TFES 0x40000000
1188+#define SATA_PORT_IS_HBFS 0x20000000
1189+#define SATA_PORT_IS_HBDS 0x10000000
1190+#define SATA_PORT_IS_IFS 0x08000000
1191+#define SATA_PORT_IS_INFS 0x04000000
1192+#define SATA_PORT_IS_OFS 0x01000000
1193+#define SATA_PORT_IS_IPMS 0x00800000
1194+#define SATA_PORT_IS_PRCS 0x00400000
1195+#define SATA_PORT_IS_DMPS 0x00000080
1196+#define SATA_PORT_IS_PCS 0x00000040
1197+#define SATA_PORT_IS_DPS 0x00000020
1198+#define SATA_PORT_IS_UFS 0x00000010
1199+#define SATA_PORT_IS_SDBS 0x00000008
1200+#define SATA_PORT_IS_DSS 0x00000004
1201+#define SATA_PORT_IS_PSS 0x00000002
1202+#define SATA_PORT_IS_DHRS 0x00000001
1203+
1204+/* Port# Interrupt Enable Register */
1205+#define SATA_PORT_IE_CPDE 0x80000000
1206+#define SATA_PORT_IE_TFEE 0x40000000
1207+#define SATA_PORT_IE_HBFE 0x20000000
1208+#define SATA_PORT_IE_HBDE 0x10000000
1209+#define SATA_PORT_IE_IFE 0x08000000
1210+#define SATA_PORT_IE_INFE 0x04000000
1211+#define SATA_PORT_IE_OFE 0x01000000
1212+#define SATA_PORT_IE_IPME 0x00800000
1213+#define SATA_PORT_IE_PRCE 0x00400000
1214+#define SATA_PORT_IE_DMPE 0x00000080
1215+#define SATA_PORT_IE_PCE 0x00000040
1216+#define SATA_PORT_IE_DPE 0x00000020
1217+#define SATA_PORT_IE_UFE 0x00000010
1218+#define SATA_PORT_IE_SDBE 0x00000008
1219+#define SATA_PORT_IE_DSE 0x00000004
1220+#define SATA_PORT_IE_PSE 0x00000002
1221+#define SATA_PORT_IE_DHRE 0x00000001
1222+
1223+/* Port# Command Register */
1224+#define SATA_PORT_CMD_ICC_MASK 0xf0000000
1225+#define SATA_PORT_CMD_ASP 0x08000000
1226+#define SATA_PORT_CMD_ALPE 0x04000000
1227+#define SATA_PORT_CMD_DLAE 0x02000000
1228+#define SATA_PORT_CMD_ATAPI 0x01000000
1229+#define SATA_PORT_CMD_APSTE 0x00800000
1230+#define SATA_PORT_CMD_ESP 0x00200000
1231+#define SATA_PORT_CMD_CPD 0x00100000
1232+#define SATA_PORT_CMD_MPSP 0x00080000
1233+#define SATA_PORT_CMD_HPCP 0x00040000
1234+#define SATA_PORT_CMD_PMA 0x00020000
1235+#define SATA_PORT_CMD_CPS 0x00010000
1236+#define SATA_PORT_CMD_CR 0x00008000
1237+#define SATA_PORT_CMD_FR 0x00004000
1238+#define SATA_PORT_CMD_MPSS 0x00002000
1239+#define SATA_PORT_CMD_CCS_MASK 0x00001f00
1240+#define SATA_PORT_CMD_FRE 0x00000010
1241+#define SATA_PORT_CMD_CLO 0x00000008
1242+#define SATA_PORT_CMD_POD 0x00000004
1243+#define SATA_PORT_CMD_SUD 0x00000002
1244+#define SATA_PORT_CMD_ST 0x00000001
1245+
1246+/* Port# Task File Data Register */
1247+#define SATA_PORT_TFD_ERR_MASK 0x0000ff00
1248+#define SATA_PORT_TFD_STS_MASK 0x000000ff
1249+#define SATA_PORT_TFD_STS_ERR 0x00000001
1250+#define SATA_PORT_TFD_STS_DRQ 0x00000008
1251+#define SATA_PORT_TFD_STS_BSY 0x00000080
1252+
1253+/* Port# Signature Register */
1254+
1255+/* Port# Serial ATA Status {SStatus} Register */
1256+#define SATA_PORT_SSTS_IPM_MASK 0x00000f00
1257+#define SATA_PORT_SSTS_SPD_MASK 0x000000f0
1258+#define SATA_PORT_SSTS_DET_MASK 0x0000000f
1259+
1260+/* Port# Serial ATA Control {SControl} Register */
1261+#define SATA_PORT_SCTL_IPM_MASK 0x00000f00
1262+#define SATA_PORT_SCTL_SPD_MASK 0x000000f0
1263+#define SATA_PORT_SCTL_DET_MASK 0x0000000f
1264+
1265+/* Port# Serial ATA Error {SError} Register */
1266+#define SATA_PORT_SERR_DIAG_X 0x04000000
1267+#define SATA_PORT_SERR_DIAG_F 0x02000000
1268+#define SATA_PORT_SERR_DIAG_T 0x01000000
1269+#define SATA_PORT_SERR_DIAG_S 0x00800000
1270+#define SATA_PORT_SERR_DIAG_H 0x00400000
1271+#define SATA_PORT_SERR_DIAG_C 0x00200000
1272+#define SATA_PORT_SERR_DIAG_D 0x00100000
1273+#define SATA_PORT_SERR_DIAG_B 0x00080000
1274+#define SATA_PORT_SERR_DIAG_W 0x00040000
1275+#define SATA_PORT_SERR_DIAG_I 0x00020000
1276+#define SATA_PORT_SERR_DIAG_N 0x00010000
1277+#define SATA_PORT_SERR_ERR_E 0x00000800
1278+#define SATA_PORT_SERR_ERR_P 0x00000400
1279+#define SATA_PORT_SERR_ERR_C 0x00000200
1280+#define SATA_PORT_SERR_ERR_T 0x00000100
1281+#define SATA_PORT_SERR_ERR_M 0x00000002
1282+#define SATA_PORT_SERR_ERR_I 0x00000001
1283+
1284+/* Port# Serial ATA Active {SActive} Register */
1285+
1286+/* Port# Command Issue Register */
1287+
1288+/* Port# Serial ATA Notification Register */
1289+
1290+/* Port# DMA Control Register */
1291+#define SATA_PORT_DMACR_RXABL_MASK 0x0000f000
1292+#define SATA_PORT_DMACR_TXABL_MASK 0x00000f00
1293+#define SATA_PORT_DMACR_RXTS_MASK 0x000000f0
1294+#define SATA_PORT_DMACR_TXTS_MASK 0x0000000f
1295+
1296+/* Port# PHY Control Register */
1297+
1298+/* Port# PHY Status Register */
1299+
1300+#define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry)
1301+
1302+/* DW0
1303+*/
1304+#define CMD_HDR_DI_CFL_MASK 0x0000001f
1305+#define CMD_HDR_DI_CFL_OFFSET 0
1306+#define CMD_HDR_DI_A 0x00000020
1307+#define CMD_HDR_DI_W 0x00000040
1308+#define CMD_HDR_DI_P 0x00000080
1309+#define CMD_HDR_DI_R 0x00000100
1310+#define CMD_HDR_DI_B 0x00000200
1311+#define CMD_HDR_DI_C 0x00000400
1312+#define CMD_HDR_DI_PMP_MASK 0x0000f000
1313+#define CMD_HDR_DI_PMP_OFFSET 12
1314+#define CMD_HDR_DI_PRDTL 0xffff0000
1315+#define CMD_HDR_DI_PRDTL_OFFSET 16
1316+
1317+/* prde_fis_len
1318+*/
1319+#define CMD_HDR_PRD_ENTRY_SHIFT 16
1320+#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
1321+#define CMD_HDR_FIS_LEN_SHIFT 2
1322+
1323+/* attribute
1324+*/
1325+#define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */
1326+#define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */
1327+/* Snoop enable for all descriptor */
1328+#define CMD_HDR_ATTR_SNOOP 0x00000200
1329+#define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */
1330+#define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */
1331+/* BIST - require the host to enter BIST mode */
1332+#define CMD_HDR_ATTR_BIST 0x00000040
1333+#define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */
1334+#define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */
1335+
1336+#define FLAGS_DMA 0x00000000
1337+#define FLAGS_FPDMA 0x00000001
1338+
1339+#define SATA_FLAG_Q_DEP_MASK 0x0000000f
1340+#define SATA_FLAG_WCACHE 0x00000100
1341+#define SATA_FLAG_FLUSH 0x00000200
1342+#define SATA_FLAG_FLUSH_EXT 0x00000400
1343+
1344+#define READ_CMD 0
1345+#define WRITE_CMD 1
1346+
1347+extern block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
1348+
1349+#endif /* __FSL_SATA_H__ */
1350diff --git a/include/ahci.h b/include/ahci.h
1351index 465ea7f..c4fb9e7 100644
1352--- a/include/ahci.h
1353+++ b/include/ahci.h
1354@@ -30,12 +30,13 @@
1355 #define AHCI_PCI_BAR 0x24
1356 #define AHCI_MAX_SG 56 /* hardware max is 64K */
1357 #define AHCI_CMD_SLOT_SZ 32
1358+#define AHCI_MAX_CMD_SLOT 32
1359 #define AHCI_RX_FIS_SZ 256
1360 #define AHCI_CMD_TBL_HDR 0x80
1361 #define AHCI_CMD_TBL_CDB 0x40
1362 #define AHCI_CMD_TBL_SZ AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
1363-#define AHCI_PORT_PRIV_DMA_SZ AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ \
1364- + AHCI_RX_FIS_SZ
1365+#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \
1366+ AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ)
1367 #define AHCI_CMD_ATAPI (1 << 5)
1368 #define AHCI_CMD_WRITE (1 << 6)
1369 #define AHCI_CMD_PREFETCH (1 << 7)
1370--
13711.7.10
1372