ahci.c 24.2 KB
Newer Older
J
Jin Zhengxiong 已提交
1
/*
2
 * Copyright (C) Freescale Semiconductor, Inc. 2006.
J
Jin Zhengxiong 已提交
3 4 5
 * Author: Jason Jin<Jason.jin@freescale.com>
 *         Zhang Wei<wei.zhang@freescale.com>
 *
6
 * SPDX-License-Identifier:	GPL-2.0+
J
Jin Zhengxiong 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * with the reference on libata and ahci drvier in kernel
 */
#include <common.h>

#include <command.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <scsi.h>
#include <ata.h>
#include <linux/ctype.h>
#include <ahci.h>

23 24
static int ata_io_flush(u8 port);

J
Jin Zhengxiong 已提交
25 26 27
struct ahci_probe_ent *probe_ent = NULL;
hd_driveid_t *ataid[AHCI_MAX_PORTS];

28 29
#define writel_with_flush(a,b)	do { writel(a,b); readl(b); } while (0)

30
/*
31 32 33 34
 * Some controllers limit number of blocks they can read/write at once.
 * Contemporary SSD devices work much faster if the read/write size is aligned
 * to a power of 2.  Let's set default to 128 and allowing to be overwritten if
 * needed.
35
 */
36 37
#ifndef MAX_SATA_BLOCKS_READ_WRITE
#define MAX_SATA_BLOCKS_READ_WRITE	0x80
38
#endif
J
Jin Zhengxiong 已提交
39

40
/* Maximum timeouts for each event */
41
#define WAIT_MS_SPINUP	10000
42
#define WAIT_MS_DATAIO	5000
43
#define WAIT_MS_FLUSH	5000
44 45
#define WAIT_MS_LINKUP	4

J
Jin Zhengxiong 已提交
46 47 48 49 50 51 52 53 54 55 56
static inline u32 ahci_port_base(u32 base, u32 port)
{
	return base + 0x100 + (port * 0x80);
}


static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
			    unsigned int port_idx)
{
	base = ahci_port_base(base, port_idx);

57 58
	port->cmd_addr = base;
	port->scr_addr = base + PORT_SCR;
J
Jin Zhengxiong 已提交
59 60 61 62
}


#define msleep(a) udelay(a * 1000)
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
static void ahci_dcache_flush_range(unsigned begin, unsigned len)
{
	const unsigned long start = begin;
	const unsigned long end = start + len;

	debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
	flush_dcache_range(start, end);
}

/*
 * SATA controller DMAs to physical RAM.  Ensure data from the
 * controller is invalidated from dcache; next access comes from
 * physical RAM.
 */
static void ahci_dcache_invalidate_range(unsigned begin, unsigned len)
{
	const unsigned long start = begin;
	const unsigned long end = start + len;

	debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
	invalidate_dcache_range(start, end);
}

/*
 * Ensure data for SATA controller is flushed out of dcache and
 * written to physical memory.
 */
static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
{
	ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
				AHCI_PORT_PRIV_DMA_SZ);
}

97 98 99
static int waiting_for_cmd_completed(volatile u8 *offset,
				     int timeout_msec,
				     u32 sign)
J
Jin Zhengxiong 已提交
100 101 102
{
	int i;
	u32 status;
103 104

	for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++)
J
Jin Zhengxiong 已提交
105 106
		msleep(1);

107
	return (i < timeout_msec) ? 0 : -1;
J
Jin Zhengxiong 已提交
108 109 110 111 112
}


static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
113
#ifndef CONFIG_SCSI_AHCI_PLAT
J
Jin Zhengxiong 已提交
114
	pci_dev_t pdev = probe_ent->dev;
115 116 117
	u16 tmp16;
	unsigned short vendor;
#endif
J
Jin Zhengxiong 已提交
118
	volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
119
	u32 tmp, cap_save, cmd;
J
Jin Zhengxiong 已提交
120
	int i, j;
121
	volatile u8 *port_mmio;
122
	u32 port_map;
J
Jin Zhengxiong 已提交
123

124 125
	debug("ahci_host_init: start\n");

J
Jin Zhengxiong 已提交
126
	cap_save = readl(mmio + HOST_CAP);
127
	cap_save &= ((1 << 28) | (1 << 17));
128
	cap_save |= (1 << 27);  /* Staggered Spin-up. Not needed. */
J
Jin Zhengxiong 已提交
129 130 131 132 133 134 135 136 137

	/* global controller reset */
	tmp = readl(mmio + HOST_CTL);
	if ((tmp & HOST_RESET) == 0)
		writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL);

	/* reset must complete within 1 second, or
	 * the hardware should be considered fried.
	 */
