1da36024aSNobuhiro Iwamatsu // SPDX-License-Identifier: GPL-2.0
2da36024aSNobuhiro Iwamatsu /*
3da36024aSNobuhiro Iwamatsu * DWC PCIe RC driver for Toshiba Visconti ARM SoC
4da36024aSNobuhiro Iwamatsu *
5da36024aSNobuhiro Iwamatsu * Copyright (C) 2021 Toshiba Electronic Device & Storage Corporation
6da36024aSNobuhiro Iwamatsu * Copyright (C) 2021 TOSHIBA CORPORATION
7da36024aSNobuhiro Iwamatsu *
8da36024aSNobuhiro Iwamatsu * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
9da36024aSNobuhiro Iwamatsu */
10da36024aSNobuhiro Iwamatsu
11da36024aSNobuhiro Iwamatsu #include <linux/clk.h>
12da36024aSNobuhiro Iwamatsu #include <linux/delay.h>
13da36024aSNobuhiro Iwamatsu #include <linux/gpio.h>
14da36024aSNobuhiro Iwamatsu #include <linux/interrupt.h>
15da36024aSNobuhiro Iwamatsu #include <linux/init.h>
16da36024aSNobuhiro Iwamatsu #include <linux/iopoll.h>
17da36024aSNobuhiro Iwamatsu #include <linux/kernel.h>
18da36024aSNobuhiro Iwamatsu #include <linux/of_platform.h>
19da36024aSNobuhiro Iwamatsu #include <linux/pci.h>
20da36024aSNobuhiro Iwamatsu #include <linux/platform_device.h>
21da36024aSNobuhiro Iwamatsu #include <linux/resource.h>
22da36024aSNobuhiro Iwamatsu #include <linux/types.h>
23da36024aSNobuhiro Iwamatsu
24da36024aSNobuhiro Iwamatsu #include "pcie-designware.h"
25da36024aSNobuhiro Iwamatsu #include "../../pci.h"
26da36024aSNobuhiro Iwamatsu
27da36024aSNobuhiro Iwamatsu struct visconti_pcie {
28da36024aSNobuhiro Iwamatsu struct dw_pcie pci;
29da36024aSNobuhiro Iwamatsu void __iomem *ulreg_base;
30da36024aSNobuhiro Iwamatsu void __iomem *smu_base;
31da36024aSNobuhiro Iwamatsu void __iomem *mpu_base;
32da36024aSNobuhiro Iwamatsu struct clk *refclk;
33da36024aSNobuhiro Iwamatsu struct clk *coreclk;
34da36024aSNobuhiro Iwamatsu struct clk *auxclk;
35da36024aSNobuhiro Iwamatsu };
36da36024aSNobuhiro Iwamatsu
37da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PCIE_MODE 0x00F4
38da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PCIE_MODE_EP 0x00
39da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PCIE_MODE_RC 0x04
40da36024aSNobuhiro Iwamatsu
41da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PERSTN_CTRL 0x00F8
42da36024aSNobuhiro Iwamatsu #define PCIE_UL_IOM_PCIE_PERSTN_I_EN BIT(3)
43da36024aSNobuhiro Iwamatsu #define PCIE_UL_DIRECT_PERSTN_EN BIT(2)
44da36024aSNobuhiro Iwamatsu #define PCIE_UL_PERSTN_OUT BIT(1)
45da36024aSNobuhiro Iwamatsu #define PCIE_UL_DIRECT_PERSTN BIT(0)
46da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PERSTN_CTRL_INIT (PCIE_UL_IOM_PCIE_PERSTN_I_EN | \
47da36024aSNobuhiro Iwamatsu PCIE_UL_DIRECT_PERSTN_EN | \
48da36024aSNobuhiro Iwamatsu PCIE_UL_DIRECT_PERSTN)
49da36024aSNobuhiro Iwamatsu
50da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PHY_INIT_02 0x0104
51da36024aSNobuhiro Iwamatsu #define PCIE_UL_PHY0_SRAM_EXT_LD_DONE BIT(0)
52da36024aSNobuhiro Iwamatsu
53da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_PHY_INIT_03 0x0108
54da36024aSNobuhiro Iwamatsu #define PCIE_UL_PHY0_SRAM_INIT_DONE BIT(0)
55da36024aSNobuhiro Iwamatsu
56da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_INT_EVENT_MASK1 0x0138
57da36024aSNobuhiro Iwamatsu #define PCIE_UL_CFG_PME_INT BIT(0)
58da36024aSNobuhiro Iwamatsu #define PCIE_UL_CFG_LINK_EQ_REQ_INT BIT(1)
59da36024aSNobuhiro Iwamatsu #define PCIE_UL_EDMA_INT0 BIT(2)
60da36024aSNobuhiro Iwamatsu #define PCIE_UL_EDMA_INT1 BIT(3)
61da36024aSNobuhiro Iwamatsu #define PCIE_UL_EDMA_INT2 BIT(4)
62da36024aSNobuhiro Iwamatsu #define PCIE_UL_EDMA_INT3 BIT(5)
63da36024aSNobuhiro Iwamatsu #define PCIE_UL_S_INT_EVENT_MASK1_ALL (PCIE_UL_CFG_PME_INT | \
64da36024aSNobuhiro Iwamatsu PCIE_UL_CFG_LINK_EQ_REQ_INT | \
65da36024aSNobuhiro Iwamatsu PCIE_UL_EDMA_INT0 | \
66da36024aSNobuhiro Iwamatsu PCIE_UL_EDMA_INT1 | \
67da36024aSNobuhiro Iwamatsu PCIE_UL_EDMA_INT2 | \
68da36024aSNobuhiro Iwamatsu PCIE_UL_EDMA_INT3)
69da36024aSNobuhiro Iwamatsu
70da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_SB_MON 0x0198
71da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_S_SIG_MON 0x019C
72da36024aSNobuhiro Iwamatsu #define PCIE_UL_CORE_RST_N_MON BIT(0)
73da36024aSNobuhiro Iwamatsu
74da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_V_SII_DBG_00 0x0844
75da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_V_SII_GEN_CTRL_01 0x0860
76da36024aSNobuhiro Iwamatsu #define PCIE_UL_APP_LTSSM_ENABLE BIT(0)
77da36024aSNobuhiro Iwamatsu
78da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_V_PHY_ST_00 0x0864
79da36024aSNobuhiro Iwamatsu #define PCIE_UL_SMLH_LINK_UP BIT(0)
80da36024aSNobuhiro Iwamatsu
81da36024aSNobuhiro Iwamatsu #define PCIE_UL_REG_V_PHY_ST_02 0x0868
82da36024aSNobuhiro Iwamatsu #define PCIE_UL_S_DETECT_ACT 0x01
83da36024aSNobuhiro Iwamatsu #define PCIE_UL_S_L0 0x11
84da36024aSNobuhiro Iwamatsu
85da36024aSNobuhiro Iwamatsu #define PISMU_CKON_PCIE 0x0038
86da36024aSNobuhiro Iwamatsu #define PISMU_CKON_PCIE_AUX_CLK BIT(1)
87da36024aSNobuhiro Iwamatsu #define PISMU_CKON_PCIE_MSTR_ACLK BIT(0)
88da36024aSNobuhiro Iwamatsu
89da36024aSNobuhiro Iwamatsu #define PISMU_RSOFF_PCIE 0x0538
90da36024aSNobuhiro Iwamatsu #define PISMU_RSOFF_PCIE_ULREG_RST_N BIT(1)
91da36024aSNobuhiro Iwamatsu #define PISMU_RSOFF_PCIE_PWR_UP_RST_N BIT(0)
92da36024aSNobuhiro Iwamatsu
93da36024aSNobuhiro Iwamatsu #define PCIE_MPU_REG_MP_EN 0x0
94da36024aSNobuhiro Iwamatsu #define MPU_MP_EN_DISABLE BIT(0)
95da36024aSNobuhiro Iwamatsu
96da36024aSNobuhiro Iwamatsu /* Access registers in PCIe ulreg */
visconti_ulreg_writel(struct visconti_pcie * pcie,u32 val,u32 reg)97da36024aSNobuhiro Iwamatsu static void visconti_ulreg_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
98da36024aSNobuhiro Iwamatsu {
99da36024aSNobuhiro Iwamatsu writel_relaxed(val, pcie->ulreg_base + reg);
100da36024aSNobuhiro Iwamatsu }
101da36024aSNobuhiro Iwamatsu
visconti_ulreg_readl(struct visconti_pcie * pcie,u32 reg)102da36024aSNobuhiro Iwamatsu static u32 visconti_ulreg_readl(struct visconti_pcie *pcie, u32 reg)
103da36024aSNobuhiro Iwamatsu {
104da36024aSNobuhiro Iwamatsu return readl_relaxed(pcie->ulreg_base + reg);
105da36024aSNobuhiro Iwamatsu }
106da36024aSNobuhiro Iwamatsu
107da36024aSNobuhiro Iwamatsu /* Access registers in PCIe smu */
visconti_smu_writel(struct visconti_pcie * pcie,u32 val,u32 reg)108da36024aSNobuhiro Iwamatsu static void visconti_smu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
109da36024aSNobuhiro Iwamatsu {
110da36024aSNobuhiro Iwamatsu writel_relaxed(val, pcie->smu_base + reg);
111da36024aSNobuhiro Iwamatsu }
112da36024aSNobuhiro Iwamatsu
113da36024aSNobuhiro Iwamatsu /* Access registers in PCIe mpu */
visconti_mpu_writel(struct visconti_pcie * pcie,u32 val,u32 reg)114da36024aSNobuhiro Iwamatsu static void visconti_mpu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
115da36024aSNobuhiro Iwamatsu {
116da36024aSNobuhiro Iwamatsu writel_relaxed(val, pcie->mpu_base + reg);
117da36024aSNobuhiro Iwamatsu }
118da36024aSNobuhiro Iwamatsu
visconti_mpu_readl(struct visconti_pcie * pcie,u32 reg)119da36024aSNobuhiro Iwamatsu static u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
120da36024aSNobuhiro Iwamatsu {
121da36024aSNobuhiro Iwamatsu return readl_relaxed(pcie->mpu_base + reg);
122da36024aSNobuhiro Iwamatsu }
123da36024aSNobuhiro Iwamatsu
visconti_pcie_link_up(struct dw_pcie * pci)124da36024aSNobuhiro Iwamatsu static int visconti_pcie_link_up(struct dw_pcie *pci)
125da36024aSNobuhiro Iwamatsu {
126da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
127da36024aSNobuhiro Iwamatsu void __iomem *addr = pcie->ulreg_base;
128da36024aSNobuhiro Iwamatsu u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
129da36024aSNobuhiro Iwamatsu
130da36024aSNobuhiro Iwamatsu return !!(val & PCIE_UL_S_L0);
131da36024aSNobuhiro Iwamatsu }
132da36024aSNobuhiro Iwamatsu
visconti_pcie_start_link(struct dw_pcie * pci)133da36024aSNobuhiro Iwamatsu static int visconti_pcie_start_link(struct dw_pcie *pci)
134da36024aSNobuhiro Iwamatsu {
135da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
136da36024aSNobuhiro Iwamatsu void __iomem *addr = pcie->ulreg_base;
137da36024aSNobuhiro Iwamatsu u32 val;
138da36024aSNobuhiro Iwamatsu int ret;
139da36024aSNobuhiro Iwamatsu
140da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, PCIE_UL_APP_LTSSM_ENABLE,
141da36024aSNobuhiro Iwamatsu PCIE_UL_REG_V_SII_GEN_CTRL_01);
142da36024aSNobuhiro Iwamatsu
143da36024aSNobuhiro Iwamatsu ret = readl_relaxed_poll_timeout(addr + PCIE_UL_REG_V_PHY_ST_02,
144da36024aSNobuhiro Iwamatsu val, (val & PCIE_UL_S_L0),
145da36024aSNobuhiro Iwamatsu 90000, 100000);
146da36024aSNobuhiro Iwamatsu if (ret)
147da36024aSNobuhiro Iwamatsu return ret;
148da36024aSNobuhiro Iwamatsu
149da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, PCIE_UL_S_INT_EVENT_MASK1_ALL,
150da36024aSNobuhiro Iwamatsu PCIE_UL_REG_S_INT_EVENT_MASK1);
151da36024aSNobuhiro Iwamatsu
152da36024aSNobuhiro Iwamatsu if (dw_pcie_link_up(pci)) {
153da36024aSNobuhiro Iwamatsu val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
154da36024aSNobuhiro Iwamatsu visconti_mpu_writel(pcie, val & ~MPU_MP_EN_DISABLE,
155da36024aSNobuhiro Iwamatsu PCIE_MPU_REG_MP_EN);
156da36024aSNobuhiro Iwamatsu }
157da36024aSNobuhiro Iwamatsu
158da36024aSNobuhiro Iwamatsu return 0;
159da36024aSNobuhiro Iwamatsu }
160da36024aSNobuhiro Iwamatsu
visconti_pcie_stop_link(struct dw_pcie * pci)161da36024aSNobuhiro Iwamatsu static void visconti_pcie_stop_link(struct dw_pcie *pci)
162da36024aSNobuhiro Iwamatsu {
163da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
164da36024aSNobuhiro Iwamatsu u32 val;
165da36024aSNobuhiro Iwamatsu
166da36024aSNobuhiro Iwamatsu val = visconti_ulreg_readl(pcie, PCIE_UL_REG_V_SII_GEN_CTRL_01);
167da36024aSNobuhiro Iwamatsu val &= ~PCIE_UL_APP_LTSSM_ENABLE;
168da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, val, PCIE_UL_REG_V_SII_GEN_CTRL_01);
169da36024aSNobuhiro Iwamatsu
170da36024aSNobuhiro Iwamatsu val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
171da36024aSNobuhiro Iwamatsu visconti_mpu_writel(pcie, val | MPU_MP_EN_DISABLE, PCIE_MPU_REG_MP_EN);
172da36024aSNobuhiro Iwamatsu }
173da36024aSNobuhiro Iwamatsu
174da36024aSNobuhiro Iwamatsu /*
175da36024aSNobuhiro Iwamatsu * In this SoC specification, the CPU bus outputs the offset value from
176da36024aSNobuhiro Iwamatsu * 0x40000000 to the PCIe bus, so 0x40000000 is subtracted from the CPU
177da36024aSNobuhiro Iwamatsu * bus address. This 0x40000000 is also based on io_base from DT.
178da36024aSNobuhiro Iwamatsu */
visconti_pcie_cpu_addr_fixup(struct dw_pcie * pci,u64 cpu_addr)179da36024aSNobuhiro Iwamatsu static u64 visconti_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
180da36024aSNobuhiro Iwamatsu {
18160b3c27fSSerge Semin struct dw_pcie_rp *pp = &pci->pp;
182da36024aSNobuhiro Iwamatsu
183da36024aSNobuhiro Iwamatsu return cpu_addr & ~pp->io_base;
184da36024aSNobuhiro Iwamatsu }
185da36024aSNobuhiro Iwamatsu
186da36024aSNobuhiro Iwamatsu static const struct dw_pcie_ops dw_pcie_ops = {
187da36024aSNobuhiro Iwamatsu .cpu_addr_fixup = visconti_pcie_cpu_addr_fixup,
188da36024aSNobuhiro Iwamatsu .link_up = visconti_pcie_link_up,
189da36024aSNobuhiro Iwamatsu .start_link = visconti_pcie_start_link,
190da36024aSNobuhiro Iwamatsu .stop_link = visconti_pcie_stop_link,
191da36024aSNobuhiro Iwamatsu };
192da36024aSNobuhiro Iwamatsu
visconti_pcie_host_init(struct dw_pcie_rp * pp)19360b3c27fSSerge Semin static int visconti_pcie_host_init(struct dw_pcie_rp *pp)
194da36024aSNobuhiro Iwamatsu {
195da36024aSNobuhiro Iwamatsu struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
196da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
197da36024aSNobuhiro Iwamatsu void __iomem *addr;
198da36024aSNobuhiro Iwamatsu int err;
199da36024aSNobuhiro Iwamatsu u32 val;
200da36024aSNobuhiro Iwamatsu
201da36024aSNobuhiro Iwamatsu visconti_smu_writel(pcie,
202da36024aSNobuhiro Iwamatsu PISMU_CKON_PCIE_AUX_CLK | PISMU_CKON_PCIE_MSTR_ACLK,
203da36024aSNobuhiro Iwamatsu PISMU_CKON_PCIE);
204da36024aSNobuhiro Iwamatsu ndelay(250);
205da36024aSNobuhiro Iwamatsu
206da36024aSNobuhiro Iwamatsu visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_ULREG_RST_N,
207da36024aSNobuhiro Iwamatsu PISMU_RSOFF_PCIE);
208da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, PCIE_UL_REG_S_PCIE_MODE_RC,
209da36024aSNobuhiro Iwamatsu PCIE_UL_REG_S_PCIE_MODE);
210da36024aSNobuhiro Iwamatsu
211da36024aSNobuhiro Iwamatsu val = PCIE_UL_REG_S_PERSTN_CTRL_INIT;
212da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
213da36024aSNobuhiro Iwamatsu udelay(100);
214da36024aSNobuhiro Iwamatsu
215da36024aSNobuhiro Iwamatsu val |= PCIE_UL_PERSTN_OUT;
216da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
217da36024aSNobuhiro Iwamatsu udelay(100);
218da36024aSNobuhiro Iwamatsu
219da36024aSNobuhiro Iwamatsu visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_PWR_UP_RST_N,
220da36024aSNobuhiro Iwamatsu PISMU_RSOFF_PCIE);
221da36024aSNobuhiro Iwamatsu
222da36024aSNobuhiro Iwamatsu addr = pcie->ulreg_base + PCIE_UL_REG_S_PHY_INIT_03;
223da36024aSNobuhiro Iwamatsu err = readl_relaxed_poll_timeout(addr, val,
224da36024aSNobuhiro Iwamatsu (val & PCIE_UL_PHY0_SRAM_INIT_DONE),
225da36024aSNobuhiro Iwamatsu 100, 1000);
226da36024aSNobuhiro Iwamatsu if (err)
227da36024aSNobuhiro Iwamatsu return err;
228da36024aSNobuhiro Iwamatsu
229da36024aSNobuhiro Iwamatsu visconti_ulreg_writel(pcie, PCIE_UL_PHY0_SRAM_EXT_LD_DONE,
230da36024aSNobuhiro Iwamatsu PCIE_UL_REG_S_PHY_INIT_02);
231da36024aSNobuhiro Iwamatsu
232da36024aSNobuhiro Iwamatsu addr = pcie->ulreg_base + PCIE_UL_REG_S_SIG_MON;
233da36024aSNobuhiro Iwamatsu return readl_relaxed_poll_timeout(addr, val,
234da36024aSNobuhiro Iwamatsu (val & PCIE_UL_CORE_RST_N_MON), 100,
235da36024aSNobuhiro Iwamatsu 1000);
236da36024aSNobuhiro Iwamatsu }
237da36024aSNobuhiro Iwamatsu
238da36024aSNobuhiro Iwamatsu static const struct dw_pcie_host_ops visconti_pcie_host_ops = {
239*aea370b2SYoshihiro Shimoda .init = visconti_pcie_host_init,
240da36024aSNobuhiro Iwamatsu };
241da36024aSNobuhiro Iwamatsu
visconti_get_resources(struct platform_device * pdev,struct visconti_pcie * pcie)242da36024aSNobuhiro Iwamatsu static int visconti_get_resources(struct platform_device *pdev,
243da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie)
244da36024aSNobuhiro Iwamatsu {
245da36024aSNobuhiro Iwamatsu struct device *dev = &pdev->dev;
246da36024aSNobuhiro Iwamatsu
247da36024aSNobuhiro Iwamatsu pcie->ulreg_base = devm_platform_ioremap_resource_byname(pdev, "ulreg");
248da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->ulreg_base))
249da36024aSNobuhiro Iwamatsu return PTR_ERR(pcie->ulreg_base);
250da36024aSNobuhiro Iwamatsu
251da36024aSNobuhiro Iwamatsu pcie->smu_base = devm_platform_ioremap_resource_byname(pdev, "smu");
252da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->smu_base))
253da36024aSNobuhiro Iwamatsu return PTR_ERR(pcie->smu_base);
254da36024aSNobuhiro Iwamatsu
255da36024aSNobuhiro Iwamatsu pcie->mpu_base = devm_platform_ioremap_resource_byname(pdev, "mpu");
256da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->mpu_base))
257da36024aSNobuhiro Iwamatsu return PTR_ERR(pcie->mpu_base);
258da36024aSNobuhiro Iwamatsu
259da36024aSNobuhiro Iwamatsu pcie->refclk = devm_clk_get(dev, "ref");
260da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->refclk))
261da36024aSNobuhiro Iwamatsu return dev_err_probe(dev, PTR_ERR(pcie->refclk),
262da36024aSNobuhiro Iwamatsu "Failed to get ref clock\n");
263da36024aSNobuhiro Iwamatsu
264da36024aSNobuhiro Iwamatsu pcie->coreclk = devm_clk_get(dev, "core");
265da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->coreclk))
266da36024aSNobuhiro Iwamatsu return dev_err_probe(dev, PTR_ERR(pcie->coreclk),
267da36024aSNobuhiro Iwamatsu "Failed to get core clock\n");
268da36024aSNobuhiro Iwamatsu
269da36024aSNobuhiro Iwamatsu pcie->auxclk = devm_clk_get(dev, "aux");
270da36024aSNobuhiro Iwamatsu if (IS_ERR(pcie->auxclk))
271da36024aSNobuhiro Iwamatsu return dev_err_probe(dev, PTR_ERR(pcie->auxclk),
272da36024aSNobuhiro Iwamatsu "Failed to get aux clock\n");
273da36024aSNobuhiro Iwamatsu
274da36024aSNobuhiro Iwamatsu return 0;
275da36024aSNobuhiro Iwamatsu }
276da36024aSNobuhiro Iwamatsu
visconti_add_pcie_port(struct visconti_pcie * pcie,struct platform_device * pdev)277da36024aSNobuhiro Iwamatsu static int visconti_add_pcie_port(struct visconti_pcie *pcie,
278da36024aSNobuhiro Iwamatsu struct platform_device *pdev)
279da36024aSNobuhiro Iwamatsu {
280da36024aSNobuhiro Iwamatsu struct dw_pcie *pci = &pcie->pci;
28160b3c27fSSerge Semin struct dw_pcie_rp *pp = &pci->pp;
282da36024aSNobuhiro Iwamatsu
283da36024aSNobuhiro Iwamatsu pp->irq = platform_get_irq_byname(pdev, "intr");
2845b840256SKrzysztof Wilczyński if (pp->irq < 0)
285da36024aSNobuhiro Iwamatsu return pp->irq;
286da36024aSNobuhiro Iwamatsu
287da36024aSNobuhiro Iwamatsu pp->ops = &visconti_pcie_host_ops;
288da36024aSNobuhiro Iwamatsu
289da36024aSNobuhiro Iwamatsu return dw_pcie_host_init(pp);
290da36024aSNobuhiro Iwamatsu }
291da36024aSNobuhiro Iwamatsu
visconti_pcie_probe(struct platform_device * pdev)292da36024aSNobuhiro Iwamatsu static int visconti_pcie_probe(struct platform_device *pdev)
293da36024aSNobuhiro Iwamatsu {
294da36024aSNobuhiro Iwamatsu struct device *dev = &pdev->dev;
295da36024aSNobuhiro Iwamatsu struct visconti_pcie *pcie;
296da36024aSNobuhiro Iwamatsu struct dw_pcie *pci;
297da36024aSNobuhiro Iwamatsu int ret;
298da36024aSNobuhiro Iwamatsu
299da36024aSNobuhiro Iwamatsu pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
300da36024aSNobuhiro Iwamatsu if (!pcie)
301da36024aSNobuhiro Iwamatsu return -ENOMEM;
302da36024aSNobuhiro Iwamatsu
303da36024aSNobuhiro Iwamatsu pci = &pcie->pci;
304da36024aSNobuhiro Iwamatsu pci->dev = dev;
305da36024aSNobuhiro Iwamatsu pci->ops = &dw_pcie_ops;
306da36024aSNobuhiro Iwamatsu
307da36024aSNobuhiro Iwamatsu ret = visconti_get_resources(pdev, pcie);
308da36024aSNobuhiro Iwamatsu if (ret)
309da36024aSNobuhiro Iwamatsu return ret;
310da36024aSNobuhiro Iwamatsu
311da36024aSNobuhiro Iwamatsu platform_set_drvdata(pdev, pcie);
312da36024aSNobuhiro Iwamatsu
313da36024aSNobuhiro Iwamatsu return visconti_add_pcie_port(pcie, pdev);
314da36024aSNobuhiro Iwamatsu }
315da36024aSNobuhiro Iwamatsu
316da36024aSNobuhiro Iwamatsu static const struct of_device_id visconti_pcie_match[] = {
317da36024aSNobuhiro Iwamatsu { .compatible = "toshiba,visconti-pcie" },
318da36024aSNobuhiro Iwamatsu {},
319da36024aSNobuhiro Iwamatsu };
320da36024aSNobuhiro Iwamatsu
321da36024aSNobuhiro Iwamatsu static struct platform_driver visconti_pcie_driver = {
322da36024aSNobuhiro Iwamatsu .probe = visconti_pcie_probe,
323da36024aSNobuhiro Iwamatsu .driver = {
324da36024aSNobuhiro Iwamatsu .name = "visconti-pcie",
325da36024aSNobuhiro Iwamatsu .of_match_table = visconti_pcie_match,
326da36024aSNobuhiro Iwamatsu .suppress_bind_attrs = true,
327da36024aSNobuhiro Iwamatsu },
328da36024aSNobuhiro Iwamatsu };
329da36024aSNobuhiro Iwamatsu builtin_platform_driver(visconti_pcie_driver);
330