3535#define PF_MCR_PTOMR BIT(0)
3636#define PF_MCR_EXL2S BIT(1)
3737
38+ /* LS1021A PEXn PM Write Control Register */
39+ #define SCFG_PEXPMWRCR (idx ) (0x5c + (idx) * 0x64)
40+ #define PMXMTTURNOFF BIT(31)
41+ #define SCFG_PEXSFTRSTCR 0x190
42+ #define PEXSR (idx ) BIT(idx)
43+
44+ /* LS1043A PEX PME control register */
45+ #define SCFG_PEXPMECR 0x144
46+ #define PEXPME (idx ) BIT(31 - (idx) * 4)
47+
48+ /* LS1043A PEX LUT debug register */
49+ #define LS_PCIE_LDBG 0x7fc
50+ #define LDBG_SR BIT(30)
51+ #define LDBG_WE BIT(31)
52+
3853#define PCIE_IATU_NUM 6
3954
4055struct ls_pcie_drvdata {
41- const u32 pf_off ;
56+ const u32 pf_lut_off ;
57+ const struct dw_pcie_host_ops * ops ;
58+ int (* exit_from_l2 )(struct dw_pcie_rp * pp );
59+ bool scfg_support ;
4260 bool pm_support ;
4361};
4462
4563struct ls_pcie {
4664 struct dw_pcie * pci ;
4765 const struct ls_pcie_drvdata * drvdata ;
48- void __iomem * pf_base ;
66+ void __iomem * pf_lut_base ;
67+ struct regmap * scfg ;
68+ int index ;
4969 bool big_endian ;
5070};
5171
52- #define ls_pcie_pf_readl_addr (addr ) ls_pcie_pf_readl (pcie, addr)
72+ #define ls_pcie_pf_lut_readl_addr (addr ) ls_pcie_pf_lut_readl (pcie, addr)
5373#define to_ls_pcie (x ) dev_get_drvdata((x)->dev)
5474
5575static bool ls_pcie_is_bridge (struct ls_pcie * pcie )
@@ -90,20 +110,20 @@ static void ls_pcie_fix_error_response(struct ls_pcie *pcie)
90110 iowrite32 (PCIE_ABSERR_SETTING , pci -> dbi_base + PCIE_ABSERR );
91111}
92112
93- static u32 ls_pcie_pf_readl (struct ls_pcie * pcie , u32 off )
113+ static u32 ls_pcie_pf_lut_readl (struct ls_pcie * pcie , u32 off )
94114{
95115 if (pcie -> big_endian )
96- return ioread32be (pcie -> pf_base + off );
116+ return ioread32be (pcie -> pf_lut_base + off );
97117
98- return ioread32 (pcie -> pf_base + off );
118+ return ioread32 (pcie -> pf_lut_base + off );
99119}
100120
101- static void ls_pcie_pf_writel (struct ls_pcie * pcie , u32 off , u32 val )
121+ static void ls_pcie_pf_lut_writel (struct ls_pcie * pcie , u32 off , u32 val )
102122{
103123 if (pcie -> big_endian )
104- iowrite32be (val , pcie -> pf_base + off );
124+ iowrite32be (val , pcie -> pf_lut_base + off );
105125 else
106- iowrite32 (val , pcie -> pf_base + off );
126+ iowrite32 (val , pcie -> pf_lut_base + off );
107127}
108128
109129static void ls_pcie_send_turnoff_msg (struct dw_pcie_rp * pp )
@@ -113,19 +133,19 @@ static void ls_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
113133 u32 val ;
114134 int ret ;
115135
116- val = ls_pcie_pf_readl (pcie , LS_PCIE_PF_MCR );
136+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_PF_MCR );
117137 val |= PF_MCR_PTOMR ;
118- ls_pcie_pf_writel (pcie , LS_PCIE_PF_MCR , val );
138+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_PF_MCR , val );
119139
120- ret = readx_poll_timeout (ls_pcie_pf_readl_addr , LS_PCIE_PF_MCR ,
140+ ret = readx_poll_timeout (ls_pcie_pf_lut_readl_addr , LS_PCIE_PF_MCR ,
121141 val , !(val & PF_MCR_PTOMR ),
122142 PCIE_PME_TO_L2_TIMEOUT_US /10 ,
123143 PCIE_PME_TO_L2_TIMEOUT_US );
124144 if (ret )
125145 dev_err (pcie -> pci -> dev , "PME_Turn_off timeout\n" );
126146}
127147
128- static void ls_pcie_exit_from_l2 (struct dw_pcie_rp * pp )
148+ static int ls_pcie_exit_from_l2 (struct dw_pcie_rp * pp )
129149{
130150 struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
131151 struct ls_pcie * pcie = to_ls_pcie (pci );
@@ -136,20 +156,22 @@ static void ls_pcie_exit_from_l2(struct dw_pcie_rp *pp)
136156 * Set PF_MCR_EXL2S bit in LS_PCIE_PF_MCR register for the link
137157 * to exit L2 state.
138158 */
139- val = ls_pcie_pf_readl (pcie , LS_PCIE_PF_MCR );
159+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_PF_MCR );
140160 val |= PF_MCR_EXL2S ;
141- ls_pcie_pf_writel (pcie , LS_PCIE_PF_MCR , val );
161+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_PF_MCR , val );
142162
143163 /*
144164 * L2 exit timeout of 10ms is not defined in the specifications,
145165 * it was chosen based on empirical observations.
146166 */
147- ret = readx_poll_timeout (ls_pcie_pf_readl_addr , LS_PCIE_PF_MCR ,
167+ ret = readx_poll_timeout (ls_pcie_pf_lut_readl_addr , LS_PCIE_PF_MCR ,
148168 val , !(val & PF_MCR_EXL2S ),
149169 1000 ,
150170 10000 );
151171 if (ret )
152172 dev_err (pcie -> pci -> dev , "L2 exit timeout\n" );
173+
174+ return ret ;
153175}
154176
155177static int ls_pcie_host_init (struct dw_pcie_rp * pp )
@@ -168,25 +190,130 @@ static int ls_pcie_host_init(struct dw_pcie_rp *pp)
168190 return 0 ;
169191}
170192
193+ static void scfg_pcie_send_turnoff_msg (struct regmap * scfg , u32 reg , u32 mask )
194+ {
195+ /* Send PME_Turn_Off message */
196+ regmap_write_bits (scfg , reg , mask , mask );
197+
198+ /*
199+ * There is no specific register to check for PME_To_Ack from endpoint.
200+ * So on the safe side, wait for PCIE_PME_TO_L2_TIMEOUT_US.
201+ */
202+ mdelay (PCIE_PME_TO_L2_TIMEOUT_US /1000 );
203+
204+ /*
205+ * Layerscape hardware reference manual recommends clearing the PMXMTTURNOFF bit
206+ * to complete the PME_Turn_Off handshake.
207+ */
208+ regmap_write_bits (scfg , reg , mask , 0 );
209+ }
210+
211+ static void ls1021a_pcie_send_turnoff_msg (struct dw_pcie_rp * pp )
212+ {
213+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
214+ struct ls_pcie * pcie = to_ls_pcie (pci );
215+
216+ scfg_pcie_send_turnoff_msg (pcie -> scfg , SCFG_PEXPMWRCR (pcie -> index ), PMXMTTURNOFF );
217+ }
218+
219+ static int scfg_pcie_exit_from_l2 (struct regmap * scfg , u32 reg , u32 mask )
220+ {
221+ /* Reset the PEX wrapper to bring the link out of L2 */
222+ regmap_write_bits (scfg , reg , mask , mask );
223+ regmap_write_bits (scfg , reg , mask , 0 );
224+
225+ return 0 ;
226+ }
227+
228+ static int ls1021a_pcie_exit_from_l2 (struct dw_pcie_rp * pp )
229+ {
230+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
231+ struct ls_pcie * pcie = to_ls_pcie (pci );
232+
233+ return scfg_pcie_exit_from_l2 (pcie -> scfg , SCFG_PEXSFTRSTCR , PEXSR (pcie -> index ));
234+ }
235+
236+ static void ls1043a_pcie_send_turnoff_msg (struct dw_pcie_rp * pp )
237+ {
238+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
239+ struct ls_pcie * pcie = to_ls_pcie (pci );
240+
241+ scfg_pcie_send_turnoff_msg (pcie -> scfg , SCFG_PEXPMECR , PEXPME (pcie -> index ));
242+ }
243+
244+ static int ls1043a_pcie_exit_from_l2 (struct dw_pcie_rp * pp )
245+ {
246+ struct dw_pcie * pci = to_dw_pcie_from_pp (pp );
247+ struct ls_pcie * pcie = to_ls_pcie (pci );
248+ u32 val ;
249+
250+ /*
251+ * Reset the PEX wrapper to bring the link out of L2.
252+ * LDBG_WE: allows the user to have write access to the PEXDBG[SR] for both setting and
253+ * clearing the soft reset on the PEX module.
254+ * LDBG_SR: When SR is set to 1, the PEX module enters soft reset.
255+ */
256+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_LDBG );
257+ val |= LDBG_WE ;
258+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_LDBG , val );
259+
260+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_LDBG );
261+ val |= LDBG_SR ;
262+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_LDBG , val );
263+
264+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_LDBG );
265+ val &= ~LDBG_SR ;
266+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_LDBG , val );
267+
268+ val = ls_pcie_pf_lut_readl (pcie , LS_PCIE_LDBG );
269+ val &= ~LDBG_WE ;
270+ ls_pcie_pf_lut_writel (pcie , LS_PCIE_LDBG , val );
271+
272+ return 0 ;
273+ }
274+
171275static const struct dw_pcie_host_ops ls_pcie_host_ops = {
172276 .init = ls_pcie_host_init ,
173277 .pme_turn_off = ls_pcie_send_turnoff_msg ,
174278};
175279
280+ static const struct dw_pcie_host_ops ls1021a_pcie_host_ops = {
281+ .init = ls_pcie_host_init ,
282+ .pme_turn_off = ls1021a_pcie_send_turnoff_msg ,
283+ };
284+
176285static const struct ls_pcie_drvdata ls1021a_drvdata = {
177- .pm_support = false,
286+ .pm_support = true,
287+ .scfg_support = true,
288+ .ops = & ls1021a_pcie_host_ops ,
289+ .exit_from_l2 = ls1021a_pcie_exit_from_l2 ,
290+ };
291+
292+ static const struct dw_pcie_host_ops ls1043a_pcie_host_ops = {
293+ .init = ls_pcie_host_init ,
294+ .pme_turn_off = ls1043a_pcie_send_turnoff_msg ,
295+ };
296+
297+ static const struct ls_pcie_drvdata ls1043a_drvdata = {
298+ .pf_lut_off = 0x10000 ,
299+ .pm_support = true,
300+ .scfg_support = true,
301+ .ops = & ls1043a_pcie_host_ops ,
302+ .exit_from_l2 = ls1043a_pcie_exit_from_l2 ,
178303};
179304
180305static const struct ls_pcie_drvdata layerscape_drvdata = {
181- .pf_off = 0xc0000 ,
306+ .pf_lut_off = 0xc0000 ,
182307 .pm_support = true,
308+ .ops = & ls_pcie_host_ops ,
309+ .exit_from_l2 = ls_pcie_exit_from_l2 ,
183310};
184311
185312static const struct of_device_id ls_pcie_of_match [] = {
186313 { .compatible = "fsl,ls1012a-pcie" , .data = & layerscape_drvdata },
187314 { .compatible = "fsl,ls1021a-pcie" , .data = & ls1021a_drvdata },
188315 { .compatible = "fsl,ls1028a-pcie" , .data = & layerscape_drvdata },
189- { .compatible = "fsl,ls1043a-pcie" , .data = & ls1021a_drvdata },
316+ { .compatible = "fsl,ls1043a-pcie" , .data = & ls1043a_drvdata },
190317 { .compatible = "fsl,ls1046a-pcie" , .data = & layerscape_drvdata },
191318 { .compatible = "fsl,ls2080a-pcie" , .data = & layerscape_drvdata },
192319 { .compatible = "fsl,ls2085a-pcie" , .data = & layerscape_drvdata },
@@ -201,6 +328,8 @@ static int ls_pcie_probe(struct platform_device *pdev)
201328 struct dw_pcie * pci ;
202329 struct ls_pcie * pcie ;
203330 struct resource * dbi_base ;
331+ u32 index [2 ];
332+ int ret ;
204333
205334 pcie = devm_kzalloc (dev , sizeof (* pcie ), GFP_KERNEL );
206335 if (!pcie )
@@ -213,9 +342,8 @@ static int ls_pcie_probe(struct platform_device *pdev)
213342 pcie -> drvdata = of_device_get_match_data (dev );
214343
215344 pci -> dev = dev ;
216- pci -> pp .ops = & ls_pcie_host_ops ;
217-
218345 pcie -> pci = pci ;
346+ pci -> pp .ops = pcie -> drvdata -> ops ;
219347
220348 dbi_base = platform_get_resource_byname (pdev , IORESOURCE_MEM , "regs" );
221349 pci -> dbi_base = devm_pci_remap_cfg_resource (dev , dbi_base );
@@ -224,7 +352,21 @@ static int ls_pcie_probe(struct platform_device *pdev)
224352
225353 pcie -> big_endian = of_property_read_bool (dev -> of_node , "big-endian" );
226354
227- pcie -> pf_base = pci -> dbi_base + pcie -> drvdata -> pf_off ;
355+ pcie -> pf_lut_base = pci -> dbi_base + pcie -> drvdata -> pf_lut_off ;
356+
357+ if (pcie -> drvdata -> scfg_support ) {
358+ pcie -> scfg = syscon_regmap_lookup_by_phandle (dev -> of_node , "fsl,pcie-scfg" );
359+ if (IS_ERR (pcie -> scfg )) {
360+ dev_err (dev , "No syscfg phandle specified\n" );
361+ return PTR_ERR (pcie -> scfg );
362+ }
363+
364+ ret = of_property_read_u32_array (dev -> of_node , "fsl,pcie-scfg" , index , 2 );
365+ if (ret )
366+ return ret ;
367+
368+ pcie -> index = index [1 ];
369+ }
228370
229371 if (!ls_pcie_is_bridge (pcie ))
230372 return - ENODEV ;
@@ -247,11 +389,14 @@ static int ls_pcie_suspend_noirq(struct device *dev)
247389static int ls_pcie_resume_noirq (struct device * dev )
248390{
249391 struct ls_pcie * pcie = dev_get_drvdata (dev );
392+ int ret ;
250393
251394 if (!pcie -> drvdata -> pm_support )
252395 return 0 ;
253396
254- ls_pcie_exit_from_l2 (& pcie -> pci -> pp );
397+ ret = pcie -> drvdata -> exit_from_l2 (& pcie -> pci -> pp );
398+ if (ret )
399+ return ret ;
255400
256401 return dw_pcie_resume_noirq (pcie -> pci );
257402}
0 commit comments