138 139 140 141 142 143 144 145 146
	i = 1000;
	do {
		udelay(1000);
		tmp = readl(mmio + HOST_CTL);
		if (!i--) {
			debug("controller reset failed (0x%x)\n", tmp);
			return -1;
		}
	} while (tmp & HOST_RESET);
J
Jin Zhengxiong 已提交
147 148 149 150 151

	writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
	writel(cap_save, mmio + HOST_CAP);
	writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);

152
#ifndef CONFIG_SCSI_AHCI_PLAT
J
Jin Zhengxiong 已提交
153 154 155 156 157 158 159 160
	pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);

	if (vendor == PCI_VENDOR_ID_INTEL) {
		u16 tmp16;
		pci_read_config_word(pdev, 0x92, &tmp16);
		tmp16 |= 0xf;
		pci_write_config_word(pdev, 0x92, tmp16);
	}
161
#endif
J
Jin Zhengxiong 已提交
162 163
	probe_ent->cap = readl(mmio + HOST_CAP);
	probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
164
	port_map = probe_ent->port_map;
J
Jin Zhengxiong 已提交
165 166 167
	probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;

	debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
168
	      probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
J
Jin Zhengxiong 已提交
169

170 171 172
	if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
		probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;

J
Jin Zhengxiong 已提交
173
	for (i = 0; i < probe_ent->n_ports; i++) {
174 175
		if (!(port_map & (1 << i)))
			continue;
176 177 178
		probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
		port_mmio = (u8 *) probe_ent->port[i].port_mmio;
		ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
J
Jin Zhengxiong 已提交
179 180 181 182 183

		/* make sure port is not active */
		tmp = readl(port_mmio + PORT_CMD);
		if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
			   PORT_CMD_FIS_RX | PORT_CMD_START)) {
S
Stefan Reinauer 已提交
184
			debug("Port %d is active. Deactivating.\n", i);
J
Jin Zhengxiong 已提交
185 186 187 188 189 190 191 192 193 194
			tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
				 PORT_CMD_FIS_RX | PORT_CMD_START);
			writel_with_flush(tmp, port_mmio + PORT_CMD);

			/* spec says 500 msecs for each bit, so
			 * this is slightly incorrect.
			 */
			msleep(500);
		}

195 196 197 198 199 200 201 202 203 204 205 206
		/* Add the spinup command to whatever mode bits may
		 * already be on in the command register.
		 */
		cmd = readl(port_mmio + PORT_CMD);
		cmd |= PORT_CMD_FIS_RX;
		cmd |= PORT_CMD_SPIN_UP;
		writel_with_flush(cmd, port_mmio + PORT_CMD);

		/* Bring up SATA link.
		 * SATA link bringup time is usually less than 1 ms; only very
		 * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
		 */
J
Jin Zhengxiong 已提交
207
		j = 0;
208
		while (j < WAIT_MS_LINKUP) {
J
Jin Zhengxiong 已提交
209 210 211
			tmp = readl(port_mmio + PORT_SCR_STAT);
			if ((tmp & 0xf) == 0x3)
				break;
212
			udelay(1000);
J
Jin Zhengxiong 已提交
213 214
			j++;
		}
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
		if (j == WAIT_MS_LINKUP) {
			printf("SATA link %d timeout.\n", i);
			continue;
		} else {
			debug("SATA link ok.\n");
		}

		/* Clear error status */
		tmp = readl(port_mmio + PORT_SCR_ERR);
		if (tmp)
			writel(tmp, port_mmio + PORT_SCR_ERR);

		debug("Spinning up device on SATA port %d... ", i);

		j = 0;
		while (j < WAIT_MS_SPINUP) {
			tmp = readl(port_mmio + PORT_TFDATA);
			if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ)))
				break;
			udelay(1000);
			j++;
		}
		printf("Target spinup took %d ms.\n", j);
		if (j == WAIT_MS_SPINUP)
239 240 241
			debug("timeout.\n");
		else
			debug("ok.\n");
J
Jin Zhengxiong 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

		tmp = readl(port_mmio + PORT_SCR_ERR);
		debug("PORT_SCR_ERR 0x%x\n", tmp);
		writel(tmp, port_mmio + PORT_SCR_ERR);

		/* ack any pending irq events for this port */
		tmp = readl(port_mmio + PORT_IRQ_STAT);
		debug("PORT_IRQ_STAT 0x%x\n", tmp);
		if (tmp)
			writel(tmp, port_mmio + PORT_IRQ_STAT);

		writel(1 << i, mmio + HOST_IRQ_STAT);

		/* set irq mask (enables interrupts) */
		writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);

S
Stefan Reinauer 已提交
258
		/* register linkup ports */
J
Jin Zhengxiong 已提交
259
		tmp = readl(port_mmio + PORT_SCR_STAT);
