diff options
author | Otavio Salvador <otavio@ossystems.com.br> | 2012-05-22 14:23:55 -0300 |
---|---|---|
committer | Otavio Salvador <otavio@ossystems.com.br> | 2012-05-22 14:23:55 -0300 |
commit | 06964063799142d938e6a0d920ab4bee661016d9 (patch) | |
tree | 8fd9c7d049d936a54c50cd7517b871501d3ec83c /recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch | |
parent | 7cd551b57aa1a23d83b168600beac15b5f4e9541 (diff) | |
download | meta-fsl-arm-06964063799142d938e6a0d920ab4bee661016d9.tar.gz |
u-boot: fix directory name for patches against 2012.04.01 version
The PV is v2012.04.01 so the directory name needs to be set as the
same.
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.patch | 1372 |
1 files changed, 0 insertions, 1372 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 deleted file mode 100644 index e4e93a6..0000000 --- a/recipes-bsp/u-boot/u-boot-2012.04.01/0004-SATA-add-driver-for-MX5-MX6-SOCs.patch +++ /dev/null | |||
@@ -1,1372 +0,0 @@ | |||
1 | From 160e7d7c3fbbcbb60ba71eb984f633db26494646 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Babic <sbabic@denx.de> | ||
3 | Date: Wed, 22 Feb 2012 00:24:39 +0000 | ||
4 | Subject: [PATCH 04/56] SATA: add driver for MX5 / MX6 SOCs | ||
5 | |||
6 | This driver is part of Freescale's LTIB for | ||
7 | MX5 / MX6. | ||
8 | |||
9 | Signed-off-by: Stefano Babic <sbabic@denx.de> | ||
10 | Signed-off-by: Terry Lv <r65388@freescale.com> | ||
11 | CC: Fabio Estevam <fabio.estevam@freescale.com> | ||
12 | CC: 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 | |||
22 | diff --git a/drivers/block/Makefile b/drivers/block/Makefile | ||
23 | index 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 | ||
34 | diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c | ||
35 | new file mode 100644 | ||
36 | index 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 | +} | ||
1009 | diff --git a/drivers/block/dwc_ahsata.h b/drivers/block/dwc_ahsata.h | ||
1010 | new file mode 100644 | ||
1011 | index 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__ */ | ||
1350 | diff --git a/include/ahci.h b/include/ahci.h | ||
1351 | index 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 | -- | ||
1371 | 1.7.10 | ||
1372 | |||