blob: 8c785ae923ffa30d930ab43262f06fc13a990148 [file] [log] [blame]
Jin Zhengxiong4782ac82006-08-23 19:10:44 +08001/*
Kumar Gala4c2e3da2009-07-28 21:49:52 -05002 * Copyright (C) Freescale Semiconductor, Inc. 2006.
Jin Zhengxiong4782ac82006-08-23 19:10:44 +08003 * Author: Jason Jin<Jason.jin@freescale.com>
4 * Zhang Wei<wei.zhang@freescale.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 * with the reference on libata and ahci drvier in kernel
25 *
26 */
27#include <common.h>
28
Jin Zhengxiong4782ac82006-08-23 19:10:44 +080029#include <command.h>
30#include <pci.h>
31#include <asm/processor.h>
32#include <asm/errno.h>
33#include <asm/io.h>
34#include <malloc.h>
35#include <scsi.h>
36#include <ata.h>
37#include <linux/ctype.h>
38#include <ahci.h>
39
Marc Jones766b16f2012-10-29 05:24:02 +000040static int ata_io_flush(u8 port);
41
Jin Zhengxiong4782ac82006-08-23 19:10:44 +080042struct ahci_probe_ent *probe_ent = NULL;
43hd_driveid_t *ataid[AHCI_MAX_PORTS];
44
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -050045#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
46
Vadim Bendebury284231e2012-10-29 05:23:44 +000047/*
Hung-Te Linb7a21b72012-10-29 05:23:53 +000048 * Some controllers limit number of blocks they can read/write at once.
49 * Contemporary SSD devices work much faster if the read/write size is aligned
50 * to a power of 2. Let's set default to 128 and allowing to be overwritten if
51 * needed.
Vadim Bendebury284231e2012-10-29 05:23:44 +000052 */
Hung-Te Linb7a21b72012-10-29 05:23:53 +000053#ifndef MAX_SATA_BLOCKS_READ_WRITE
54#define MAX_SATA_BLOCKS_READ_WRITE 0x80
Vadim Bendebury284231e2012-10-29 05:23:44 +000055#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +080056
Walter Murphy57847662012-10-29 05:24:00 +000057/* Maximum timeouts for each event */
Marc Jones2a0c61d2012-10-29 05:24:01 +000058#define WAIT_MS_SPINUP 10000
Walter Murphy57847662012-10-29 05:24:00 +000059#define WAIT_MS_DATAIO 5000
Marc Jones766b16f2012-10-29 05:24:02 +000060#define WAIT_MS_FLUSH 5000
Walter Murphy57847662012-10-29 05:24:00 +000061#define WAIT_MS_LINKUP 4
62
Jin Zhengxiong4782ac82006-08-23 19:10:44 +080063static inline u32 ahci_port_base(u32 base, u32 port)
64{
65 return base + 0x100 + (port * 0x80);
66}
67
68
69static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
70 unsigned int port_idx)
71{
72 base = ahci_port_base(base, port_idx);
73
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -050074 port->cmd_addr = base;
75 port->scr_addr = base + PORT_SCR;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +080076}
77
78
79#define msleep(a) udelay(a * 1000)
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -050080
Taylor Hutt90b276f2012-10-29 05:23:59 +000081static void ahci_dcache_flush_range(unsigned begin, unsigned len)
82{
83 const unsigned long start = begin;
84 const unsigned long end = start + len;
85
86 debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
87 flush_dcache_range(start, end);
88}
89
90/*
91 * SATA controller DMAs to physical RAM. Ensure data from the
92 * controller is invalidated from dcache; next access comes from
93 * physical RAM.
94 */
95static void ahci_dcache_invalidate_range(unsigned begin, unsigned len)
96{
97 const unsigned long start = begin;
98 const unsigned long end = start + len;
99
100 debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
101 invalidate_dcache_range(start, end);
102}
103
104/*
105 * Ensure data for SATA controller is flushed out of dcache and
106 * written to physical memory.
107 */
108static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
109{
110 ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
111 AHCI_PORT_PRIV_DMA_SZ);
112}
113
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500114static int waiting_for_cmd_completed(volatile u8 *offset,
115 int timeout_msec,
116 u32 sign)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800117{
118 int i;
119 u32 status;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500120
121 for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800122 msleep(1);
123
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500124 return (i < timeout_msec) ? 0 : -1;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800125}
126
127
128static int ahci_host_init(struct ahci_probe_ent *probe_ent)
129{
Rob Herring942e3142011-07-06 16:13:36 +0000130#ifndef CONFIG_SCSI_AHCI_PLAT
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800131 pci_dev_t pdev = probe_ent->dev;
Rob Herring942e3142011-07-06 16:13:36 +0000132 u16 tmp16;
133 unsigned short vendor;
134#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800135 volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
Marc Jones2a0c61d2012-10-29 05:24:01 +0000136 u32 tmp, cap_save, cmd;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800137 int i, j;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500138 volatile u8 *port_mmio;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800139
Vadim Bendebury284231e2012-10-29 05:23:44 +0000140 debug("ahci_host_init: start\n");
141
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800142 cap_save = readl(mmio + HOST_CAP);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500143 cap_save &= ((1 << 28) | (1 << 17));
Marc Jones2a0c61d2012-10-29 05:24:01 +0000144 cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800145
146 /* global controller reset */
147 tmp = readl(mmio + HOST_CTL);
148 if ((tmp & HOST_RESET) == 0)
149 writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);
150
151 /* reset must complete within 1 second, or
152 * the hardware should be considered fried.
153 */
Stefan Reinauer9a65b872012-10-29 05:23:49 +0000154 i = 1000;
155 do {
156 udelay(1000);
157 tmp = readl(mmio + HOST_CTL);
158 if (!i--) {
159 debug("controller reset failed (0x%x)\n", tmp);
160 return -1;
161 }
162 } while (tmp & HOST_RESET);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800163
164 writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
165 writel(cap_save, mmio + HOST_CAP);
166 writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
167
Rob Herring942e3142011-07-06 16:13:36 +0000168#ifndef CONFIG_SCSI_AHCI_PLAT
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800169 pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
170
171 if (vendor == PCI_VENDOR_ID_INTEL) {
172 u16 tmp16;
173 pci_read_config_word(pdev, 0x92, &tmp16);
174 tmp16 |= 0xf;
175 pci_write_config_word(pdev, 0x92, tmp16);
176 }
Rob Herring942e3142011-07-06 16:13:36 +0000177#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800178 probe_ent->cap = readl(mmio + HOST_CAP);
179 probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
180 probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
181
182 debug("cap 0x%x port_map 0x%x n_ports %d\n",
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500183 probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800184
Vadim Bendebury284231e2012-10-29 05:23:44 +0000185 if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
186 probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
187
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800188 for (i = 0; i < probe_ent->n_ports; i++) {
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500189 probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
190 port_mmio = (u8 *) probe_ent->port[i].port_mmio;
191 ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800192
193 /* make sure port is not active */
194 tmp = readl(port_mmio + PORT_CMD);
195 if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
196 PORT_CMD_FIS_RX | PORT_CMD_START)) {
Stefan Reinauer7ba79172012-10-29 05:23:50 +0000197 debug("Port %d is active. Deactivating.\n", i);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800198 tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
199 PORT_CMD_FIS_RX | PORT_CMD_START);
200 writel_with_flush(tmp, port_mmio + PORT_CMD);
201
202 /* spec says 500 msecs for each bit, so
203 * this is slightly incorrect.
204 */
205 msleep(500);
206 }
207
Marc Jones2a0c61d2012-10-29 05:24:01 +0000208 /* Add the spinup command to whatever mode bits may
209 * already be on in the command register.
210 */
211 cmd = readl(port_mmio + PORT_CMD);
212 cmd |= PORT_CMD_FIS_RX;
213 cmd |= PORT_CMD_SPIN_UP;
214 writel_with_flush(cmd, port_mmio + PORT_CMD);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800215
Marc Jones2a0c61d2012-10-29 05:24:01 +0000216 /* Bring up SATA link.
217 * SATA link bringup time is usually less than 1 ms; only very
218 * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
219 */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800220 j = 0;
Walter Murphy57847662012-10-29 05:24:00 +0000221 while (j < WAIT_MS_LINKUP) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800222 tmp = readl(port_mmio + PORT_SCR_STAT);
223 if ((tmp & 0xf) == 0x3)
224 break;
Stefan Reinauer9a65b872012-10-29 05:23:49 +0000225 udelay(1000);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800226 j++;
227 }
Marc Jones2a0c61d2012-10-29 05:24:01 +0000228 if (j == WAIT_MS_LINKUP) {
229 printf("SATA link %d timeout.\n", i);
230 continue;
231 } else {
232 debug("SATA link ok.\n");
233 }
234
235 /* Clear error status */
236 tmp = readl(port_mmio + PORT_SCR_ERR);
237 if (tmp)
238 writel(tmp, port_mmio + PORT_SCR_ERR);
239
240 debug("Spinning up device on SATA port %d... ", i);
241
242 j = 0;
243 while (j < WAIT_MS_SPINUP) {
244 tmp = readl(port_mmio + PORT_TFDATA);
245 if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ)))
246 break;
247 udelay(1000);
248 j++;
249 }
250 printf("Target spinup took %d ms.\n", j);
251 if (j == WAIT_MS_SPINUP)
Stefan Reinauer9a65b872012-10-29 05:23:49 +0000252 debug("timeout.\n");
253 else
254 debug("ok.\n");
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800255
256 tmp = readl(port_mmio + PORT_SCR_ERR);
257 debug("PORT_SCR_ERR 0x%x\n", tmp);
258 writel(tmp, port_mmio + PORT_SCR_ERR);
259
260 /* ack any pending irq events for this port */
261 tmp = readl(port_mmio + PORT_IRQ_STAT);
262 debug("PORT_IRQ_STAT 0x%x\n", tmp);
263 if (tmp)
264 writel(tmp, port_mmio + PORT_IRQ_STAT);
265
266 writel(1 << i, mmio + HOST_IRQ_STAT);
267
268 /* set irq mask (enables interrupts) */
269 writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
270
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000271 /* register linkup ports */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800272 tmp = readl(port_mmio + PORT_SCR_STAT);
Marc Jones766b16f2012-10-29 05:24:02 +0000273 debug("SATA port %d status: 0x%x\n", i, tmp);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500274 if ((tmp & 0xf) == 0x03)
275 probe_ent->link_port_map |= (0x01 << i);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800276 }
277
278 tmp = readl(mmio + HOST_CTL);
279 debug("HOST_CTL 0x%x\n", tmp);
280 writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
281 tmp = readl(mmio + HOST_CTL);
282 debug("HOST_CTL 0x%x\n", tmp);
Rob Herring942e3142011-07-06 16:13:36 +0000283#ifndef CONFIG_SCSI_AHCI_PLAT
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800284 pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
285 tmp |= PCI_COMMAND_MASTER;
286 pci_write_config_word(pdev, PCI_COMMAND, tmp16);
Rob Herring942e3142011-07-06 16:13:36 +0000287#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800288 return 0;
289}
290
291
292static void ahci_print_info(struct ahci_probe_ent *probe_ent)
293{
Rob Herring942e3142011-07-06 16:13:36 +0000294#ifndef CONFIG_SCSI_AHCI_PLAT
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800295 pci_dev_t pdev = probe_ent->dev;
Rob Herring942e3142011-07-06 16:13:36 +0000296 u16 cc;
297#endif
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500298 volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000299 u32 vers, cap, cap2, impl, speed;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800300 const char *speed_s;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800301 const char *scc_s;
302
303 vers = readl(mmio + HOST_VERSION);
304 cap = probe_ent->cap;
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000305 cap2 = readl(mmio + HOST_CAP2);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800306 impl = probe_ent->port_map;
307
308 speed = (cap >> 20) & 0xf;
309 if (speed == 1)
310 speed_s = "1.5";
311 else if (speed == 2)
312 speed_s = "3";
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000313 else if (speed == 3)
314 speed_s = "6";
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800315 else
316 speed_s = "?";
317
Rob Herring942e3142011-07-06 16:13:36 +0000318#ifdef CONFIG_SCSI_AHCI_PLAT
319 scc_s = "SATA";
320#else
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800321 pci_read_config_word(pdev, 0x0a, &cc);
322 if (cc == 0x0101)
323 scc_s = "IDE";
324 else if (cc == 0x0106)
325 scc_s = "SATA";
326 else if (cc == 0x0104)
327 scc_s = "RAID";
328 else
329 scc_s = "unknown";
Rob Herring942e3142011-07-06 16:13:36 +0000330#endif
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500331 printf("AHCI %02x%02x.%02x%02x "
332 "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
333 (vers >> 24) & 0xff,
334 (vers >> 16) & 0xff,
335 (vers >> 8) & 0xff,
336 vers & 0xff,
337 ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800338
339 printf("flags: "
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000340 "%s%s%s%s%s%s%s"
341 "%s%s%s%s%s%s%s"
342 "%s%s%s%s%s%s\n",
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500343 cap & (1 << 31) ? "64bit " : "",
344 cap & (1 << 30) ? "ncq " : "",
345 cap & (1 << 28) ? "ilck " : "",
346 cap & (1 << 27) ? "stag " : "",
347 cap & (1 << 26) ? "pm " : "",
348 cap & (1 << 25) ? "led " : "",
349 cap & (1 << 24) ? "clo " : "",
350 cap & (1 << 19) ? "nz " : "",
351 cap & (1 << 18) ? "only " : "",
352 cap & (1 << 17) ? "pmp " : "",
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000353 cap & (1 << 16) ? "fbss " : "",
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500354 cap & (1 << 15) ? "pio " : "",
355 cap & (1 << 14) ? "slum " : "",
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000356 cap & (1 << 13) ? "part " : "",
357 cap & (1 << 7) ? "ccc " : "",
358 cap & (1 << 6) ? "ems " : "",
359 cap & (1 << 5) ? "sxs " : "",
360 cap2 & (1 << 2) ? "apst " : "",
361 cap2 & (1 << 1) ? "nvmp " : "",
362 cap2 & (1 << 0) ? "boh " : "");
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800363}
364
Rob Herring942e3142011-07-06 16:13:36 +0000365#ifndef CONFIG_SCSI_AHCI_PLAT
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500366static int ahci_init_one(pci_dev_t pdev)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800367{
Ed Swarthout63cec582007-08-02 14:09:49 -0500368 u16 vendor;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800369 int rc;
370
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500371 memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800372
Ed Swarthout594e7982007-08-14 14:06:45 -0500373 probe_ent = malloc(sizeof(struct ahci_probe_ent));
374 memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800375 probe_ent->dev = pdev;
376
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500377 probe_ent->host_flags = ATA_FLAG_SATA
378 | ATA_FLAG_NO_LEGACY
379 | ATA_FLAG_MMIO
380 | ATA_FLAG_PIO_DMA
381 | ATA_FLAG_NO_ATAPI;
382 probe_ent->pio_mask = 0x1f;
383 probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800384
Vadim Bendebury284231e2012-10-29 05:23:44 +0000385 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base);
386 debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800387
388 /* Take from kernel:
389 * JMicron-specific fixup:
390 * make sure we're in AHCI mode
391 */
392 pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500393 if (vendor == 0x197b)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800394 pci_write_config_byte(pdev, 0x41, 0xa1);
395
396 /* initialize adapter */
397 rc = ahci_host_init(probe_ent);
398 if (rc)
399 goto err_out;
400
401 ahci_print_info(probe_ent);
402
403 return 0;
404
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500405 err_out:
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800406 return rc;
407}
Rob Herring942e3142011-07-06 16:13:36 +0000408#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800409
410#define MAX_DATA_BYTE_COUNT (4*1024*1024)
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500411
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800412static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
413{
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800414 struct ahci_ioports *pp = &(probe_ent->port[port]);
415 struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
416 u32 sg_count;
417 int i;
418
419 sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500420 if (sg_count > AHCI_MAX_SG) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800421 printf("Error:Too much sg!\n");
422 return -1;
423 }
424
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500425 for (i = 0; i < sg_count; i++) {
426 ahci_sg->addr =
427 cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800428 ahci_sg->addr_hi = 0;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500429 ahci_sg->flags_size = cpu_to_le32(0x3fffff &
430 (buf_len < MAX_DATA_BYTE_COUNT
431 ? (buf_len - 1)
432 : (MAX_DATA_BYTE_COUNT - 1)));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800433 ahci_sg++;
434 buf_len -= MAX_DATA_BYTE_COUNT;
435 }
436
437 return sg_count;
438}
439
440
441static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
442{
443 pp->cmd_slot->opts = cpu_to_le32(opts);
444 pp->cmd_slot->status = 0;
445 pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
446 pp->cmd_slot->tbl_addr_hi = 0;
447}
448
449
Gabe Blacke81058c2012-10-29 05:23:52 +0000450#ifdef CONFIG_AHCI_SETFEATURES_XFER
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800451static void ahci_set_feature(u8 port)
452{
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800453 struct ahci_ioports *pp = &(probe_ent->port[port]);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500454 volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
455 u32 cmd_fis_len = 5; /* five dwords */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800456 u8 fis[20];
457
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000458 /* set feature */
Taylor Huttc8731112012-10-29 05:23:55 +0000459 memset(fis, 0, sizeof(fis));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800460 fis[0] = 0x27;
461 fis[1] = 1 << 7;
462 fis[2] = ATA_CMD_SETF;
463 fis[3] = SETFEATURES_XFER;
464 fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
465
Taylor Huttc8731112012-10-29 05:23:55 +0000466 memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800467 ahci_fill_cmd_slot(pp, cmd_fis_len);
Taylor Hutt90b276f2012-10-29 05:23:59 +0000468 ahci_dcache_flush_sata_cmd(pp);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800469 writel(1, port_mmio + PORT_CMD_ISSUE);
470 readl(port_mmio + PORT_CMD_ISSUE);
471
Walter Murphy57847662012-10-29 05:24:00 +0000472 if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
473 WAIT_MS_DATAIO, 0x1)) {
Stefan Reinauer4e422bc2012-10-29 05:23:51 +0000474 printf("set feature error on port %d!\n", port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800475 }
476}
Gabe Blacke81058c2012-10-29 05:23:52 +0000477#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800478
479
480static int ahci_port_start(u8 port)
481{
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800482 struct ahci_ioports *pp = &(probe_ent->port[port]);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500483 volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800484 u32 port_status;
485 u32 mem;
486
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500487 debug("Enter start port: %d\n", port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800488 port_status = readl(port_mmio + PORT_SCR_STAT);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500489 debug("Port %d status: %x\n", port, port_status);
490 if ((port_status & 0xf) != 0x03) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800491 printf("No Link on this port!\n");
492 return -1;
493 }
494
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500495 mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800496 if (!mem) {
497 free(pp);
498 printf("No mem for table!\n");
499 return -ENOMEM;
500 }
501
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500502 mem = (mem + 0x800) & (~0x7ff); /* Aligned to 2048-bytes */
503 memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800504
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800505 /*
506 * First item in chunk of DMA memory: 32-slot command table,
507 * 32 bytes each in size
508 */
Taylor Hutt64738e82012-10-29 05:23:58 +0000509 pp->cmd_slot =
510 (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
Vadim Bendebury284231e2012-10-29 05:23:44 +0000511 debug("cmd_slot = 0x%x\n", (unsigned)pp->cmd_slot);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800512 mem += (AHCI_CMD_SLOT_SZ + 224);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500513
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800514 /*
515 * Second item: Received-FIS area
516 */
Taylor Hutt64738e82012-10-29 05:23:58 +0000517 pp->rx_fis = virt_to_phys((void *)mem);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800518 mem += AHCI_RX_FIS_SZ;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500519
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800520 /*
521 * Third item: data area for storing a single command
522 * and its scatter-gather table
523 */
Taylor Hutt64738e82012-10-29 05:23:58 +0000524 pp->cmd_tbl = virt_to_phys((void *)mem);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500525 debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800526
527 mem += AHCI_CMD_TBL_HDR;
Taylor Hutt64738e82012-10-29 05:23:58 +0000528 pp->cmd_tbl_sg =
529 (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800530
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500531 writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800532
533 writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
534
535 writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500536 PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
537 PORT_CMD_START, port_mmio + PORT_CMD);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800538
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500539 debug("Exit start port %d\n", port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800540
541 return 0;
542}
543
544
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000545static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
546 int buf_len, u8 is_write)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800547{
548
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500549 struct ahci_ioports *pp = &(probe_ent->port[port]);
550 volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800551 u32 opts;
552 u32 port_status;
553 int sg_count;
554
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000555 debug("Enter %s: for port %d\n", __func__, port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800556
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500557 if (port > probe_ent->n_ports) {
Taylor Hutt5a2b77f2012-10-29 05:23:56 +0000558 printf("Invalid port number %d\n", port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800559 return -1;
560 }
561
562 port_status = readl(port_mmio + PORT_SCR_STAT);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500563 if ((port_status & 0xf) != 0x03) {
564 debug("No Link on port %d!\n", port);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800565 return -1;
566 }
567
568 memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
569
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500570 sg_count = ahci_fill_sg(port, buf, buf_len);
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000571 opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800572 ahci_fill_cmd_slot(pp, opts);
573
Taylor Hutt90b276f2012-10-29 05:23:59 +0000574 ahci_dcache_flush_sata_cmd(pp);
575 ahci_dcache_flush_range((unsigned)buf, (unsigned)buf_len);
576
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800577 writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
578
Walter Murphy57847662012-10-29 05:24:00 +0000579 if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
580 WAIT_MS_DATAIO, 0x1)) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800581 printf("timeout exit!\n");
582 return -1;
583 }
Taylor Hutt90b276f2012-10-29 05:23:59 +0000584
585 ahci_dcache_invalidate_range((unsigned)buf, (unsigned)buf_len);
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000586 debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800587
588 return 0;
589}
590
591
592static char *ata_id_strcpy(u16 *target, u16 *src, int len)
593{
594 int i;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500595 for (i = 0; i < len / 2; i++)
Rob Herringe5a6c792011-06-01 09:10:26 +0000596 target[i] = swab16(src[i]);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800597 return (char *)target;
598}
599
600
601static void dump_ataid(hd_driveid_t *ataid)
602{
603 debug("(49)ataid->capability = 0x%x\n", ataid->capability);
604 debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
605 debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
606 debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
607 debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
608 debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
609 debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
610 debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
611 debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
612 debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
613 debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
614 debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
615 debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
616 debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
617 debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
618}
619
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500620
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800621/*
622 * SCSI INQUIRY command operation.
623 */
624static int ata_scsiop_inquiry(ccb *pccb)
625{
626 u8 hdr[] = {
627 0,
628 0,
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500629 0x5, /* claim SPC-3 version compatibility */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800630 2,
631 95 - 4,
632 };
633 u8 fis[20];
634 u8 *tmpid;
635 u8 port;
636
637 /* Clean ccb data buffer */
638 memset(pccb->pdata, 0, pccb->datalen);
639
640 memcpy(pccb->pdata, hdr, sizeof(hdr));
641
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500642 if (pccb->datalen <= 35)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800643 return 0;
644
Taylor Huttc8731112012-10-29 05:23:55 +0000645 memset(fis, 0, sizeof(fis));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800646 /* Construct the FIS */
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500647 fis[0] = 0x27; /* Host to device FIS. */
648 fis[1] = 1 << 7; /* Command FIS. */
649 fis[2] = ATA_CMD_IDENT; /* Command byte. */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800650
651 /* Read id from sata */
652 port = pccb->target;
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500653 if (!(tmpid = malloc(sizeof(hd_driveid_t))))
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800654 return -ENOMEM;
655
Taylor Huttc8731112012-10-29 05:23:55 +0000656 if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), tmpid,
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000657 sizeof(hd_driveid_t), 0)) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800658 debug("scsi_ahci: SCSI inquiry command failure.\n");
659 return -EIO;
660 }
661
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500662 if (ataid[port])
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800663 free(ataid[port]);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500664 ataid[port] = (hd_driveid_t *) tmpid;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800665
666 memcpy(&pccb->pdata[8], "ATA ", 8);
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500667 ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
668 ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800669
670 dump_ataid(ataid[port]);
671 return 0;
672}
673
674
675/*
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000676 * SCSI READ10/WRITE10 command operation.
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800677 */
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000678static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800679{
Vadim Bendebury284231e2012-10-29 05:23:44 +0000680 u32 lba = 0;
681 u16 blocks = 0;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800682 u8 fis[20];
Vadim Bendebury284231e2012-10-29 05:23:44 +0000683 u8 *user_buffer = pccb->pdata;
684 u32 user_buffer_size = pccb->datalen;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800685
Vadim Bendebury284231e2012-10-29 05:23:44 +0000686 /* Retrieve the base LBA number from the ccb structure. */
687 memcpy(&lba, pccb->cmd + 2, sizeof(lba));
688 lba = be32_to_cpu(lba);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800689
Vadim Bendebury284231e2012-10-29 05:23:44 +0000690 /*
691 * And the number of blocks.
692 *
693 * For 10-byte and 16-byte SCSI R/W commands, transfer
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800694 * length 0 means transfer 0 block of data.
695 * However, for ATA R/W commands, sector count 0 means
696 * 256 or 65536 sectors, not 0 sectors as in SCSI.
697 *
698 * WARNING: one or two older ATA drives treat 0 as 0...
699 */
Vadim Bendebury284231e2012-10-29 05:23:44 +0000700 blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);
701
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000702 debug("scsi_ahci: %s %d blocks starting from lba 0x%x\n",
703 is_write ? "write" : "read", (unsigned)lba, blocks);
Vadim Bendebury284231e2012-10-29 05:23:44 +0000704
705 /* Preset the FIS */
Taylor Huttc8731112012-10-29 05:23:55 +0000706 memset(fis, 0, sizeof(fis));
Vadim Bendebury284231e2012-10-29 05:23:44 +0000707 fis[0] = 0x27; /* Host to device FIS. */
708 fis[1] = 1 << 7; /* Command FIS. */
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000709 /* Command byte (read/write). */
Walter Murphyfe1f8082012-10-29 05:24:03 +0000710 fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800711
Vadim Bendebury284231e2012-10-29 05:23:44 +0000712 while (blocks) {
713 u16 now_blocks; /* number of blocks per iteration */
714 u32 transfer_size; /* number of bytes per iteration */
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800715
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000716 now_blocks = min(MAX_SATA_BLOCKS_READ_WRITE, blocks);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800717
Vadim Bendebury284231e2012-10-29 05:23:44 +0000718 transfer_size = ATA_BLOCKSIZE * now_blocks;
719 if (transfer_size > user_buffer_size) {
720 printf("scsi_ahci: Error: buffer too small.\n");
721 return -EIO;
722 }
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800723
Walter Murphyfe1f8082012-10-29 05:24:03 +0000724 /* LBA48 SATA command but only use 32bit address range within
725 * that. The next smaller command range (28bit) is too small.
726 */
Vadim Bendebury284231e2012-10-29 05:23:44 +0000727 fis[4] = (lba >> 0) & 0xff;
728 fis[5] = (lba >> 8) & 0xff;
729 fis[6] = (lba >> 16) & 0xff;
Walter Murphyfe1f8082012-10-29 05:24:03 +0000730 fis[7] = 1 << 6; /* device reg: set LBA mode */
731 fis[8] = ((lba >> 24) & 0xff);
732 fis[3] = 0xe0; /* features */
Vadim Bendebury284231e2012-10-29 05:23:44 +0000733
734 /* Block (sector) count */
735 fis[12] = (now_blocks >> 0) & 0xff;
736 fis[13] = (now_blocks >> 8) & 0xff;
737
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000738 /* Read/Write from ahci */
739 if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
740 user_buffer, user_buffer_size,
741 is_write)) {
742 debug("scsi_ahci: SCSI %s10 command failure.\n",
743 is_write ? "WRITE" : "READ");
Vadim Bendebury284231e2012-10-29 05:23:44 +0000744 return -EIO;
745 }
Marc Jones766b16f2012-10-29 05:24:02 +0000746
747 /* If this transaction is a write, do a following flush.
748 * Writes in u-boot are so rare, and the logic to know when is
749 * the last write and do a flush only there is sufficiently
750 * difficult. Just do a flush after every write. This incurs,
751 * usually, one extra flush when the rare writes do happen.
752 */
753 if (is_write) {
754 if (-EIO == ata_io_flush(pccb->target))
755 return -EIO;
756 }
Vadim Bendebury284231e2012-10-29 05:23:44 +0000757 user_buffer += transfer_size;
758 user_buffer_size -= transfer_size;
759 blocks -= now_blocks;
760 lba += now_blocks;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800761 }
762
763 return 0;
764}
765
766
767/*
768 * SCSI READ CAPACITY10 command operation.
769 */
770static int ata_scsiop_read_capacity10(ccb *pccb)
771{
Kumar Galacb6d0b72009-07-13 09:24:00 -0500772 u32 cap;
Gabe Black19d1d412012-10-29 05:23:54 +0000773 u32 block_size;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800774
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500775 if (!ataid[pccb->target]) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800776 printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500777 "\tNo ATA info!\n"
778 "\tPlease run SCSI commmand INQUIRY firstly!\n");
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800779 return -EPERM;
780 }
781
Gabe Black19d1d412012-10-29 05:23:54 +0000782 cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
783 if (cap == 0xfffffff) {
784 unsigned short *cap48 = ataid[pccb->target]->lba48_capacity;
785 if (cap48[2] || cap48[3]) {
786 cap = 0xffffffff;
787 } else {
788 cap = (le16_to_cpu(cap48[1]) << 16) |
789 (le16_to_cpu(cap48[0]));
790 }
791 }
792
793 cap = cpu_to_be32(cap);
Kumar Galacb6d0b72009-07-13 09:24:00 -0500794 memcpy(pccb->pdata, &cap, sizeof(cap));
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800795
Gabe Black19d1d412012-10-29 05:23:54 +0000796 block_size = cpu_to_be32((u32)512);
797 memcpy(&pccb->pdata[4], &block_size, 4);
798
799 return 0;
800}
801
802
803/*
804 * SCSI READ CAPACITY16 command operation.
805 */
806static int ata_scsiop_read_capacity16(ccb *pccb)
807{
808 u64 cap;
809 u64 block_size;
810
811 if (!ataid[pccb->target]) {
812 printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
813 "\tNo ATA info!\n"
814 "\tPlease run SCSI commmand INQUIRY firstly!\n");
815 return -EPERM;
816 }
817
818 cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
819 if (cap == 0xfffffff) {
820 memcpy(&cap, ataid[pccb->target]->lba48_capacity, sizeof(cap));
821 cap = le64_to_cpu(cap);
822 }
823
824 cap = cpu_to_be64(cap);
825 memcpy(pccb->pdata, &cap, sizeof(cap));
826
827 block_size = cpu_to_be64((u64)512);
828 memcpy(&pccb->pdata[8], &block_size, 8);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800829
830 return 0;
831}
832
833
834/*
835 * SCSI TEST UNIT READY command operation.
836 */
837static int ata_scsiop_test_unit_ready(ccb *pccb)
838{
839 return (ataid[pccb->target]) ? 0 : -EPERM;
840}
841
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500842
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800843int scsi_exec(ccb *pccb)
844{
845 int ret;
846
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500847 switch (pccb->cmd[0]) {
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800848 case SCSI_READ10:
Hung-Te Linb7a21b72012-10-29 05:23:53 +0000849 ret = ata_scsiop_read_write(pccb, 0);
850 break;
851 case SCSI_WRITE10:
852 ret = ata_scsiop_read_write(pccb, 1);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800853 break;
Gabe Black19d1d412012-10-29 05:23:54 +0000854 case SCSI_RD_CAPAC10:
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800855 ret = ata_scsiop_read_capacity10(pccb);
856 break;
Gabe Black19d1d412012-10-29 05:23:54 +0000857 case SCSI_RD_CAPAC16:
858 ret = ata_scsiop_read_capacity16(pccb);
859 break;
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800860 case SCSI_TST_U_RDY:
861 ret = ata_scsiop_test_unit_ready(pccb);
862 break;
863 case SCSI_INQUIRY:
864 ret = ata_scsiop_inquiry(pccb);
865 break;
866 default:
867 printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
868 return FALSE;
869 }
870
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500871 if (ret) {
872 debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800873 return FALSE;
874 }
875 return TRUE;
876
877}
878
879
880void scsi_low_level_init(int busdevfunc)
881{
882 int i;
883 u32 linkmap;
884
Rob Herring942e3142011-07-06 16:13:36 +0000885#ifndef CONFIG_SCSI_AHCI_PLAT
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800886 ahci_init_one(busdevfunc);
Rob Herring942e3142011-07-06 16:13:36 +0000887#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800888
889 linkmap = probe_ent->link_port_map;
890
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200891 for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500892 if (((linkmap >> i) & 0x01)) {
893 if (ahci_port_start((u8) i)) {
894 printf("Can not start port %d\n", i);
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800895 continue;
896 }
Gabe Blacke81058c2012-10-29 05:23:52 +0000897#ifdef CONFIG_AHCI_SETFEATURES_XFER
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500898 ahci_set_feature((u8) i);
Gabe Blacke81058c2012-10-29 05:23:52 +0000899#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800900 }
901 }
902}
903
Rob Herring942e3142011-07-06 16:13:36 +0000904#ifdef CONFIG_SCSI_AHCI_PLAT
905int ahci_init(u32 base)
906{
907 int i, rc = 0;
908 u32 linkmap;
909
910 memset(ataid, 0, sizeof(ataid));
911
912 probe_ent = malloc(sizeof(struct ahci_probe_ent));
913 memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
914
915 probe_ent->host_flags = ATA_FLAG_SATA
916 | ATA_FLAG_NO_LEGACY
917 | ATA_FLAG_MMIO
918 | ATA_FLAG_PIO_DMA
919 | ATA_FLAG_NO_ATAPI;
920 probe_ent->pio_mask = 0x1f;
921 probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
922
923 probe_ent->mmio_base = base;
924
925 /* initialize adapter */
926 rc = ahci_host_init(probe_ent);
927 if (rc)
928 goto err_out;
929
930 ahci_print_info(probe_ent);
931
932 linkmap = probe_ent->link_port_map;
933
934 for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
935 if (((linkmap >> i) & 0x01)) {
936 if (ahci_port_start((u8) i)) {
937 printf("Can not start port %d\n", i);
938 continue;
939 }
Gabe Blacke81058c2012-10-29 05:23:52 +0000940#ifdef CONFIG_AHCI_SETFEATURES_XFER
Rob Herring942e3142011-07-06 16:13:36 +0000941 ahci_set_feature((u8) i);
Gabe Blacke81058c2012-10-29 05:23:52 +0000942#endif
Rob Herring942e3142011-07-06 16:13:36 +0000943 }
944 }
945err_out:
946 return rc;
947}
948#endif
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800949
Marc Jones766b16f2012-10-29 05:24:02 +0000950/*
951 * In the general case of generic rotating media it makes sense to have a
952 * flush capability. It probably even makes sense in the case of SSDs because
953 * one cannot always know for sure what kind of internal cache/flush mechanism
954 * is embodied therein. At first it was planned to invoke this after the last
955 * write to disk and before rebooting. In practice, knowing, a priori, which
956 * is the last write is difficult. Because writing to the disk in u-boot is
957 * very rare, this flush command will be invoked after every block write.
958 */
959static int ata_io_flush(u8 port)
960{
961 u8 fis[20];
962 struct ahci_ioports *pp = &(probe_ent->port[port]);
963 volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
964 u32 cmd_fis_len = 5; /* five dwords */
965
966 /* Preset the FIS */
967 memset(fis, 0, 20);
968 fis[0] = 0x27; /* Host to device FIS. */
969 fis[1] = 1 << 7; /* Command FIS. */
Walter Murphyfe1f8082012-10-29 05:24:03 +0000970 fis[2] = ATA_CMD_FLUSH_EXT;
Marc Jones766b16f2012-10-29 05:24:02 +0000971
972 memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
973 ahci_fill_cmd_slot(pp, cmd_fis_len);
974 writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
975
976 if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
977 WAIT_MS_FLUSH, 0x1)) {
978 debug("scsi_ahci: flush command timeout on port %d.\n", port);
979 return -EIO;
980 }
981
982 return 0;
983}
984
985
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800986void scsi_bus_reset(void)
987{
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500988 /*Not implement*/
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800989}
990
991
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500992void scsi_print_error(ccb * pccb)
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800993{
Jon Loeliger4a7cc0f2006-08-23 11:04:43 -0500994 /*The ahci error info can be read in the ahci driver*/
Jin Zhengxiong4782ac82006-08-23 19:10:44 +0800995}