260
		debug("SATA port %d status: 0x%x\n", i, tmp);
261 262
		if ((tmp & 0xf) == 0x03)
			probe_ent->link_port_map |= (0x01 << i);
J
Jin Zhengxiong 已提交
263 264 265 266 267 268 269
	}

	tmp = readl(mmio + HOST_CTL);
	debug("HOST_CTL 0x%x\n", tmp);
	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
	tmp = readl(mmio + HOST_CTL);
	debug("HOST_CTL 0x%x\n", tmp);
270
#ifndef CONFIG_SCSI_AHCI_PLAT
J
Jin Zhengxiong 已提交
271 272 273
	pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
	tmp |= PCI_COMMAND_MASTER;
	pci_write_config_word(pdev, PCI_COMMAND, tmp16);
274
#endif
J
Jin Zhengxiong 已提交
275 276 277 278 279 280
	return 0;
}


static void ahci_print_info(struct ahci_probe_ent *probe_ent)
{
281
#ifndef CONFIG_SCSI_AHCI_PLAT
J
Jin Zhengxiong 已提交
282
	pci_dev_t pdev = probe_ent->dev;
283 284
	u16 cc;
#endif
285
	volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
S
Stefan Reinauer 已提交
286
	u32 vers, cap, cap2, impl, speed;
J
Jin Zhengxiong 已提交
287 288 289 290 291
	const char *speed_s;
	const char *scc_s;

	vers = readl(mmio + HOST_VERSION);
	cap = probe_ent->cap;
S
Stefan Reinauer 已提交
292
	cap2 = readl(mmio + HOST_CAP2);
J
Jin Zhengxiong 已提交
293 294 295 296 297 298 299
	impl = probe_ent->port_map;

	speed = (cap >> 20) & 0xf;
	if (speed == 1)
		speed_s = "1.5";
	else if (speed == 2)
		speed_s = "3";
S
Stefan Reinauer 已提交
300 301
	else if (speed == 3)
		speed_s = "6";
J
Jin Zhengxiong 已提交
302 303 304
	else
		speed_s = "?";

305 306 307
#ifdef CONFIG_SCSI_AHCI_PLAT
	scc_s = "SATA";
#else
J
Jin Zhengxiong 已提交
308 309 310 311 312 313 314 315 316
	pci_read_config_word(pdev, 0x0a, &cc);
	if (cc == 0x0101)
		scc_s = "IDE";
	else if (cc == 0x0106)
		scc_s = "SATA";
	else if (cc == 0x0104)
		scc_s = "RAID";
	else
		scc_s = "unknown";
317
#endif
318 319 320 321 322 323 324
	printf("AHCI %02x%02x.%02x%02x "
	       "%u slots %u ports %s Gbps 0x%x impl %s mode\n",
	       (vers >> 24) & 0xff,
	       (vers >> 16) & 0xff,
	       (vers >> 8) & 0xff,
	       vers & 0xff,
	       ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
J
Jin Zhengxiong 已提交
325 326

	printf("flags: "
S
Stefan Reinauer 已提交
327 328 329
	       "%s%s%s%s%s%s%s"
	       "%s%s%s%s%s%s%s"
	       "%s%s%s%s%s%s\n",
330 331 332 333 334 335 336 337 338 339
	       cap & (1 << 31) ? "64bit " : "",
	       cap & (1 << 30) ? "ncq " : "",
	       cap & (1 << 28) ? "ilck " : "",
	       cap & (1 << 27) ? "stag " : "",
	       cap & (1 << 26) ? "pm " : "",
	       cap & (1 << 25) ? "led " : "",
	       cap & (1 << 24) ? "clo " : "",
	       cap & (1 << 19) ? "nz " : "",
	       cap & (1 << 18) ? "only " : "",
	       cap & (1 << 17) ? "pmp " : "",
S
Stefan Reinauer 已提交
340
	       cap & (1 << 16) ? "fbss " : "",
341 342
	       cap & (1 << 15) ? "pio " : "",
	       cap & (1 << 14) ? "slum " : "",
S
Stefan Reinauer 已提交
343 344 345 346 347 348 349
	       cap & (1 << 13) ? "part " : "",
	       cap & (1 << 7) ? "ccc " : "",
	       cap & (1 << 6) ? "ems " : "",
	       cap & (1 << 5) ? "sxs " : "",
	       cap2 & (1 << 2) ? "apst " : "",
	       cap2 & (1 << 1) ? "nvmp " : "",
	       cap2 & (1 << 0) ? "boh " : "");
J
Jin Zhengxiong 已提交
350 351
}

352
#ifndef CONFIG_SCSI_AHCI_PLAT
353
static int ahci_init_one(pci_dev_t pdev)
J
Jin Zhengxiong 已提交
354
{
355
	u16 vendor;
J
Jin Zhengxiong 已提交
356 357
	int rc;

358
	memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
J
Jin Zhengxiong 已提交
359

360 361
	probe_ent = malloc(sizeof(struct ahci_probe_ent));
	memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
J
Jin Zhengxiong 已提交
362 363
	probe_ent->dev = pdev;

364 365 366 367 368 369 370
	probe_ent->host_flags = ATA_FLAG_SATA
				| ATA_FLAG_NO_LEGACY
				| ATA_FLAG_MMIO
				| ATA_FLAG_PIO_DMA
				| ATA_FLAG_NO_ATAPI;
	probe_ent->pio_mask = 0x1f;
	probe_ent->udma_mask = 0x7f;	/*Fixme,assume to support UDMA6 */
J
Jin Zhengxiong 已提交
371

372 373
	pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base);
	debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base);
