* @hdma_support: HDMA support on this SoC
* @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache snooping
* @disable_mhi_ram_parity_check: Disable MHI RAM data parity error check
+ * @firmware_managed: Set if the controller is firmware managed
*/
struct qcom_pcie_ep_cfg {
bool hdma_support;
bool override_no_snoop;
bool disable_mhi_ram_parity_check;
+ bool firmware_managed;
};
/**
static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep)
{
+ struct device *dev = pcie_ep->pci.dev;
+
+ pm_runtime_put(dev);
+
+ /* Skip resource disablement if controller is firmware-managed */
+ if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
+ return;
+
icc_set_bw(pcie_ep->icc_mem, 0, 0);
phy_power_off(pcie_ep->phy);
phy_exit(pcie_ep->phy);
u32 val, offset;
int ret;
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable device: %d\n", ret);
+ return ret;
+ }
+
+ /* Skip resource enablement if controller is firmware-managed */
+ if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
+ goto skip_resources_enable;
+
ret = qcom_pcie_enable_resources(pcie_ep);
if (ret) {
dev_err(dev, "Failed to enable resources: %d\n", ret);
+ pm_runtime_put(dev);
return ret;
}
+skip_resources_enable:
/* Perform cleanup that requires refclk */
pci_epc_deinit_notify(pci->ep.epc);
dw_pcie_ep_cleanup(&pci->ep);
return ret;
}
+ pcie_ep->reset = devm_gpiod_get(dev, "reset", GPIOD_IN);
+ if (IS_ERR(pcie_ep->reset))
+ return PTR_ERR(pcie_ep->reset);
+
+ pcie_ep->wake = devm_gpiod_get_optional(dev, "wake", GPIOD_OUT_LOW);
+ if (IS_ERR(pcie_ep->wake))
+ return PTR_ERR(pcie_ep->wake);
+
+ if (pcie_ep->cfg && pcie_ep->cfg->firmware_managed)
+ return 0;
+
pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks);
if (pcie_ep->num_clks < 0) {
dev_err(dev, "Failed to get clocks\n");
if (IS_ERR(pcie_ep->core_reset))
return PTR_ERR(pcie_ep->core_reset);
- pcie_ep->reset = devm_gpiod_get(dev, "reset", GPIOD_IN);
- if (IS_ERR(pcie_ep->reset))
- return PTR_ERR(pcie_ep->reset);
-
- pcie_ep->wake = devm_gpiod_get_optional(dev, "wake", GPIOD_OUT_LOW);
- if (IS_ERR(pcie_ep->wake))
- return PTR_ERR(pcie_ep->wake);
-
pcie_ep->phy = devm_phy_optional_get(dev, "pciephy");
if (IS_ERR(pcie_ep->phy))
ret = PTR_ERR(pcie_ep->phy);
platform_set_drvdata(pdev, pcie_ep);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
ret = qcom_pcie_ep_get_resources(pdev, pcie_ep);
if (ret)
return ret;
goto err_disable_irqs;
}
+ ret = pm_runtime_put_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to suspend device: %d\n", ret);
+ goto err_disable_irqs;
+ }
+
pcie_ep->debugfs = debugfs_create_dir(name, NULL);
qcom_pcie_ep_init_debugfs(pcie_ep);
.disable_mhi_ram_parity_check = true,
};
+static const struct qcom_pcie_ep_cfg cfg_1_34_0_fw_managed = {
+ .hdma_support = true,
+ .override_no_snoop = true,
+ .disable_mhi_ram_parity_check = true,
+ .firmware_managed = true,
+};
+
static const struct of_device_id qcom_pcie_ep_match[] = {
+ { .compatible = "qcom,sa8255p-pcie-ep", .data = &cfg_1_34_0_fw_managed},
{ .compatible = "qcom,sa8775p-pcie-ep", .data = &cfg_1_34_0},
{ .compatible = "qcom,sdx55-pcie-ep", },
{ .compatible = "qcom,sm8450-pcie-ep", },