staticvoid armada8k_pcie_disable_phys(struct armada8k_pcie *pcie)
{ int i;
for (i = 0; i < ARMADA8K_PCIE_MAX_LANES; i++) {
phy_power_off(pcie->phy[i]);
phy_exit(pcie->phy[i]);
}
}
staticint armada8k_pcie_enable_phys(struct armada8k_pcie *pcie)
{ int ret; int i;
for (i = 0; i < ARMADA8K_PCIE_MAX_LANES; i++) {
ret = phy_init(pcie->phy[i]); if (ret) return ret;
ret = phy_set_mode_ext(pcie->phy[i], PHY_MODE_PCIE,
pcie->phy_count); if (ret) {
phy_exit(pcie->phy[i]); return ret;
}
ret = phy_power_on(pcie->phy[i]); if (ret) {
phy_exit(pcie->phy[i]); return ret;
}
}
return 0;
}
staticint armada8k_pcie_setup_phys(struct armada8k_pcie *pcie)
{ struct dw_pcie *pci = pcie->pci; struct device *dev = pci->dev; struct device_node *node = dev->of_node; int ret = 0; int i;
for (i = 0; i < ARMADA8K_PCIE_MAX_LANES; i++) {
pcie->phy[i] = devm_of_phy_get_by_index(dev, node, i); if (IS_ERR(pcie->phy[i])) { if (PTR_ERR(pcie->phy[i]) != -ENODEV) return PTR_ERR(pcie->phy[i]);
pcie->phy[i] = NULL; continue;
}
pcie->phy_count++;
}
/* Old bindings miss the PHY handle, so just warn if there is no PHY */ if (!pcie->phy_count)
dev_warn(dev, "No available PHY\n");
ret = armada8k_pcie_enable_phys(pcie); if (ret)
dev_err(dev, "Failed to initialize PHY(s) (%d)\n", ret);
/* * Interrupts are directly handled by the device driver of the * PCI device. However, they are also latched into the PCIe * controller, so we simply discard them.
*/
val = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG);
dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG, val);
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) return -ENOMEM;
pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); if (!pci) return -ENOMEM;
pci->dev = dev;
pci->ops = &dw_pcie_ops;
pcie->pci = pci;
pcie->clk = devm_clk_get(dev, NULL); if (IS_ERR(pcie->clk)) return PTR_ERR(pcie->clk);
ret = clk_prepare_enable(pcie->clk); if (ret) return ret;
pcie->clk_reg = devm_clk_get(dev, "reg"); if (pcie->clk_reg == ERR_PTR(-EPROBE_DEFER)) {
ret = -EPROBE_DEFER; goto fail;
} if (!IS_ERR(pcie->clk_reg)) {
ret = clk_prepare_enable(pcie->clk_reg); if (ret) goto fail_clkreg;
}
/* Get the dw-pcie unit configuration/control registers base. */
base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
pci->dbi_base = devm_pci_remap_cfg_resource(dev, base); if (IS_ERR(pci->dbi_base)) {
ret = PTR_ERR(pci->dbi_base); goto fail_clkreg;
}
ret = armada8k_pcie_setup_phys(pcie); if (ret) goto fail_clkreg;
platform_set_drvdata(pdev, pcie);
ret = armada8k_add_pcie_port(pcie, pdev); if (ret) goto disable_phy;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.