X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fblock%2Fahci.c;h=3fa14a76b8871e5785353be38ea64a39e2d7f9f6;hb=4d555ae3f5805f354060c7b0be0557e7ed92c26a;hp=734fdcc3dbd38fddc27a4068adab6fab6c0e0397;hpb=3f42dc87b4fbcc99baa26c7be8d0b74aaa4c2f30;p=oweals%2Fu-boot.git diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 734fdcc3db..3fa14a76b8 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -10,9 +10,10 @@ #include #include +#include #include #include -#include +#include #include #include #include @@ -44,7 +45,7 @@ u16 *ataid[AHCI_MAX_PORTS]; #define WAIT_MS_FLUSH 5000 #define WAIT_MS_LINKUP 200 -static inline void __iomem *ahci_port_base(void __iomem *base, u32 port) +__weak void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); } @@ -167,10 +168,15 @@ int ahci_reset(void __iomem *base) static int ahci_host_init(struct ahci_probe_ent *probe_ent) { -#ifndef CONFIG_SCSI_AHCI_PLAT +#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) +# ifdef CONFIG_DM_PCI + struct udevice *dev = probe_ent->dev; + struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); +# else pci_dev_t pdev = probe_ent->dev; - u16 tmp16; unsigned short vendor; +# endif + u16 tmp16; #endif void __iomem *mmio = probe_ent->mmio_base; u32 tmp, cap_save, cmd; @@ -192,7 +198,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) writel(cap_save, mmio + HOST_CAP); writel_with_flush(0xf, mmio + HOST_PORTS_IMPL); -#ifndef CONFIG_SCSI_AHCI_PLAT +#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) +# ifdef CONFIG_DM_PCI + if (pplat->vendor == PCI_VENDOR_ID_INTEL) { + u16 tmp16; + + dm_pci_read_config16(dev, 0x92, &tmp16); + dm_pci_write_config16(dev, 0x92, tmp16 | 0xf); + } +# else pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor); if (vendor == PCI_VENDOR_ID_INTEL) { @@ -201,6 +215,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) tmp16 |= 0xf; pci_write_config_word(pdev, 0x92, tmp16); } +# endif #endif probe_ent->cap = readl(mmio + HOST_CAP); probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL); @@ -312,10 +327,18 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); tmp = readl(mmio + HOST_CTL); debug("HOST_CTL 0x%x\n", tmp); +#if !defined(CONFIG_DM_SCSI) #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + dm_pci_read_config16(dev, PCI_COMMAND, &tmp16); + tmp |= PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, tmp16); +# else pci_read_config_word(pdev, PCI_COMMAND, &tmp16); tmp |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, tmp16); +# endif +#endif #endif return 0; } @@ -323,8 +346,12 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) static void ahci_print_info(struct ahci_probe_ent *probe_ent) { -#ifndef CONFIG_SCSI_AHCI_PLAT +#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) +# if defined(CONFIG_DM_PCI) + struct udevice *dev = probe_ent->dev; +# else pci_dev_t pdev = probe_ent->dev; +# endif u16 cc; #endif void __iomem *mmio = probe_ent->mmio_base; @@ -347,10 +374,14 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) else speed_s = "?"; -#ifdef CONFIG_SCSI_AHCI_PLAT +#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI) scc_s = "SATA"; #else +# ifdef CONFIG_DM_PCI + dm_pci_read_config16(dev, 0x0a, &cc); +# else pci_read_config_word(pdev, 0x0a, &cc); +# endif if (cc == 0x0101) scc_s = "IDE"; else if (cc == 0x0106) @@ -395,9 +426,15 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) } #ifndef CONFIG_SCSI_AHCI_PLAT -static int ahci_init_one(pci_dev_t pdev) +# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI) +static int ahci_init_one(struct udevice *dev) +# else +static int ahci_init_one(pci_dev_t dev) +# endif { +#if !defined(CONFIG_DM_SCSI) u16 vendor; +#endif int rc; probe_ent = malloc(sizeof(struct ahci_probe_ent)); @@ -407,7 +444,7 @@ static int ahci_init_one(pci_dev_t pdev) } memset(probe_ent, 0, sizeof(struct ahci_probe_ent)); - probe_ent->dev = pdev; + probe_ent->dev = dev; probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY @@ -417,18 +454,36 @@ static int ahci_init_one(pci_dev_t pdev) probe_ent->pio_mask = 0x1f; probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ - probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5, +#if !defined(CONFIG_DM_SCSI) +#ifdef CONFIG_DM_PCI + probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5, + PCI_REGION_MEM); + + /* Take from kernel: + * JMicron-specific fixup: + * make sure we're in AHCI mode + */ + dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor); + if (vendor == 0x197b) + dm_pci_write_config8(dev, 0x41, 0xa1); +#else + probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5, PCI_REGION_MEM); - debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base); /* Take from kernel: * JMicron-specific fixup: * make sure we're in AHCI mode */ - pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor); + pci_read_config_word(dev, PCI_VENDOR_ID, &vendor); if (vendor == 0x197b) - pci_write_config_byte(pdev, 0x41, 0xa1); + pci_write_config_byte(dev, 0x41, 0xa1); +#endif +#else + struct scsi_platdata *plat = dev_get_platdata(dev); + probe_ent->mmio_base = (void *)plat->base; +#endif + debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base); /* initialize adapter */ rc = ahci_host_init(probe_ent); if (rc) @@ -818,7 +873,7 @@ static int ata_scsiop_read_capacity10(ccb *pccb) if (!ataid[pccb->target]) { printf("scsi_ahci: SCSI READ CAPACITY10 command failure. " "\tNo ATA info!\n" - "\tPlease run SCSI command INQUIRY firstly!\n"); + "\tPlease run SCSI command INQUIRY first!\n"); return -EPERM; } @@ -847,7 +902,7 @@ static int ata_scsiop_read_capacity16(ccb *pccb) if (!ataid[pccb->target]) { printf("scsi_ahci: SCSI READ CAPACITY16 command failure. " "\tNo ATA info!\n" - "\tPlease run SCSI command INQUIRY firstly!\n"); + "\tPlease run SCSI command INQUIRY first!\n"); return -EPERM; } @@ -908,14 +963,29 @@ int scsi_exec(ccb *pccb) } - +#if defined(CONFIG_DM_SCSI) +void scsi_low_level_init(int busdevfunc, struct udevice *dev) +#else void scsi_low_level_init(int busdevfunc) +#endif { int i; u32 linkmap; #ifndef CONFIG_SCSI_AHCI_PLAT +# if defined(CONFIG_DM_PCI) + struct udevice *dev; + int ret; + + ret = dm_pci_bus_find_bdf(busdevfunc, &dev); + if (ret) + return; + ahci_init_one(dev); +# elif defined(CONFIG_DM_SCSI) + ahci_init_one(dev); +# else ahci_init_one(busdevfunc); +# endif #endif linkmap = probe_ent->link_port_map; @@ -1005,6 +1075,7 @@ static int ata_io_flush(u8 port) memcpy((unsigned char *)pp->cmd_tbl, fis, 20); ahci_fill_cmd_slot(pp, cmd_fis_len); + ahci_dcache_flush_sata_cmd(pp); writel_with_flush(1, port_mmio + PORT_CMD_ISSUE); if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,