Lines Matching +full:dt +full:- +full:mmio

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2004-2005 Red Hat, Inc.
37 * ahci_platform_enable_phys - Enable PHYs
40 * This function enables all the PHYs found in hpriv->phys, if any.
51 for (i = 0; i < hpriv->nports; i++) { in ahci_platform_enable_phys()
52 rc = phy_init(hpriv->phys[i]); in ahci_platform_enable_phys()
56 rc = phy_set_mode(hpriv->phys[i], PHY_MODE_SATA); in ahci_platform_enable_phys()
58 phy_exit(hpriv->phys[i]); in ahci_platform_enable_phys()
62 rc = phy_power_on(hpriv->phys[i]); in ahci_platform_enable_phys()
64 phy_exit(hpriv->phys[i]); in ahci_platform_enable_phys()
72 while (--i >= 0) { in ahci_platform_enable_phys()
73 phy_power_off(hpriv->phys[i]); in ahci_platform_enable_phys()
74 phy_exit(hpriv->phys[i]); in ahci_platform_enable_phys()
81 * ahci_platform_disable_phys - Disable PHYs
84 * This function disables all PHYs found in hpriv->phys.
90 for (i = 0; i < hpriv->nports; i++) { in ahci_platform_disable_phys()
91 phy_power_off(hpriv->phys[i]); in ahci_platform_disable_phys()
92 phy_exit(hpriv->phys[i]); in ahci_platform_disable_phys()
98 * ahci_platform_find_clk - Find platform clock
112 for (i = 0; i < hpriv->n_clks; i++) { in ahci_platform_find_clk()
113 if (hpriv->clks[i].id && !strcmp(hpriv->clks[i].id, con_id)) in ahci_platform_find_clk()
114 return hpriv->clks[i].clk; in ahci_platform_find_clk()
122 * ahci_platform_enable_clks - Enable platform clocks
132 return clk_bulk_prepare_enable(hpriv->n_clks, hpriv->clks); in ahci_platform_enable_clks()
137 * ahci_platform_disable_clks - Disable platform clocks
141 * (bulk-clocks-disable function is supposed to do that in reverse
146 clk_bulk_disable_unprepare(hpriv->n_clks, hpriv->clks); in ahci_platform_disable_clks()
151 * ahci_platform_deassert_rsts - Deassert/trigger platform resets
162 if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER) in ahci_platform_deassert_rsts()
163 return reset_control_reset(hpriv->rsts); in ahci_platform_deassert_rsts()
165 return reset_control_deassert(hpriv->rsts); in ahci_platform_deassert_rsts()
170 * ahci_platform_assert_rsts - Assert/rearm platform resets
173 * This function asserts or rearms (for self-deasserting resets) all
181 if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER) in ahci_platform_assert_rsts()
182 return reset_control_rearm(hpriv->rsts); in ahci_platform_assert_rsts()
184 return reset_control_assert(hpriv->rsts); in ahci_platform_assert_rsts()
189 * ahci_platform_enable_regulators - Enable regulators
193 * hpriv->target_pwrs, if any. If a regulator fails to be enabled, it
204 rc = regulator_enable(hpriv->ahci_regulator); in ahci_platform_enable_regulators()
208 rc = regulator_enable(hpriv->phy_regulator); in ahci_platform_enable_regulators()
212 for (i = 0; i < hpriv->nports; i++) { in ahci_platform_enable_regulators()
213 if (!hpriv->target_pwrs[i]) in ahci_platform_enable_regulators()
216 rc = regulator_enable(hpriv->target_pwrs[i]); in ahci_platform_enable_regulators()
224 while (--i >= 0) in ahci_platform_enable_regulators()
225 if (hpriv->target_pwrs[i]) in ahci_platform_enable_regulators()
226 regulator_disable(hpriv->target_pwrs[i]); in ahci_platform_enable_regulators()
228 regulator_disable(hpriv->phy_regulator); in ahci_platform_enable_regulators()
230 regulator_disable(hpriv->ahci_regulator); in ahci_platform_enable_regulators()
236 * ahci_platform_disable_regulators - Disable regulators
239 * This function disables all regulators found in hpriv->target_pwrs and
246 for (i = 0; i < hpriv->nports; i++) { in ahci_platform_disable_regulators()
247 if (!hpriv->target_pwrs[i]) in ahci_platform_disable_regulators()
249 regulator_disable(hpriv->target_pwrs[i]); in ahci_platform_disable_regulators()
252 regulator_disable(hpriv->ahci_regulator); in ahci_platform_disable_regulators()
253 regulator_disable(hpriv->phy_regulator); in ahci_platform_disable_regulators()
257 * ahci_platform_enable_resources - Enable platform resources
309 * ahci_platform_disable_resources - Disable platform resources
336 if (hpriv->got_runtime_pm) { in ahci_platform_put_resources()
346 for (c = 0; c < hpriv->nports; c++) in ahci_platform_put_resources()
347 if (hpriv->target_pwrs && hpriv->target_pwrs[c]) in ahci_platform_put_resources()
348 regulator_put(hpriv->target_pwrs[c]); in ahci_platform_put_resources()
350 kfree(hpriv->target_pwrs); in ahci_platform_put_resources()
358 hpriv->phys[port] = devm_of_phy_get(dev, node, NULL); in ahci_platform_get_phy()
360 if (!IS_ERR(hpriv->phys[port])) in ahci_platform_get_phy()
363 rc = PTR_ERR(hpriv->phys[port]); in ahci_platform_get_phy()
365 case -ENOSYS: in ahci_platform_get_phy()
374 case -ENODEV: in ahci_platform_get_phy()
376 hpriv->phys[port] = NULL; in ahci_platform_get_phy()
379 case -EPROBE_DEFER: in ahci_platform_get_phy()
403 hpriv->target_pwrs[port] = target_pwr; in ahci_platform_get_regulator()
415 if (!of_property_read_u32(dev->of_node, "hba-cap", &hpriv->saved_cap)) in ahci_platform_get_firmware()
416 hpriv->saved_cap &= (HOST_CAP_SSS | HOST_CAP_MPS); in ahci_platform_get_firmware()
418 of_property_read_u32(dev->of_node, in ahci_platform_get_firmware()
419 "ports-implemented", &hpriv->saved_port_map); in ahci_platform_get_firmware()
421 for_each_child_of_node_scoped(dev->of_node, child) { in ahci_platform_get_firmware()
426 return -EINVAL; in ahci_platform_get_firmware()
428 if (!of_property_read_u32(child, "hba-port-cap", &hpriv->saved_port_cap[port])) in ahci_platform_get_firmware()
429 hpriv->saved_port_cap[port] &= PORT_CMD_CAP; in ahci_platform_get_firmware()
436 * ahci_platform_get_resources - Get platform resources
443 * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
447 * clock for non-OF platforms (optional)
457 int child_nodes, rc = -ENOMEM, enabled_ports = 0; in ahci_platform_get_resources()
458 struct device *dev = &pdev->dev; in ahci_platform_get_resources()
463 return ERR_PTR(-ENOMEM); in ahci_platform_get_resources()
473 * If the DT provided an "ahci" named resource, use it. Otherwise, in ahci_platform_get_resources()
477 hpriv->mmio = devm_platform_ioremap_resource_byname(pdev, "ahci"); in ahci_platform_get_resources()
479 hpriv->mmio = devm_platform_ioremap_resource(pdev, 0); in ahci_platform_get_resources()
480 if (IS_ERR(hpriv->mmio)) { in ahci_platform_get_resources()
481 rc = PTR_ERR(hpriv->mmio); in ahci_platform_get_resources()
487 * running on a non-OF platform or due to the clocks being defined in in ahci_platform_get_resources()
488 * bypass of the DT firmware (like da850, spear13xx). In that case we in ahci_platform_get_resources()
492 rc = devm_clk_bulk_get_all(dev, &hpriv->clks); in ahci_platform_get_resources()
498 hpriv->n_clks = rc; in ahci_platform_get_resources()
504 hpriv->clks = devm_kzalloc(dev, sizeof(*hpriv->clks), GFP_KERNEL); in ahci_platform_get_resources()
505 if (!hpriv->clks) { in ahci_platform_get_resources()
506 rc = -ENOMEM; in ahci_platform_get_resources()
509 hpriv->clks->clk = devm_clk_get_optional(dev, NULL); in ahci_platform_get_resources()
510 if (IS_ERR(hpriv->clks->clk)) { in ahci_platform_get_resources()
511 rc = PTR_ERR(hpriv->clks->clk); in ahci_platform_get_resources()
513 } else if (hpriv->clks->clk) { in ahci_platform_get_resources()
514 hpriv->clks->id = "ahci"; in ahci_platform_get_resources()
515 hpriv->n_clks = 1; in ahci_platform_get_resources()
519 hpriv->ahci_regulator = devm_regulator_get(dev, "ahci"); in ahci_platform_get_resources()
520 if (IS_ERR(hpriv->ahci_regulator)) { in ahci_platform_get_resources()
521 rc = PTR_ERR(hpriv->ahci_regulator); in ahci_platform_get_resources()
526 hpriv->phy_regulator = devm_regulator_get(dev, "phy"); in ahci_platform_get_resources()
527 if (IS_ERR(hpriv->phy_regulator)) { in ahci_platform_get_resources()
528 rc = PTR_ERR(hpriv->phy_regulator); in ahci_platform_get_resources()
533 hpriv->rsts = devm_reset_control_array_get_optional_shared(dev); in ahci_platform_get_resources()
534 if (IS_ERR(hpriv->rsts)) { in ahci_platform_get_resources()
535 rc = PTR_ERR(hpriv->rsts); in ahci_platform_get_resources()
539 hpriv->f_rsts = flags & AHCI_PLATFORM_RST_TRIGGER; in ahci_platform_get_resources()
543 * Too many sub-nodes most likely means having something wrong with in ahci_platform_get_resources()
546 child_nodes = of_get_child_count(dev->of_node); in ahci_platform_get_resources()
548 rc = -EINVAL; in ahci_platform_get_resources()
553 * If no sub-node was found, we still need to set nports to in ahci_platform_get_resources()
558 hpriv->nports = child_nodes; in ahci_platform_get_resources()
560 hpriv->nports = 1; in ahci_platform_get_resources()
562 hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL); in ahci_platform_get_resources()
563 if (!hpriv->phys) { in ahci_platform_get_resources()
564 rc = -ENOMEM; in ahci_platform_get_resources()
571 hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL); in ahci_platform_get_resources()
572 if (!hpriv->target_pwrs) { in ahci_platform_get_resources()
573 rc = -ENOMEM; in ahci_platform_get_resources()
578 for_each_child_of_node_scoped(dev->of_node, child) { in ahci_platform_get_resources()
586 rc = -EINVAL; in ahci_platform_get_resources()
590 if (port >= hpriv->nports) { in ahci_platform_get_resources()
603 &port_dev->dev); in ahci_platform_get_resources()
604 if (rc == -EPROBE_DEFER) in ahci_platform_get_resources()
617 rc = -ENODEV; in ahci_platform_get_resources()
621 if (!hpriv->mask_port_map) in ahci_platform_get_resources()
622 hpriv->mask_port_map = mask_port_map; in ahci_platform_get_resources()
625 * If no sub-node was found, keep this for device tree in ahci_platform_get_resources()
628 rc = ahci_platform_get_phy(hpriv, 0, dev, dev->of_node); in ahci_platform_get_resources()
633 if (rc == -EPROBE_DEFER) in ahci_platform_get_resources()
638 * Retrieve firmware-specific flags which then will be used to set in ahci_platform_get_resources()
639 * the HW-init fields of HBA and its ports in ahci_platform_get_resources()
647 hpriv->got_runtime_pm = true; in ahci_platform_get_resources()
659 * ahci_platform_init_host - Bring up an ahci-platform host
661 * @hpriv: ahci-host private data for the host
666 * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
677 struct device *dev = &pdev->dev; in ahci_platform_init_host()
687 return -EINVAL; in ahci_platform_init_host()
689 hpriv->irq = irq; in ahci_platform_init_host()
692 pi.private_data = (void *)(unsigned long)hpriv->flags; in ahci_platform_init_host()
696 if (hpriv->cap & HOST_CAP_NCQ) in ahci_platform_init_host()
699 if (hpriv->cap & HOST_CAP_PMP) in ahci_platform_init_host()
709 n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); in ahci_platform_init_host()
713 return -ENOMEM; in ahci_platform_init_host()
715 host->private_data = hpriv; in ahci_platform_init_host()
717 if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) in ahci_platform_init_host()
718 host->flags |= ATA_HOST_PARALLEL_SCAN; in ahci_platform_init_host()
725 for (i = 0; i < host->n_ports; i++) { in ahci_platform_init_host()
726 struct ata_port *ap = host->ports[i]; in ahci_platform_init_host()
728 ata_port_desc(ap, "mmio %pR", in ahci_platform_init_host()
730 ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); in ahci_platform_init_host()
733 if (ap->flags & ATA_FLAG_EM) in ahci_platform_init_host()
734 ap->em_message_type = hpriv->em_msg_type; in ahci_platform_init_host()
736 /* disabled/not-implemented port */ in ahci_platform_init_host()
737 if (!(hpriv->port_map & (1 << i))) in ahci_platform_init_host()
738 ap->ops = &ata_dummy_port_ops; in ahci_platform_init_host()
741 if (hpriv->cap & HOST_CAP_64) { in ahci_platform_init_host()
744 dev_err(dev, "Failed to enable 64-bit DMA.\n"); in ahci_platform_init_host()
762 struct ahci_host_priv *hpriv = host->private_data; in ahci_host_stop()
768 * ahci_platform_shutdown - Disable interrupts and stop DMA for host ports
778 struct ahci_host_priv *hpriv = host->private_data; in ahci_platform_shutdown()
779 void __iomem *mmio = hpriv->mmio; in ahci_platform_shutdown() local
782 for (i = 0; i < host->n_ports; i++) { in ahci_platform_shutdown()
783 struct ata_port *ap = host->ports[i]; in ahci_platform_shutdown()
786 if (ap->ops->freeze) in ahci_platform_shutdown()
787 ap->ops->freeze(ap); in ahci_platform_shutdown()
790 if (ap->ops->port_stop) in ahci_platform_shutdown()
791 ap->ops->port_stop(ap); in ahci_platform_shutdown()
795 writel(readl(mmio + HOST_CTL) & ~HOST_IRQ_EN, mmio + HOST_CTL); in ahci_platform_shutdown()
796 readl(mmio + HOST_CTL); /* flush */ in ahci_platform_shutdown()
797 writel(GENMASK(host->n_ports, 0), mmio + HOST_IRQ_STAT); in ahci_platform_shutdown()
803 * ahci_platform_suspend_host - Suspend an ahci-platform host
807 * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
816 struct ahci_host_priv *hpriv = host->private_data; in ahci_platform_suspend_host()
817 void __iomem *mmio = hpriv->mmio; in ahci_platform_suspend_host() local
820 if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { in ahci_platform_suspend_host()
822 return -EIO; in ahci_platform_suspend_host()
830 ctl = readl(mmio + HOST_CTL); in ahci_platform_suspend_host()
832 writel(ctl, mmio + HOST_CTL); in ahci_platform_suspend_host()
833 readl(mmio + HOST_CTL); /* flush */ in ahci_platform_suspend_host()
835 if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS) in ahci_platform_suspend_host()
844 * ahci_platform_resume_host - Resume an ahci-platform host
847 * This function does all the usual steps needed to resume an ahci-platform
857 struct ahci_host_priv *hpriv = host->private_data; in ahci_platform_resume_host()
860 if (dev->power.power_state.event == PM_EVENT_SUSPEND) { in ahci_platform_resume_host()
868 if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS) in ahci_platform_resume_host()
878 * ahci_platform_suspend - Suspend an ahci-platform device
890 struct ahci_host_priv *hpriv = host->private_data; in ahci_platform_suspend()
904 * ahci_platform_resume - Resume an ahci-platform device
916 struct ahci_host_priv *hpriv = host->private_data; in ahci_platform_resume()