Lines Matching +full:ahci +full:- +full:port
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Broadcom SATA3 AHCI Controller Driver
5 * Copyright © 2009-2015 Broadcom Corporation
22 #include "ahci.h"
24 #define DRV_NAME "brcm-ahci"
28 #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */
29 #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */
30 #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */
51 /* On big-endian MIPS, buses are reversed to big endian, so switch them back */
53 #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */
54 #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */
97 * bus endianness (i.e., big-endian CPU + big endian bus ==> native in brcm_sata_readreg()
120 struct brcm_ahci_priv *priv = hpriv->plat_data; in brcm_sata_alpm_init()
125 host_caps = readl(hpriv->mmio + HOST_CAP); in brcm_sata_alpm_init()
127 hpriv->flags |= AHCI_HFLAG_YES_ALPM; in brcm_sata_alpm_init()
136 if (priv->port_mask & BIT(i)) in brcm_sata_alpm_init()
138 hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl)); in brcm_sata_alpm_init()
142 static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port) in brcm_sata_phy_enable() argument
144 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + in brcm_sata_phy_enable()
145 (port * SATA_TOP_CTRL_PHY_OFFS); in brcm_sata_phy_enable()
149 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) in brcm_sata_phy_enable()
174 static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port) in brcm_sata_phy_disable() argument
176 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + in brcm_sata_phy_disable()
177 (port * SATA_TOP_CTRL_PHY_OFFS); in brcm_sata_phy_disable()
181 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) in brcm_sata_phy_disable()
184 /* power-off the PHY digital logic */ in brcm_sata_phy_disable()
204 if (priv->port_mask & BIT(i)) in brcm_sata_phys_enable()
213 if (priv->port_mask & BIT(i)) in brcm_sata_phys_disable()
222 impl = readl(hpriv->mmio + HOST_PORTS_IMPL); in brcm_ahci_get_portmask()
225 dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", in brcm_ahci_get_portmask()
228 dev_info(priv->dev, "no ports found\n"); in brcm_ahci_get_portmask()
235 void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL; in brcm_sata_init()
241 if (priv->version == BRCM_SATA_NSP) in brcm_sata_init()
251 struct ata_port *ap = dev->link->ap; in brcm_ahci_read_id()
252 struct ata_host *host = ap->host; in brcm_ahci_read_id()
253 struct ahci_host_priv *hpriv = host->private_data; in brcm_ahci_read_id()
254 struct brcm_ahci_priv *priv = hpriv->plat_data; in brcm_ahci_read_id()
255 void __iomem *mmio = hpriv->mmio; in brcm_ahci_read_id()
269 spin_lock_irqsave(&host->lock, flags); in brcm_ahci_read_id()
274 spin_unlock_irqrestore(&host->lock, flags); in brcm_ahci_read_id()
277 brcm_sata_phy_disable(priv, ap->port_no); in brcm_ahci_read_id()
287 brcm_sata_phy_enable(priv, ap->port_no); in brcm_ahci_read_id()
289 /* Re-initialize and calibrate the PHY */ in brcm_ahci_read_id()
290 for (i = 0; i < hpriv->nports; i++) { in brcm_ahci_read_id()
294 rc = phy_init(hpriv->phys[i]); in brcm_ahci_read_id()
298 rc = phy_calibrate(hpriv->phys[i]); in brcm_ahci_read_id()
300 phy_exit(hpriv->phys[i]); in brcm_ahci_read_id()
305 /* Re-enable host interrupts */ in brcm_ahci_read_id()
306 spin_lock_irqsave(&host->lock, flags); in brcm_ahci_read_id()
311 spin_unlock_irqrestore(&host->lock, flags); in brcm_ahci_read_id()
316 while (--i >= 0) { in brcm_ahci_read_id()
317 phy_power_off(hpriv->phys[i]); in brcm_ahci_read_id()
318 phy_exit(hpriv->phys[i]); in brcm_ahci_read_id()
326 struct ahci_host_priv *hpriv = host->private_data; in brcm_ahci_host_stop()
348 struct ahci_host_priv *hpriv = host->private_data; in brcm_ahci_suspend()
349 struct brcm_ahci_priv *priv = hpriv->plat_data; in brcm_ahci_suspend()
359 reset_control_assert(priv->rcdev_ahci); in brcm_ahci_suspend()
360 reset_control_rearm(priv->rcdev_rescal); in brcm_ahci_suspend()
368 struct ahci_host_priv *hpriv = host->private_data; in brcm_ahci_resume()
369 struct brcm_ahci_priv *priv = hpriv->plat_data; in brcm_ahci_resume()
372 ret = reset_control_deassert(priv->rcdev_ahci); in brcm_ahci_resume()
375 ret = reset_control_reset(priv->rcdev_rescal); in brcm_ahci_resume()
379 /* Make sure clocks are turned on before re-configuration */ in brcm_ahci_resume()
393 * ahci_platform_resume() as-is since a second call to in brcm_ahci_resume()
428 {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
429 {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
430 {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
431 {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
432 {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
440 struct device *dev = &pdev->dev; in brcm_ahci_probe()
447 return -ENOMEM; in brcm_ahci_probe()
449 of_id = of_match_node(ahci_of_match, pdev->dev.of_node); in brcm_ahci_probe()
451 return -ENODEV; in brcm_ahci_probe()
453 priv->version = (unsigned long)of_id->data; in brcm_ahci_probe()
454 priv->dev = dev; in brcm_ahci_probe()
456 priv->top_ctrl = devm_platform_ioremap_resource_byname(pdev, "top-ctrl"); in brcm_ahci_probe()
457 if (IS_ERR(priv->top_ctrl)) in brcm_ahci_probe()
458 return PTR_ERR(priv->top_ctrl); in brcm_ahci_probe()
460 if (priv->version == BRCM_SATA_BCM7216) { in brcm_ahci_probe()
461 priv->rcdev_rescal = devm_reset_control_get_optional_shared( in brcm_ahci_probe()
462 &pdev->dev, "rescal"); in brcm_ahci_probe()
463 if (IS_ERR(priv->rcdev_rescal)) in brcm_ahci_probe()
464 return PTR_ERR(priv->rcdev_rescal); in brcm_ahci_probe()
466 priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci"); in brcm_ahci_probe()
467 if (IS_ERR(priv->rcdev_ahci)) in brcm_ahci_probe()
468 return PTR_ERR(priv->rcdev_ahci); in brcm_ahci_probe()
474 hpriv->plat_data = priv; in brcm_ahci_probe()
475 hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO; in brcm_ahci_probe()
477 switch (priv->version) { in brcm_ahci_probe()
479 hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE; in brcm_ahci_probe()
482 hpriv->flags |= AHCI_HFLAG_NO_NCQ; in brcm_ahci_probe()
483 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; in brcm_ahci_probe()
489 ret = reset_control_reset(priv->rcdev_rescal); in brcm_ahci_probe()
492 ret = reset_control_deassert(priv->rcdev_ahci); in brcm_ahci_probe()
505 * of the standard AHCI register space. in brcm_ahci_probe()
509 /* Initializes priv->port_mask which is used below */ in brcm_ahci_probe()
510 priv->port_mask = brcm_ahci_get_portmask(hpriv, priv); in brcm_ahci_probe()
511 if (!priv->port_mask) { in brcm_ahci_probe()
512 ret = -ENODEV; in brcm_ahci_probe()
530 dev_info(dev, "Broadcom AHCI SATA3 registered\n"); in brcm_ahci_probe()
543 reset_control_assert(priv->rcdev_ahci); in brcm_ahci_probe()
544 reset_control_rearm(priv->rcdev_rescal); in brcm_ahci_probe()
550 struct ata_host *host = dev_get_drvdata(&pdev->dev); in brcm_ahci_remove()
551 struct ahci_host_priv *hpriv = host->private_data; in brcm_ahci_remove()
552 struct brcm_ahci_priv *priv = hpriv->plat_data; in brcm_ahci_remove()
568 ret = brcm_ahci_suspend(&pdev->dev); in brcm_ahci_shutdown()
570 dev_err(&pdev->dev, "failed to shutdown\n"); in brcm_ahci_shutdown()
587 MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
590 MODULE_ALIAS("platform:sata-brcmstb");