xref: /linux/drivers/pci/controller/dwc/pcie-visconti.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
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