pcie0: pcie0@2B000000 {
compatible = "plda,pci-xpressrich3-axi";
reg = <0x0 0x2B000000 0x0 0x1000000
- 0x9 0x40000000 0x0 0x10000000>;
+ 0x9 0x40000000 0x0 0x10000000>;
reg-names = "reg", "config";
interrupts = <56>;
interrupt-controller;
<0x0 0x0 0x0 0x2 &plic 0x2>,
<0x0 0x0 0x0 0x3 &plic 0x3>,
<0x0 0x0 0x0 0x4 &plic 0x4>;
+ resets = <&rstgen RSTN_U0_PLDA_PCIE_AXI_MST0>,
+ <&rstgen RSTN_U0_PLDA_PCIE_AXI_SLV0>,
+ <&rstgen RSTN_U0_PLDA_PCIE_AXI_SLV>,
+ <&rstgen RSTN_U0_PLDA_PCIE_BRG>,
+ <&rstgen RSTN_U0_PLDA_PCIE_CORE>,
+ <&rstgen RSTN_U0_PLDA_PCIE_APB>;
+ reset-names = "rst_mst0", "rst_slv0", "rst_slv",
+ "rst_brg", "rst_core", "rst_apb";
+ clocks = <&clkgen JH7110_PCIE0_CLK_TL>,
+ <&clkgen JH7110_PCIE0_CLK_AXI_MST0>,
+ <&clkgen JH7110_PCIE0_CLK_APB>;
+ clock-names = "tl", "axi_mst0", "apb";
#interrupt-cells = <1>;
device_type = "pci";
bus-range = <0x0 0xff>;
pcie1:pcie1@2C000000 {
compatible = "plda,pci-xpressrich3-axi";
reg = <0x0 0x2C000000 0x0 0x1000000
- 0x9 0xc0000000 0x0 0x10000000>;
+ 0x9 0xc0000000 0x0 0x10000000>;
reg-names = "reg", "config";
device_type = "pci";
bus-range = <0x0 0xff>;
<0x0 0x0 0x0 0x2 &plic 0x2>,
<0x0 0x0 0x0 0x3 &plic 0x3>,
<0x0 0x0 0x0 0x4 &plic 0x4>;
+ resets = <&rstgen RSTN_U1_PLDA_PCIE_AXI_MST0>,
+ <&rstgen RSTN_U1_PLDA_PCIE_AXI_SLV0>,
+ <&rstgen RSTN_U1_PLDA_PCIE_AXI_SLV>,
+ <&rstgen RSTN_U1_PLDA_PCIE_BRG>,
+ <&rstgen RSTN_U1_PLDA_PCIE_CORE>,
+ <&rstgen RSTN_U1_PLDA_PCIE_APB>;
+ reset-names = "rst_mst0", "rst_slv0", "rst_slv",
+ "rst_brg", "rst_core", "rst_apb";
+ clocks = <&clkgen JH7110_PCIE1_CLK_TL>,
+ <&clkgen JH7110_PCIE1_CLK_AXI_MST0>,
+ <&clkgen JH7110_PCIE1_CLK_APB>;
+ clock-names = "tl", "axi_mst0", "apb";
status = "disabled";
};
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/msi.h>
-
+#include <linux/reset.h>
+#include <linux/clk.h>
#define PCIE_BASIC_STATUS 0x018
struct irq_domain *legacy_irq_domain;
struct pci_host_bridge *bridge;
struct plda_msi msi;
+ struct reset_control *resets;
+ struct clk_bulk_data *clks;
+ int num_clks;
};
static inline void plda_writel(struct plda_pcie *pcie, const u32 value,
return 0;
}
+static int plda_clk_rst_init(struct plda_pcie *pcie)
+{
+ int ret;
+ struct device *dev = &pcie->pdev->dev;
+
+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
+ if (pcie->num_clks < 0) {
+ dev_err(dev, "failed to get pcie clocks\n");
+ ret = -ENODEV;
+ goto exit;
+ }
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
+ if (ret) {
+ dev_err(&pcie->pdev->dev, "failed to enable clocks\n");
+ goto exit;
+ }
+
+ pcie->resets = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(pcie->resets)) {
+ ret = PTR_ERR(pcie->resets);
+ dev_err(dev, "failed to get pcie resets");
+ goto err_clk_init;
+ }
+ ret = reset_control_deassert(pcie->resets);
+ goto exit;
+
+err_clk_init:
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+exit:
+ return ret;
+}
+
+static void plda_clk_rst_deinit(struct plda_pcie *pcie)
+{
+ reset_control_assert(pcie->resets);
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
+}
void plda_pcie_hw_init(struct plda_pcie *pcie)
{
platform_set_drvdata(pdev, pcie);
+ ret = plda_clk_rst_init(pcie);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to init pcie clk reset: %d\n", ret);
+ return ret;
+ }
+
ret = plda_pcie_init_irq_domain(pcie);
if (ret) {
dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
struct plda_pcie *pcie = platform_get_drvdata(pdev);
plda_pcie_free_irq_domain(pcie);
+ plda_clk_rst_deinit(pcie);
platform_set_drvdata(pdev, NULL);
return 0;
}