J
Jin Zhengxiong 已提交
374 375 376 377 378 379

	/* Take from kernel:
	 * JMicron-specific fixup:
	 * make sure we're in AHCI mode
	 */
	pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
380
	if (vendor == 0x197b)
J
Jin Zhengxiong 已提交
381 382 383 384 385 386 387 388 389 390 391
		pci_write_config_byte(pdev, 0x41, 0xa1);

	/* initialize adapter */
	rc = ahci_host_init(probe_ent);
	if (rc)
		goto err_out;

	ahci_print_info(probe_ent);

	return 0;

392
      err_out:
J
Jin Zhengxiong 已提交
393 394
	return rc;
}
395
#endif
J
Jin Zhengxiong 已提交
396 397

#define MAX_DATA_BYTE_COUNT  (4*1024*1024)
398

J
Jin Zhengxiong 已提交
399 400 401 402 403 404 405 406
static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
{
	struct ahci_ioports *pp = &(probe_ent->port[port]);
	struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
	u32 sg_count;
	int i;

	sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1;
407
	if (sg_count > AHCI_MAX_SG) {
J
Jin Zhengxiong 已提交
408 409 410 411
		printf("Error:Too much sg!\n");
		return -1;
	}

412 413 414
	for (i = 0; i < sg_count; i++) {
		ahci_sg->addr =
		    cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT);
J
Jin Zhengxiong 已提交
415
		ahci_sg->addr_hi = 0;
416 417 418 419
		ahci_sg->flags_size = cpu_to_le32(0x3fffff &
					  (buf_len < MAX_DATA_BYTE_COUNT
					   ? (buf_len - 1)
					   : (MAX_DATA_BYTE_COUNT - 1)));
J
Jin Zhengxiong 已提交
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
		ahci_sg++;
		buf_len -= MAX_DATA_BYTE_COUNT;
	}

	return sg_count;
}


static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
{
	pp->cmd_slot->opts = cpu_to_le32(opts);
	pp->cmd_slot->status = 0;
	pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff);
	pp->cmd_slot->tbl_addr_hi = 0;
}


437
#ifdef CONFIG_AHCI_SETFEATURES_XFER
J
Jin Zhengxiong 已提交
438 439 440
static void ahci_set_feature(u8 port)
{
	struct ahci_ioports *pp = &(probe_ent->port[port]);
441 442
	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
	u32 cmd_fis_len = 5;	/* five dwords */
J
Jin Zhengxiong 已提交
443 444
	u8 fis[20];

S
Stefan Reinauer 已提交
445
	/* set feature */
446
	memset(fis, 0, sizeof(fis));
J
Jin Zhengxiong 已提交
447 448 449 450 451 452
	fis[0] = 0x27;
	fis[1] = 1 << 7;
	fis[2] = ATA_CMD_SETF;
	fis[3] = SETFEATURES_XFER;
	fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;

453
	memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis));
J
Jin Zhengxiong 已提交
454
	ahci_fill_cmd_slot(pp, cmd_fis_len);
455
	ahci_dcache_flush_sata_cmd(pp);
J
Jin Zhengxiong 已提交
456 457 458
	writel(1, port_mmio + PORT_CMD_ISSUE);
	readl(port_mmio + PORT_CMD_ISSUE);

459 460
	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
				WAIT_MS_DATAIO, 0x1)) {
S
Stefan Reinauer 已提交
461
		printf("set feature error on port %d!\n", port);
J
Jin Zhengxiong 已提交
462 463
	}
}
464
#endif
J
Jin Zhengxiong 已提交
465 466 467 468 469


