Lines Matching +full:sata +full:- +full:port
1 // SPDX-License-Identifier: GPL-2.0+
9 * This driver provides a SCSI interface to SATA.
30 #include <dm/device-internal.h>
33 static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port);
59 __weak void __iomem *ahci_port_base(void __iomem *base, u32 port) in ahci_port_base() argument
61 return base + 0x100 + (port * 0x80); in ahci_port_base()
76 * SATA controller DMAs to physical RAM. Ensure data from the
90 * Ensure data for SATA controller is flushed out of dcache and
95 ahci_dcache_flush_range((unsigned long)pp->cmd_slot, in ahci_dcache_flush_sata_cmd()
109 return (i < timeout_msec) ? 0 : -1; in waiting_for_cmd_completed()
112 int __weak ahci_link_up(struct ahci_uc_priv *uc_priv, u8 port) in ahci_link_up() argument
116 void __iomem *port_mmio = uc_priv->port[port].port_mmio; in ahci_link_up()
119 * Bring up SATA link. in ahci_link_up()
120 * SATA link bringup time is usually less than 1 ms; only very in ahci_link_up()
121 * rarely has it taken between 1-2 ms. Never seen it above 2 ms. in ahci_link_up()
158 i--; in ahci_reset()
163 return -1; in ahci_reset()
173 struct udevice *dev = uc_priv->dev; in ahci_host_init()
176 pci_dev_t pdev = uc_priv->dev; in ahci_host_init()
181 void __iomem *mmio = uc_priv->mmio_base; in ahci_host_init()
191 cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */ in ahci_host_init()
193 ret = ahci_reset(uc_priv->mmio_base); in ahci_host_init()
203 if (pplat->vendor == PCI_VENDOR_ID_INTEL) { in ahci_host_init()
220 uc_priv->cap = readl(mmio + HOST_CAP); in ahci_host_init()
221 uc_priv->port_map = readl(mmio + HOST_PORTS_IMPL); in ahci_host_init()
222 port_map = uc_priv->port_map; in ahci_host_init()
223 uc_priv->n_ports = (uc_priv->cap & 0x1f) + 1; in ahci_host_init()
226 uc_priv->cap, uc_priv->port_map, uc_priv->n_ports); in ahci_host_init()
229 if (uc_priv->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID) in ahci_host_init()
230 uc_priv->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID; in ahci_host_init()
233 for (i = 0; i < uc_priv->n_ports; i++) { in ahci_host_init()
236 uc_priv->port[i].port_mmio = ahci_port_base(mmio, i); in ahci_host_init()
237 port_mmio = (u8 *)uc_priv->port[i].port_mmio; in ahci_host_init()
239 /* make sure port is not active */ in ahci_host_init()
243 debug("Port %d is active. Deactivating.\n", i); in ahci_host_init()
265 /* Bring up SATA link. */ in ahci_host_init()
268 printf("SATA link %d timeout.\n", i); in ahci_host_init()
271 debug("SATA link ok.\n"); in ahci_host_init()
279 debug("Spinning up device on SATA port %d... ", i); in ahci_host_init()
296 debug("SATA link %d down (COMINIT received), retrying...\n", i); in ahci_host_init()
297 i--; in ahci_host_init()
311 /* ack any pending irq events for this port */ in ahci_host_init()
321 debug("SATA port %d status: 0x%x\n", i, tmp); in ahci_host_init()
323 uc_priv->link_port_map |= (0x01 << i); in ahci_host_init()
352 struct udevice *dev = uc_priv->dev; in ahci_print_info()
354 pci_dev_t pdev = uc_priv->dev; in ahci_print_info()
358 void __iomem *mmio = uc_priv->mmio_base; in ahci_print_info()
364 cap = uc_priv->cap; in ahci_print_info()
366 impl = uc_priv->port_map; in ahci_print_info()
379 scc_s = "SATA"; in ahci_print_info()
389 scc_s = "SATA"; in ahci_print_info()
441 uc_priv->dev = dev; in ahci_init_one()
443 uc_priv->host_flags = ATA_FLAG_SATA in ahci_init_one()
448 uc_priv->pio_mask = 0x1f; in ahci_init_one()
449 uc_priv->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ in ahci_init_one()
453 uc_priv->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5, in ahci_init_one()
457 * JMicron-specific fixup: in ahci_init_one()
464 uc_priv->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5, in ahci_init_one()
468 * JMicron-specific fixup: in ahci_init_one()
477 uc_priv->mmio_base = (void *)plat->base; in ahci_init_one()
480 debug("ahci mmio_base=0x%p\n", uc_priv->mmio_base); in ahci_init_one()
497 static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, in ahci_fill_sg() argument
500 struct ahci_ioports *pp = &(uc_priv->port[port]); in ahci_fill_sg()
501 struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; in ahci_fill_sg()
505 sg_count = ((buf_len - 1) / MAX_DATA_BYTE_COUNT) + 1; in ahci_fill_sg()
508 return -1; in ahci_fill_sg()
515 ahci_sg->addr = cpu_to_le32(lower_32_bits(pa)); in ahci_fill_sg()
516 ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa)); in ahci_fill_sg()
517 if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) { in ahci_fill_sg()
519 return -1; in ahci_fill_sg()
521 ahci_sg->flags_size = cpu_to_le32(0x3fffff & in ahci_fill_sg()
523 ? (buf_len - 1) in ahci_fill_sg()
524 : (MAX_DATA_BYTE_COUNT - 1))); in ahci_fill_sg()
526 buf_len -= MAX_DATA_BYTE_COUNT; in ahci_fill_sg()
535 pp->cmd_slot->opts = cpu_to_le32(opts); in ahci_fill_cmd_slot()
536 pp->cmd_slot->status = 0; in ahci_fill_cmd_slot()
537 pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff); in ahci_fill_cmd_slot()
539 pp->cmd_slot->tbl_addr_hi = in ahci_fill_cmd_slot()
540 cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16)); in ahci_fill_cmd_slot()
556 return -ETIMEDOUT; in wait_spinup()
559 static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) in ahci_port_start() argument
561 struct ahci_ioports *pp = &(uc_priv->port[port]); in ahci_port_start()
562 void __iomem *port_mmio = pp->port_mmio; in ahci_port_start()
567 debug("Enter start port: %d\n", port); in ahci_port_start()
569 debug("Port %d status: %x\n", port, port_status); in ahci_port_start()
571 printf("No Link on this port!\n"); in ahci_port_start()
572 return -1; in ahci_port_start()
579 return -ENOMEM; in ahci_port_start()
584 * First item in chunk of DMA memory: 32-slot command table, in ahci_port_start()
587 pp->cmd_slot = in ahci_port_start()
589 debug("cmd_slot = %p\n", pp->cmd_slot); in ahci_port_start()
593 * Second item: Received-FIS area in ahci_port_start()
595 pp->rx_fis = virt_to_phys((void *)mem); in ahci_port_start()
600 * and its scatter-gather table in ahci_port_start()
602 pp->cmd_tbl = virt_to_phys((void *)mem); in ahci_port_start()
603 debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl); in ahci_port_start()
606 pp->cmd_tbl_sg = in ahci_port_start()
609 dma_addr = (ulong)pp->cmd_slot; in ahci_port_start()
612 dma_addr = (ulong)pp->rx_fis; in ahci_port_start()
624 debug("Exit start port %d\n", port); in ahci_port_start()
634 static int ahci_device_data_io(struct ahci_uc_priv *uc_priv, u8 port, u8 *fis, in ahci_device_data_io() argument
638 struct ahci_ioports *pp = &(uc_priv->port[port]); in ahci_device_data_io()
639 void __iomem *port_mmio = pp->port_mmio; in ahci_device_data_io()
644 debug("Enter %s: for port %d\n", __func__, port); in ahci_device_data_io()
646 if (port > uc_priv->n_ports) { in ahci_device_data_io()
647 printf("Invalid port number %d\n", port); in ahci_device_data_io()
648 return -1; in ahci_device_data_io()
653 debug("No Link on port %d!\n", port); in ahci_device_data_io()
654 return -1; in ahci_device_data_io()
657 memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len); in ahci_device_data_io()
659 sg_count = ahci_fill_sg(uc_priv, port, buf, buf_len); in ahci_device_data_io()
671 return -1; in ahci_device_data_io()
676 debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status); in ahci_device_data_io()
699 0x5, /* claim SPC-3 version compatibility */ in ata_scsiop_inquiry()
701 95 - 4, in ata_scsiop_inquiry()
706 u8 port; in ata_scsiop_inquiry() local
709 memset(pccb->pdata, 0, pccb->datalen); in ata_scsiop_inquiry()
711 memcpy(pccb->pdata, hdr, sizeof(hdr)); in ata_scsiop_inquiry()
713 if (pccb->datalen <= 35) in ata_scsiop_inquiry()
722 /* Read id from sata */ in ata_scsiop_inquiry()
723 port = pccb->target; in ata_scsiop_inquiry()
725 if (ahci_device_data_io(uc_priv, port, (u8 *)&fis, sizeof(fis), in ata_scsiop_inquiry()
728 return -EIO; in ata_scsiop_inquiry()
731 if (!uc_priv->ataid[port]) { in ata_scsiop_inquiry()
732 uc_priv->ataid[port] = malloc(ATA_ID_WORDS * 2); in ata_scsiop_inquiry()
733 if (!uc_priv->ataid[port]) { in ata_scsiop_inquiry()
734 printf("%s: No memory for ataid[port]\n", __func__); in ata_scsiop_inquiry()
735 return -ENOMEM; in ata_scsiop_inquiry()
739 idbuf = uc_priv->ataid[port]; in ata_scsiop_inquiry()
744 memcpy(&pccb->pdata[8], "ATA ", 8); in ata_scsiop_inquiry()
745 ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16); in ata_scsiop_inquiry()
746 ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4); in ata_scsiop_inquiry()
764 u8 *user_buffer = pccb->pdata; in ata_scsiop_read_write()
765 u32 user_buffer_size = pccb->datalen; in ata_scsiop_read_write()
768 if (pccb->cmd[0] == SCSI_READ16) { in ata_scsiop_read_write()
769 memcpy(&lba, pccb->cmd + 2, 8); in ata_scsiop_read_write()
773 memcpy(&temp, pccb->cmd + 2, 4); in ata_scsiop_read_write()
781 * For 10-byte and 16-byte SCSI R/W commands, transfer in ata_scsiop_read_write()
788 if (pccb->cmd[0] == SCSI_READ16) in ata_scsiop_read_write()
789 blocks = (((u16)pccb->cmd[13]) << 8) | ((u16) pccb->cmd[14]); in ata_scsiop_read_write()
791 blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]); in ata_scsiop_read_write()
812 return -EIO; in ata_scsiop_read_write()
816 * LBA48 SATA command but only use 32bit address range within in ata_scsiop_read_write()
826 if (pccb->cmd[0] == SCSI_READ16) { in ata_scsiop_read_write()
839 if (ahci_device_data_io(uc_priv, pccb->target, (u8 *)&fis, in ata_scsiop_read_write()
844 return -EIO; in ata_scsiop_read_write()
848 * Writes in u-boot are so rare, and the logic to know when is in ata_scsiop_read_write()
854 if (-EIO == ata_io_flush(uc_priv, pccb->target)) in ata_scsiop_read_write()
855 return -EIO; in ata_scsiop_read_write()
858 user_buffer_size -= transfer_size; in ata_scsiop_read_write()
859 blocks -= now_blocks; in ata_scsiop_read_write()
877 if (!uc_priv->ataid[pccb->target]) { in ata_scsiop_read_capacity10()
881 return -EPERM; in ata_scsiop_read_capacity10()
884 cap64 = ata_id_n_sectors(uc_priv->ataid[pccb->target]); in ata_scsiop_read_capacity10()
889 memcpy(pccb->pdata, &cap, sizeof(cap)); in ata_scsiop_read_capacity10()
892 memcpy(&pccb->pdata[4], &block_size, 4); in ata_scsiop_read_capacity10()
907 if (!uc_priv->ataid[pccb->target]) { in ata_scsiop_read_capacity16()
911 return -EPERM; in ata_scsiop_read_capacity16()
914 cap = ata_id_n_sectors(uc_priv->ataid[pccb->target]); in ata_scsiop_read_capacity16()
916 memcpy(pccb->pdata, &cap, sizeof(cap)); in ata_scsiop_read_capacity16()
919 memcpy(&pccb->pdata[8], &block_size, 8); in ata_scsiop_read_capacity16()
931 return (uc_priv->ataid[pccb->target]) ? 0 : -EPERM; in ata_scsiop_test_unit_ready()
939 uc_priv = dev_get_uclass_priv(dev->parent); in ahci_scsi_exec()
945 switch (pccb->cmd[0]) { in ahci_scsi_exec()
966 printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]); in ahci_scsi_exec()
967 return -ENOTSUPP; in ahci_scsi_exec()
971 debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret); in ahci_scsi_exec()
983 linkmap = uc_priv->link_port_map; in ahci_start_ports()
985 for (i = 0; i < uc_priv->n_ports; i++) { in ahci_start_ports()
988 printf("Can not start port %d\n", i); in ahci_start_ports()
1051 uc_priv->host_flags = ATA_FLAG_SATA in ahci_init_common()
1056 uc_priv->pio_mask = 0x1f; in ahci_init_common()
1057 uc_priv->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ in ahci_init_common()
1059 uc_priv->mmio_base = base; in ahci_init_common()
1082 return -ENOMEM; in ahci_init()
1111 * is the last write is difficult. Because writing to the disk in u-boot is
1114 static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port) in ata_io_flush() argument
1117 struct ahci_ioports *pp = &(uc_priv->port[port]); in ata_io_flush()
1118 void __iomem *port_mmio = pp->port_mmio; in ata_io_flush()
1127 memcpy((unsigned char *)pp->cmd_tbl, fis, 20); in ata_io_flush()
1134 debug("scsi_ahci: flush command timeout on port %d.\n", port); in ata_io_flush()
1135 return -EIO; in ata_io_flush()
1171 return -ENODEV; in ahci_probe_scsi()
1173 uc_plat->base = base; in ahci_probe_scsi()
1174 uc_plat->max_lun = 1; in ahci_probe_scsi()
1175 uc_plat->max_id = 2; in ahci_probe_scsi()
1186 * scsi_scan_dev() scans devices up-to the number of max_id. in ahci_probe_scsi()
1190 uc_plat->max_id = max_t(unsigned long, uc_priv->n_ports, in ahci_probe_scsi()
1191 uc_plat->max_id); in ahci_probe_scsi()
1192 /* If port count is less than max_id, update max_id */ in ahci_probe_scsi()
1193 if (uc_priv->n_ports < uc_plat->max_id) in ahci_probe_scsi()
1194 uc_plat->max_id = uc_priv->n_ports; in ahci_probe_scsi()