Lines Matching +full:mmio +full:- +full:mux

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * AppliedMicro X-Gene SoC SATA Host Controller Driver
20 #define DRV_NAME "xgene-ahci"
25 /* MUX CSR */
86 void __iomem *csr_mux; /* MUX CSR address of IP */
91 dev_dbg(ctx->dev, "Release memory from shutdown\n"); in xgene_ahci_init_memram()
92 writel(0x0, ctx->csr_diag + CFG_MEM_RAM_SHUTDOWN); in xgene_ahci_init_memram()
93 readl(ctx->csr_diag + CFG_MEM_RAM_SHUTDOWN); /* Force a barrier */ in xgene_ahci_init_memram()
95 if (readl(ctx->csr_diag + BLOCK_MEM_RDY) != 0xFFFFFFFF) { in xgene_ahci_init_memram()
96 dev_err(ctx->dev, "failed to release memory from shutdown\n"); in xgene_ahci_init_memram()
97 return -ENODEV; in xgene_ahci_init_memram()
103 * xgene_ahci_poll_reg_val- Poll a register on a specific value.
129 * xgene_ahci_restart_engine - Restart the dma engine.
137 struct ahci_host_priv *hpriv = ap->host->private_data; in xgene_ahci_restart_engine()
138 struct ahci_port_priv *pp = ap->private_data; in xgene_ahci_restart_engine()
150 return -EBUSY; in xgene_ahci_restart_engine()
152 hpriv->stop_engine(ap); in xgene_ahci_restart_engine()
159 if (pp->fbs_supported) { in xgene_ahci_restart_engine()
165 hpriv->start_engine(ap); in xgene_ahci_restart_engine()
171 * xgene_ahci_qc_issue - Issue commands to the device
188 struct ata_port *ap = qc->ap; in xgene_ahci_qc_issue()
189 struct ahci_host_priv *hpriv = ap->host->private_data; in xgene_ahci_qc_issue()
190 struct xgene_ahci_context *ctx = hpriv->plat_data; in xgene_ahci_qc_issue()
199 if (ctx->class[ap->port_no] == ATA_DEV_PMP) { in xgene_ahci_qc_issue()
202 port_fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET; in xgene_ahci_qc_issue()
206 if (unlikely((ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA) || in xgene_ahci_qc_issue()
207 (ctx->last_cmd[ap->port_no] == ATA_CMD_PACKET) || in xgene_ahci_qc_issue()
208 (ctx->last_cmd[ap->port_no] == ATA_CMD_SMART))) in xgene_ahci_qc_issue()
214 ctx->last_cmd[ap->port_no] = qc->tf.command; in xgene_ahci_qc_issue()
221 void __iomem *diagcsr = ctx->csr_diag; in xgene_ahci_is_memram_inited()
228 * xgene_ahci_read_id - Read ID data from the specified device
247 * bit15-8: reserved in xgene_ahci_read_id()
251 * bit4: In-order sata delivery supported in xgene_ahci_read_id()
253 * bit2: DMA Setup FIS Auto-Activate optimization supported in xgene_ahci_read_id()
254 * bit1: DMA Setup FIX non-Zero buffer offsets supported in xgene_ahci_read_id()
266 void __iomem *mmio = ctx->hpriv->mmio; in xgene_ahci_set_phy_cfg() local
269 dev_dbg(ctx->dev, "port configure mmio 0x%p channel %d\n", in xgene_ahci_set_phy_cfg()
270 mmio, channel); in xgene_ahci_set_phy_cfg()
271 val = readl(mmio + PORTCFG); in xgene_ahci_set_phy_cfg()
273 writel(val, mmio + PORTCFG); in xgene_ahci_set_phy_cfg()
274 readl(mmio + PORTCFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
276 writel(0x0001fffe, mmio + PORTPHY1CFG); in xgene_ahci_set_phy_cfg()
277 readl(mmio + PORTPHY1CFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
278 writel(0x28183219, mmio + PORTPHY2CFG); in xgene_ahci_set_phy_cfg()
279 readl(mmio + PORTPHY2CFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
280 writel(0x13081008, mmio + PORTPHY3CFG); in xgene_ahci_set_phy_cfg()
281 readl(mmio + PORTPHY3CFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
282 writel(0x00480815, mmio + PORTPHY4CFG); in xgene_ahci_set_phy_cfg()
283 readl(mmio + PORTPHY4CFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
285 val = readl(mmio + PORTPHY5CFG); in xgene_ahci_set_phy_cfg()
287 writel(val, mmio + PORTPHY5CFG); in xgene_ahci_set_phy_cfg()
288 readl(mmio + PORTPHY5CFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
289 val = readl(mmio + PORTAXICFG); in xgene_ahci_set_phy_cfg()
292 writel(val, mmio + PORTAXICFG); in xgene_ahci_set_phy_cfg()
293 readl(mmio + PORTAXICFG); /* Force a barrier */ in xgene_ahci_set_phy_cfg()
295 val = readl(mmio + PORTRANSCFG); in xgene_ahci_set_phy_cfg()
297 writel(val, mmio + PORTRANSCFG); in xgene_ahci_set_phy_cfg()
301 * xgene_ahci_do_hardreset - Issue the actual COMRESET
307 * required for each supported disk speed - Gen3 (6.0Gbps), Gen2 (3.0Gbps),
350 const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context); in xgene_ahci_do_hardreset()
351 struct ata_port *ap = link->ap; in xgene_ahci_do_hardreset()
352 struct ahci_host_priv *hpriv = ap->host->private_data; in xgene_ahci_do_hardreset()
353 struct xgene_ahci_context *ctx = hpriv->plat_data; in xgene_ahci_do_hardreset()
354 struct ahci_port_priv *pp = ap->private_data; in xgene_ahci_do_hardreset()
355 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; in xgene_ahci_do_hardreset()
364 ata_tf_init(link->device, &tf); in xgene_ahci_do_hardreset()
372 dev_warn(ctx->dev, "link has error\n"); in xgene_ahci_do_hardreset()
390 struct ata_port *ap = link->ap; in xgene_ahci_hardreset()
391 struct ahci_host_priv *hpriv = ap->host->private_data; in xgene_ahci_hardreset()
408 hpriv->stop_engine(ap); in xgene_ahci_hardreset()
419 hpriv->start_engine(ap); in xgene_ahci_hardreset()
429 struct ahci_host_priv *hpriv = host->private_data; in xgene_ahci_host_stop()
435 * xgene_ahci_pmp_softreset - Issue the softreset to the drives connected
452 struct ata_port *ap = link->ap; in xgene_ahci_pmp_softreset()
472 * xgene_ahci_softreset - Issue the softreset to the drive.
486 * 0xF for both PMP/NON-PMP initially
496 struct ata_port *ap = link->ap; in xgene_ahci_softreset()
497 struct ahci_host_priv *hpriv = ap->host->private_data; in xgene_ahci_softreset()
498 struct xgene_ahci_context *ctx = hpriv->plat_data; in xgene_ahci_softreset()
520 ctx->class[ap->port_no] = *class; in xgene_ahci_softreset()
526 if (retry--) { in xgene_ahci_softreset()
536 * xgene_ahci_handle_broken_edge_irq - Handle the broken irq.
562 struct ahci_host_priv *hpriv = host->private_data; in xgene_ahci_handle_broken_edge_irq()
566 if (!readl(hpriv->mmio + HOST_IRQ_STAT)) { in xgene_ahci_handle_broken_edge_irq()
567 for (i = 0; i < host->n_ports; i++) { in xgene_ahci_handle_broken_edge_irq()
571 port_mmio = ahci_port_base(host->ports[i]); in xgene_ahci_handle_broken_edge_irq()
585 void __iomem *mmio; in xgene_ahci_irq_intr() local
588 hpriv = host->private_data; in xgene_ahci_irq_intr()
589 mmio = hpriv->mmio; in xgene_ahci_irq_intr()
592 irq_stat = readl(mmio + HOST_IRQ_STAT); in xgene_ahci_irq_intr()
596 irq_masked = irq_stat & hpriv->port_map; in xgene_ahci_irq_intr()
598 spin_lock(&host->lock); in xgene_ahci_irq_intr()
604 writel(irq_stat, mmio + HOST_IRQ_STAT); in xgene_ahci_irq_intr()
608 spin_unlock(&host->lock); in xgene_ahci_irq_intr()
646 struct xgene_ahci_context *ctx = hpriv->plat_data; in xgene_ahci_hw_init()
660 writel(0xffffffff, hpriv->mmio + HOST_IRQ_STAT); in xgene_ahci_hw_init()
661 readl(hpriv->mmio + HOST_IRQ_STAT); /* Force a barrier */ in xgene_ahci_hw_init()
662 writel(0, ctx->csr_core + INTSTATUSMASK); in xgene_ahci_hw_init()
663 val = readl(ctx->csr_core + INTSTATUSMASK); /* Force a barrier */ in xgene_ahci_hw_init()
664 dev_dbg(ctx->dev, "top level interrupt mask 0x%X value 0x%08X\n", in xgene_ahci_hw_init()
667 writel(0x0, ctx->csr_core + ERRINTSTATUSMASK); in xgene_ahci_hw_init()
668 readl(ctx->csr_core + ERRINTSTATUSMASK); /* Force a barrier */ in xgene_ahci_hw_init()
669 writel(0x0, ctx->csr_axi + INT_SLV_TMOMASK); in xgene_ahci_hw_init()
670 readl(ctx->csr_axi + INT_SLV_TMOMASK); in xgene_ahci_hw_init()
673 writel(0xffffffff, ctx->csr_core + SLVRDERRATTRIBUTES); in xgene_ahci_hw_init()
674 writel(0xffffffff, ctx->csr_core + SLVWRERRATTRIBUTES); in xgene_ahci_hw_init()
675 writel(0xffffffff, ctx->csr_core + MSTRDERRATTRIBUTES); in xgene_ahci_hw_init()
676 writel(0xffffffff, ctx->csr_core + MSTWRERRATTRIBUTES); in xgene_ahci_hw_init()
679 val = readl(ctx->csr_core + BUSCTLREG); in xgene_ahci_hw_init()
682 writel(val, ctx->csr_core + BUSCTLREG); in xgene_ahci_hw_init()
684 val = readl(ctx->csr_core + IOFMSTRWAUX); in xgene_ahci_hw_init()
687 writel(val, ctx->csr_core + IOFMSTRWAUX); in xgene_ahci_hw_init()
688 val = readl(ctx->csr_core + IOFMSTRWAUX); in xgene_ahci_hw_init()
689 dev_dbg(ctx->dev, "coherency 0x%X value 0x%08X\n", in xgene_ahci_hw_init()
699 /* Check for optional MUX resource */ in xgene_ahci_mux_select()
700 if (!ctx->csr_mux) in xgene_ahci_mux_select()
703 val = readl(ctx->csr_mux + SATA_ENET_CONFIG_REG); in xgene_ahci_mux_select()
705 writel(val, ctx->csr_mux + SATA_ENET_CONFIG_REG); in xgene_ahci_mux_select()
706 val = readl(ctx->csr_mux + SATA_ENET_CONFIG_REG); in xgene_ahci_mux_select()
707 return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0; in xgene_ahci_mux_select()
724 {.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1},
725 {.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2},
732 struct device *dev = &pdev->dev; in xgene_ahci_probe()
747 return -ENOMEM; in xgene_ahci_probe()
749 hpriv->plat_data = ctx; in xgene_ahci_probe()
750 ctx->hpriv = hpriv; in xgene_ahci_probe()
751 ctx->dev = dev; in xgene_ahci_probe()
754 ctx->csr_core = devm_platform_ioremap_resource(pdev, 1); in xgene_ahci_probe()
755 if (IS_ERR(ctx->csr_core)) in xgene_ahci_probe()
756 return PTR_ERR(ctx->csr_core); in xgene_ahci_probe()
759 ctx->csr_diag = devm_platform_ioremap_resource(pdev, 2); in xgene_ahci_probe()
760 if (IS_ERR(ctx->csr_diag)) in xgene_ahci_probe()
761 return PTR_ERR(ctx->csr_diag); in xgene_ahci_probe()
764 ctx->csr_axi = devm_platform_ioremap_resource(pdev, 3); in xgene_ahci_probe()
765 if (IS_ERR(ctx->csr_axi)) in xgene_ahci_probe()
766 return PTR_ERR(ctx->csr_axi); in xgene_ahci_probe()
768 /* Retrieve the optional IP mux resource */ in xgene_ahci_probe()
775 ctx->csr_mux = csr; in xgene_ahci_probe()
778 if (dev->of_node) { in xgene_ahci_probe()
787 acpi_id = acpi_match_device(xgene_ahci_acpi_match, &pdev->dev); in xgene_ahci_probe()
789 dev_warn(&pdev->dev, "No node entry in ACPI table. Assume version1\n"); in xgene_ahci_probe()
791 } else if (acpi_id->driver_data) { in xgene_ahci_probe()
792 version = (enum xgene_ahci_version) acpi_id->driver_data; in xgene_ahci_probe()
793 status = acpi_get_object_info(ACPI_HANDLE(&pdev->dev), &info); in xgene_ahci_probe()
795 dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", in xgene_ahci_probe()
799 if (info->valid & ACPI_VALID_CID) in xgene_ahci_probe()
807 dev_dbg(dev, "VAddr 0x%p Mmio VAddr 0x%p\n", ctx->csr_core, in xgene_ahci_probe()
808 hpriv->mmio); in xgene_ahci_probe()
812 dev_err(dev, "SATA mux selection failed error %d\n", rc); in xgene_ahci_probe()
813 return -ENODEV; in xgene_ahci_probe()
837 hpriv->flags = AHCI_HFLAG_NO_NCQ; in xgene_ahci_probe()
840 hpriv->flags |= AHCI_HFLAG_YES_FBS; in xgene_ahci_probe()
841 hpriv->irq_handler = xgene_ahci_irq_intr; in xgene_ahci_probe()
847 rc = ahci_platform_init_host(pdev, hpriv, ppi[version - 1], in xgene_ahci_probe()
852 dev_dbg(dev, "X-Gene SATA host controller initialized\n"); in xgene_ahci_probe()
872 MODULE_DESCRIPTION("APM X-Gene AHCI SATA driver");