static int ahci_port_start(u8 port)
{
	struct ahci_ioports *pp = &(probe_ent->port[port]);
470
	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
J
Jin Zhengxiong 已提交
471 472 473
	u32 port_status;
	u32 mem;

474
	debug("Enter start port: %d\n", port);
J
Jin Zhengxiong 已提交
475
	port_status = readl(port_mmio + PORT_SCR_STAT);
476 477
	debug("Port %d status: %x\n", port, port_status);
	if ((port_status & 0xf) != 0x03) {
J
Jin Zhengxiong 已提交
478 479 480 481
		printf("No Link on this port!\n");
		return -1;
	}

482
	mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048);
J
Jin Zhengxiong 已提交
483 484 485 486 487 488
	if (!mem) {
		free(pp);
		printf("No mem for table!\n");
		return -ENOMEM;
	}

489 490
	mem = (mem + 0x800) & (~0x7ff);	/* Aligned to 2048-bytes */
	memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ);
J
Jin Zhengxiong 已提交
491 492 493 494 495

	/*
	 * First item in chunk of DMA memory: 32-slot command table,
	 * 32 bytes each in size
	 */
496 497
	pp->cmd_slot =
		(struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
498
	debug("cmd_slot = 0x%x\n", (unsigned)pp->cmd_slot);
J
Jin Zhengxiong 已提交
499
	mem += (AHCI_CMD_SLOT_SZ + 224);
500

J
Jin Zhengxiong 已提交
501 502 503
	/*
	 * Second item: Received-FIS area
	 */
504
	pp->rx_fis = virt_to_phys((void *)mem);
J
Jin Zhengxiong 已提交
505
	mem += AHCI_RX_FIS_SZ;
506

J
Jin Zhengxiong 已提交
507 508 509 510
	/*
	 * Third item: data area for storing a single command
	 * and its scatter-gather table
	 */
511
	pp->cmd_tbl = virt_to_phys((void *)mem);
512
	debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
J
Jin Zhengxiong 已提交
513 514

	mem += AHCI_CMD_TBL_HDR;
515 516
	pp->cmd_tbl_sg =
			(struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
J
Jin Zhengxiong 已提交
517

518
	writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
J
Jin Zhengxiong 已提交
519 520 521 522

	writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);

	writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
523 524
			  PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
			  PORT_CMD_START, port_mmio + PORT_CMD);
J
Jin Zhengxiong 已提交
525

526
	debug("Exit start port %d\n", port);
J
Jin Zhengxiong 已提交
527 528 529 530 531

	return 0;
}


532 533
static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
				int buf_len, u8 is_write)
J
Jin Zhengxiong 已提交
534 535
{

536 537
	struct ahci_ioports *pp = &(probe_ent->port[port]);
	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
J
Jin Zhengxiong 已提交
538 539 540 541
	u32 opts;
	u32 port_status;
	int sg_count;

542
	debug("Enter %s: for port %d\n", __func__, port);
J
Jin Zhengxiong 已提交
543

544
	if (port > probe_ent->n_ports) {
T
Taylor Hutt 已提交
545
		printf("Invalid port number %d\n", port);
J
Jin Zhengxiong 已提交
546 547 548 549
		return -1;
	}

	port_status = readl(port_mmio + PORT_SCR_STAT);
550 551
	if ((port_status & 0xf) != 0x03) {
		debug("No Link on port %d!\n", port);
J
Jin Zhengxiong 已提交
552 553 554 555 556
		return -1;
	}

	memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);

557
	sg_count = ahci_fill_sg(port, buf, buf_len);
558
	opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
J
Jin Zhengxiong 已提交
559 560
	ahci_fill_cmd_slot(pp, opts);

561 562 563
	ahci_dcache_flush_sata_cmd(pp);
	ahci_dcache_flush_range((unsigned)buf, (unsigned)buf_len);

J
Jin Zhengxiong 已提交
564 565
	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);

566 567
	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
				WAIT_MS_DATAIO, 0x1)) {
J
Jin Zhengxiong 已提交
568 569 570
		printf("timeout exit!\n");
		return -1;
	}
571 572

	ahci_dcache_invalidate_range((unsigned)buf, (unsigned)buf_len);
573
	debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status);
J
Jin Zhengxiong 已提交
574 575 576 577 578 579 580 581

	return 0;
}


static char *ata_id_strcpy(u16 *target, u16 *src, int len)
{
	int i;
582
	for (i = 0; i < len / 2; i++)
583
		target[i] = swab16(src[i]);
J
Jin Zhengxiong 已提交
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
	return (char *)target;
}


static void dump_ataid(hd_driveid_t *ataid)
{
	debug("(49)ataid->capability = 0x%x\n", ataid->capability);
	debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
	debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
	debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
	debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
	debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
	debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
	debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
	debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
	debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
	debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
	debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
	debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
	debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
	debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
}

607

J
Jin Zhengxiong 已提交
608 609 610 611 612
/*
 * SCSI INQUIRY command operation.
 */
static int ata_scsiop_inquiry(ccb *pccb)
{
R
Rob Herring 已提交
613
	static const u8 hdr[] = {
J
Jin Zhengxiong 已提交
614 615
		0,
		0,
616
		0x5,		/* claim SPC-3 version compatibility */
J
Jin Zhengxiong 已提交
617 618 619 620 621 622 623 624 625 626 627 628
		2,
		95 - 4,
	};
	u8 fis[20];
	u8 *tmpid;
	u8 port;

	/* Clean ccb data buffer */
	memset(pccb->pdata, 0, pccb->datalen);

	memcpy(pccb->pdata, hdr, sizeof(hdr));

629
	if (pccb->datalen <= 35)
J
Jin Zhengxiong 已提交
630 631
		return 0;

632
	memset(fis, 0, sizeof(fis));
J
Jin Zhengxiong 已提交
633
	/* Construct the FIS */
634 635 636
	fis[0] = 0x27;		/* Host to device FIS. */
	fis[1] = 1 << 7;	/* Command FIS. */
	fis[2] = ATA_CMD_IDENT;	/* Command byte. */
J
Jin Zhengxiong 已提交
637 638 639

	/* Read id from sata */
	port = pccb->target;
640
	if (!(tmpid = malloc(sizeof(hd_driveid_t))))
J
Jin Zhengxiong 已提交
641 642
		return -ENOMEM;

643
	if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), tmpid,
644
				sizeof(hd_driveid_t), 0)) {
J
Jin Zhengxiong 已提交
645
		debug("scsi_ahci: SCSI inquiry command failure.\n");
646
		free(tmpid);
J
Jin Zhengxiong 已提交
647 648 649
		return -EIO;
	}

650
	if (ataid[port])
J
Jin Zhengxiong 已提交
651
		free(ataid[port]);
652
	ataid[port] = (hd_driveid_t *) tmpid;
J
Jin Zhengxiong 已提交
653 654

	memcpy(&pccb->pdata[8], "ATA     ", 8);
655 656
	ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
	ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
J
Jin Zhengxiong 已提交
657 658 659 660 661 662 663

	dump_ataid(ataid[port]);
	return 0;
}


/*
664
 * SCSI READ10/WRITE10 command operation.
J
Jin Zhengxiong 已提交
665
 */
666
static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
J
Jin Zhengxiong 已提交
667
{
668 669
	u32 lba = 0;
	u16 blocks = 0;
J
Jin Zhengxiong 已提交
670
	u8 fis[20];
671 672
	u8 *user_buffer = pccb->pdata;
	u32 user_buffer_size = pccb->datalen;
J
Jin Zhengxiong 已提交
673

674 675 676
	/* Retrieve the base LBA number from the ccb structure. */
	memcpy(&lba, pccb->cmd + 2, sizeof(lba));
	lba = be32_to_cpu(lba);
J
Jin Zhengxiong 已提交
677

678 679 680 681
	/*
	 * And the number of blocks.
	 *
	 * For 10-byte and 16-byte SCSI R/W commands, transfer
J
Jin Zhengxiong 已提交
682 683 684 685 686 687
	 * length 0 means transfer 0 block of data.
	 * However, for ATA R/W commands, sector count 0 means
	 * 256 or 65536 sectors, not 0 sectors as in SCSI.
	 *
	 * WARNING: one or two older ATA drives treat 0 as 0...
	 */
688 689
	blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);

690 691
	debug("scsi_ahci: %s %d blocks starting from lba 0x%x\n",
	      is_write ?  "write" : "read", (unsigned)lba, blocks);
692 693

	/* Preset the FIS */
694
	memset(fis, 0, sizeof(fis));
695 696
	fis[0] = 0x27;		 /* Host to device FIS. */
	fis[1] = 1 << 7;	 /* Command FIS. */
697
	/* Command byte (read/write). */
698
	fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
J
Jin Zhengxiong 已提交
699

700 701 702 703
	while (blocks) {
		u16 now_blocks; /* number of blocks per iteration */
		u32 transfer_size; /* number of bytes per iteration */

704
		now_blocks = min(MAX_SATA_BLOCKS_READ_WRITE, blocks);
705 706 707 708 709 710 711

		transfer_size = ATA_BLOCKSIZE * now_blocks;
		if (transfer_size > user_buffer_size) {
			printf("scsi_ahci: Error: buffer too small.\n");
			return -EIO;
		}

712 713 714
		/* LBA48 SATA command but only use 32bit address range within
		 * that. The next smaller command range (28bit) is too small.
		 */
715 716 717
		fis[4] = (lba >> 0) & 0xff;
		fis[5] = (lba >> 8) & 0xff;
		fis[6] = (lba >> 16) & 0xff;
718 719 720
		fis[7] = 1 << 6; /* device reg: set LBA mode */
		fis[8] = ((lba >> 24) & 0xff);
		fis[3] = 0xe0; /* features */
721 722 723 724 725

		/* Block (sector) count */
		fis[12] = (now_blocks >> 0) & 0xff;
		fis[13] = (now_blocks >> 8) & 0xff;

726 727 728 729 730 731
		/* Read/Write from ahci */
		if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
					user_buffer, user_buffer_size,
					is_write)) {
			debug("scsi_ahci: SCSI %s10 command failure.\n",
			      is_write ? "WRITE" : "READ");
732 733
			return -EIO;
		}
734 735 736 737 738 739 740 741 742 743 744

		/* If this transaction is a write, do a following flush.
		 * Writes in u-boot are so rare, and the logic to know when is
		 * the last write and do a flush only there is sufficiently
		 * difficult. Just do a flush after every write. This incurs,
		 * usually, one extra flush when the rare writes do happen.
		 */
		if (is_write) {
			if (-EIO == ata_io_flush(pccb->target))
				return -EIO;
		}
745 746 747 748
		user_buffer += transfer_size;
		user_buffer_size -= transfer_size;
		blocks -= now_blocks;
		lba += now_blocks;
J
Jin Zhengxiong 已提交
749 750 751 752 753 754 755 756 757 758 759
	}

	return 0;
}


/*
 * SCSI READ CAPACITY10 command operation.
 */
static int ata_scsiop_read_capacity10(ccb *pccb)
{
K
Kumar Gala 已提交
760
	u32 cap;
761
	u32 block_size;
J
Jin Zhengxiong 已提交
762

763
	if (!ataid[pccb->target]) {
J
Jin Zhengxiong 已提交
764
		printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
765 766
		       "\tNo ATA info!\n"
		       "\tPlease run SCSI commmand INQUIRY firstly!\n");
J
Jin Zhengxiong 已提交
767 768 769
		return -EPERM;
	}

770 771 772 773 774 775 776 777 778 779 780 781
	cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
	if (cap == 0xfffffff) {
		unsigned short *cap48 = ataid[pccb->target]->lba48_capacity;
		if (cap48[2] || cap48[3]) {
			cap = 0xffffffff;
		} else {
			cap = (le16_to_cpu(cap48[1]) << 16) |
			      (le16_to_cpu(cap48[0]));
		}
	}

	cap = cpu_to_be32(cap);
K
Kumar Gala 已提交
782
	memcpy(pccb->pdata, &cap, sizeof(cap));
J
Jin Zhengxiong 已提交
783

784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
	block_size = cpu_to_be32((u32)512);
	memcpy(&pccb->pdata[4], &block_size, 4);

	return 0;
}


/*
 * SCSI READ CAPACITY16 command operation.
 */
static int ata_scsiop_read_capacity16(ccb *pccb)
{
	u64 cap;
	u64 block_size;

	if (!ataid[pccb->target]) {
		printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
		       "\tNo ATA info!\n"
		       "\tPlease run SCSI commmand INQUIRY firstly!\n");
		return -EPERM;
	}

	cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
	if (cap == 0xfffffff) {
		memcpy(&cap, ataid[pccb->target]->lba48_capacity, sizeof(cap));
		cap = le64_to_cpu(cap);
	}

	cap = cpu_to_be64(cap);
	memcpy(pccb->pdata, &cap, sizeof(cap));

	block_size = cpu_to_be64((u64)512);
	memcpy(&pccb->pdata[8], &block_size, 8);
J
Jin Zhengxiong 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829

	return 0;
}


/*
 * SCSI TEST UNIT READY command operation.
 */
static int ata_scsiop_test_unit_ready(ccb *pccb)
{
	return (ataid[pccb->target]) ? 0 : -EPERM;
}

830

J
Jin Zhengxiong 已提交
831 832 833 834
int scsi_exec(ccb *pccb)
{
	int ret;

835
	switch (pccb->cmd[0]) {
J
Jin Zhengxiong 已提交
836
	case SCSI_READ10:
837 838 839 840
		ret = ata_scsiop_read_write(pccb, 0);
		break;
	case SCSI_WRITE10:
		ret = ata_scsiop_read_write(pccb, 1);
J
Jin Zhengxiong 已提交
841
		break;
842
	case SCSI_RD_CAPAC10:
J
Jin Zhengxiong 已提交
843 844
		ret = ata_scsiop_read_capacity10(pccb);
		break;
845 846 847
	case SCSI_RD_CAPAC16:
		ret = ata_scsiop_read_capacity16(pccb);
		break;
J
Jin Zhengxiong 已提交
848 849 850 851 852 853 854 855
	case SCSI_TST_U_RDY:
		ret = ata_scsiop_test_unit_ready(pccb);
		break;
	case SCSI_INQUIRY:
		ret = ata_scsiop_inquiry(pccb);
		break;
	default:
		printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
Y
York Sun 已提交
856
		return false;
J
Jin Zhengxiong 已提交
857 858
	}

859 860
	if (ret) {
		debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
Y
York Sun 已提交
861
		return false;
J
Jin Zhengxiong 已提交
862
	}
Y
York Sun 已提交
863
	return true;
J
Jin Zhengxiong 已提交
864 865 866 867 868 869 870 871 872

}


void scsi_low_level_init(int busdevfunc)
{
	int i;
	u32 linkmap;

873
#ifndef CONFIG_SCSI_AHCI_PLAT
J
Jin Zhengxiong 已提交
874
	ahci_init_one(busdevfunc);
875
#endif
J
Jin Zhengxiong 已提交
876 877 878

	linkmap = probe_ent->link_port_map;

879
	for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
880 881 882
		if (((linkmap >> i) & 0x01)) {
			if (ahci_port_start((u8) i)) {
				printf("Can not start port %d\n", i);
J
Jin Zhengxiong 已提交
883 884
				continue;
			}
885
#ifdef CONFIG_AHCI_SETFEATURES_XFER
886
			ahci_set_feature((u8) i);
887
#endif
J
Jin Zhengxiong 已提交
888 889 890 891
		}
	}
}

892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
#ifdef CONFIG_SCSI_AHCI_PLAT
int ahci_init(u32 base)
{
	int i, rc = 0;
	u32 linkmap;

	memset(ataid, 0, sizeof(ataid));

	probe_ent = malloc(sizeof(struct ahci_probe_ent));
	memset(probe_ent, 0, sizeof(struct ahci_probe_ent));

	probe_ent->host_flags = ATA_FLAG_SATA
				| ATA_FLAG_NO_LEGACY
				| ATA_FLAG_MMIO
				| ATA_FLAG_PIO_DMA
				| ATA_FLAG_NO_ATAPI;
	probe_ent->pio_mask = 0x1f;
	probe_ent->udma_mask = 0x7f;	/*Fixme,assume to support UDMA6 */

	probe_ent->mmio_base = base;

	/* initialize adapter */
	rc = ahci_host_init(probe_ent);
	if (rc)
		goto err_out;

	ahci_print_info(probe_ent);

	linkmap = probe_ent->link_port_map;

	for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
		if (((linkmap >> i) & 0x01)) {
			if (ahci_port_start((u8) i)) {
				printf("Can not start port %d\n", i);
				continue;
			}
928
#ifdef CONFIG_AHCI_SETFEATURES_XFER
929
			ahci_set_feature((u8) i);
930
#endif
931 932 933 934 935 936
		}
	}
err_out:
	return rc;
}
#endif
J
Jin Zhengxiong 已提交
937

938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
/*
 * In the general case of generic rotating media it makes sense to have a
 * flush capability. It probably even makes sense in the case of SSDs because
 * one cannot always know for sure what kind of internal cache/flush mechanism
 * is embodied therein. At first it was planned to invoke this after the last
 * write to disk and before rebooting. In practice, knowing, a priori, which
 * is the last write is difficult. Because writing to the disk in u-boot is
 * very rare, this flush command will be invoked after every block write.
 */
static int ata_io_flush(u8 port)
{
	u8 fis[20];
	struct ahci_ioports *pp = &(probe_ent->port[port]);
	volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
	u32 cmd_fis_len = 5;	/* five dwords */

	/* Preset the FIS */
	memset(fis, 0, 20);
	fis[0] = 0x27;		 /* Host to device FIS. */
	fis[1] = 1 << 7;	 /* Command FIS. */
958
	fis[2] = ATA_CMD_FLUSH_EXT;
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973

	memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
	ahci_fill_cmd_slot(pp, cmd_fis_len);
	writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);

	if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
			WAIT_MS_FLUSH, 0x1)) {
		debug("scsi_ahci: flush command timeout on port %d.\n", port);
		return -EIO;
	}

	return 0;
}


J
Jin Zhengxiong 已提交
974 975
void scsi_bus_reset(void)
{
976
	/*Not implement*/
J
Jin Zhengxiong 已提交
977 978 979
}


980
void scsi_print_error(ccb * pccb)
J
Jin Zhengxiong 已提交
981
{
982
	/*The ahci error info can be read in the ahci driver*/
J
Jin Zhengxiong 已提交
983
}