Skip to content

Commit d1624da

Browse files
committed
Merge branch 'pci/controller/j721e'
- Add DT "ti,syscon-acspcie-proxy-ctrl" and driver support to enable the ACSPCIE module to drive Refclk for the Endpoint (Siddharth Vadapalli) - Extract the cadence link setup from cdns_pcie_host_setup() so link setup can be done separately during resume (Thomas Richard) - Use dev_err_probe() to simplify j721e probe (Thomas Richard) - Add T_PERST_CLK_US definition for the mandatory delay between Refclk becoming stable and PERST# being deasserted (Thomas Richard) - Add j721e suspend and resume support (Théo Lebrun) * pci/controller/j721e: PCI: j721e: Add suspend and resume support PCI: j721e: Use T_PERST_CLK_US macro PCI: Add T_PERST_CLK_US macro PCI: j721e: Add reset GPIO to struct j721e_pcie PCI: j721e: Use dev_err_probe() in the probe() function PCI: cadence: Set cdns_pcie_host_init() global PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup() PCI: j721e: Enable ACSPCIE Refclk if "ti,syscon-acspcie-proxy-ctrl" exists dt-bindings: PCI: ti,j721e-pci-host: Add ACSPCIE proxy control property
2 parents f8ca62b + c538d40 commit d1624da

File tree

5 files changed

+207
-36
lines changed

5 files changed

+207
-36
lines changed

Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ properties:
3838
- const: reg
3939
- const: cfg
4040

41+
ti,syscon-acspcie-proxy-ctrl:
42+
$ref: /schemas/types.yaml#/definitions/phandle-array
43+
items:
44+
- items:
45+
- description: Phandle to the ACSPCIE Proxy Control Register
46+
- description: Bitmask corresponding to the PAD IO Buffer
47+
output enable fields (Active Low).
48+
description: Specifier for enabling the ACSPCIE PAD outputs to drive
49+
the reference clock to the Endpoint device.
50+
4151
ti,syscon-pcie-ctrl:
4252
$ref: /schemas/types.yaml#/definitions/phandle-array
4353
items:

drivers/pci/controller/cadence/pci-j721e.c

Lines changed: 141 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88

99
#include <linux/clk.h>
10+
#include <linux/clk-provider.h>
11+
#include <linux/container_of.h>
1012
#include <linux/delay.h>
1113
#include <linux/gpio/consumer.h>
1214
#include <linux/io.h>
@@ -22,6 +24,8 @@
2224
#include "../../pci.h"
2325
#include "pcie-cadence.h"
2426

27+
#define cdns_pcie_to_rc(p) container_of(p, struct cdns_pcie_rc, pcie)
28+
2529
#define ENABLE_REG_SYS_2 0x108
2630
#define STATUS_REG_SYS_2 0x508
2731
#define STATUS_CLR_REG_SYS_2 0x708
@@ -44,6 +48,7 @@ enum link_status {
4448
#define J721E_MODE_RC BIT(7)
4549
#define LANE_COUNT(n) ((n) << 8)
4650

51+
#define ACSPCIE_PAD_DISABLE_MASK GENMASK(1, 0)
4752
#define GENERATION_SEL_MASK GENMASK(1, 0)
4853

4954
struct j721e_pcie {
@@ -52,6 +57,7 @@ struct j721e_pcie {
5257
u32 mode;
5358
u32 num_lanes;
5459
u32 max_lanes;
60+
struct gpio_desc *reset_gpio;
5561
void __iomem *user_cfg_base;
5662
void __iomem *intd_cfg_base;
5763
u32 linkdown_irq_regfield;
@@ -220,6 +226,36 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
220226
return ret;
221227
}
222228

229+
static int j721e_enable_acspcie_refclk(struct j721e_pcie *pcie,
230+
struct regmap *syscon)
231+
{
232+
struct device *dev = pcie->cdns_pcie->dev;
233+
struct device_node *node = dev->of_node;
234+
u32 mask = ACSPCIE_PAD_DISABLE_MASK;
235+
struct of_phandle_args args;
236+
u32 val;
237+
int ret;
238+
239+
ret = of_parse_phandle_with_fixed_args(node,
240+
"ti,syscon-acspcie-proxy-ctrl",
241+
1, 0, &args);
242+
if (ret) {
243+
dev_err(dev,
244+
"ti,syscon-acspcie-proxy-ctrl has invalid arguments\n");
245+
return ret;
246+
}
247+
248+
/* Clear PAD IO disable bits to enable refclk output */
249+
val = ~(args.args[0]);
250+
ret = regmap_update_bits(syscon, 0, mask, val);
251+
if (ret) {
252+
dev_err(dev, "failed to enable ACSPCIE refclk: %d\n", ret);
253+
return ret;
254+
}
255+
256+
return 0;
257+
}
258+
223259
static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
224260
{
225261
struct device *dev = pcie->cdns_pcie->dev;
@@ -259,7 +295,13 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
259295
return ret;
260296
}
261297

262-
return 0;
298+
/* Enable ACSPCIE refclk output if the optional property exists */
299+
syscon = syscon_regmap_lookup_by_phandle_optional(node,
300+
"ti,syscon-acspcie-proxy-ctrl");
301+
if (!syscon)
302+
return 0;
303+
304+
return j721e_enable_acspcie_refclk(pcie, syscon);
263305
}
264306

265307
static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
@@ -482,20 +524,20 @@ static int j721e_pcie_probe(struct platform_device *pdev)
482524
pm_runtime_enable(dev);
483525
ret = pm_runtime_get_sync(dev);
484526
if (ret < 0) {
485-
dev_err(dev, "pm_runtime_get_sync failed\n");
527+
dev_err_probe(dev, ret, "pm_runtime_get_sync failed\n");
486528
goto err_get_sync;
487529
}
488530

489531
ret = j721e_pcie_ctrl_init(pcie);
490532
if (ret < 0) {
491-
dev_err(dev, "pm_runtime_get_sync failed\n");
533+
dev_err_probe(dev, ret, "pm_runtime_get_sync failed\n");
492534
goto err_get_sync;
493535
}
494536

495537
ret = devm_request_irq(dev, irq, j721e_pcie_link_irq_handler, 0,
496538
"j721e-pcie-link-down-irq", pcie);
497539
if (ret < 0) {
498-
dev_err(dev, "failed to request link state IRQ %d\n", irq);
540+
dev_err_probe(dev, ret, "failed to request link state IRQ %d\n", irq);
499541
goto err_get_sync;
500542
}
501543

@@ -505,42 +547,40 @@ static int j721e_pcie_probe(struct platform_device *pdev)
505547
case PCI_MODE_RC:
506548
gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
507549
if (IS_ERR(gpiod)) {
508-
ret = PTR_ERR(gpiod);
509-
if (ret != -EPROBE_DEFER)
510-
dev_err(dev, "Failed to get reset GPIO\n");
550+
ret = dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get reset GPIO\n");
511551
goto err_get_sync;
512552
}
553+
pcie->reset_gpio = gpiod;
513554

514555
ret = cdns_pcie_init_phy(dev, cdns_pcie);
515556
if (ret) {
516-
dev_err(dev, "Failed to init phy\n");
557+
dev_err_probe(dev, ret, "Failed to init phy\n");
517558
goto err_get_sync;
518559
}
519560

520561
clk = devm_clk_get_optional(dev, "pcie_refclk");
521562
if (IS_ERR(clk)) {
522-
ret = PTR_ERR(clk);
523-
dev_err(dev, "failed to get pcie_refclk\n");
563+
ret = dev_err_probe(dev, PTR_ERR(clk), "failed to get pcie_refclk\n");
524564
goto err_pcie_setup;
525565
}
526566

527567
ret = clk_prepare_enable(clk);
528568
if (ret) {
529-
dev_err(dev, "failed to enable pcie_refclk\n");
569+
dev_err_probe(dev, ret, "failed to enable pcie_refclk\n");
530570
goto err_pcie_setup;
531571
}
532572
pcie->refclk = clk;
533573

534574
/*
535-
* "Power Sequencing and Reset Signal Timings" table in
536-
* PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
537-
* indicates PERST# should be deasserted after minimum of 100us
538-
* once REFCLK is stable. The REFCLK to the connector in RC
539-
* mode is selected while enabling the PHY. So deassert PERST#
540-
* after 100 us.
575+
* The "Power Sequencing and Reset Signal Timings" table of the
576+
* PCI Express Card Electromechanical Specification, Revision
577+
* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST#
578+
* should be deasserted after minimum of 100us once REFCLK is
579+
* stable. The REFCLK to the connector in RC mode is selected
580+
* while enabling the PHY. So deassert PERST# after 100 us.
541581
*/
542582
if (gpiod) {
543-
usleep_range(100, 200);
583+
fsleep(PCIE_T_PERST_CLK_US);
544584
gpiod_set_value_cansleep(gpiod, 1);
545585
}
546586

@@ -554,7 +594,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
554594
case PCI_MODE_EP:
555595
ret = cdns_pcie_init_phy(dev, cdns_pcie);
556596
if (ret) {
557-
dev_err(dev, "Failed to init phy\n");
597+
dev_err_probe(dev, ret, "Failed to init phy\n");
558598
goto err_get_sync;
559599
}
560600

@@ -589,13 +629,95 @@ static void j721e_pcie_remove(struct platform_device *pdev)
589629
pm_runtime_disable(dev);
590630
}
591631

632+
static int j721e_pcie_suspend_noirq(struct device *dev)
633+
{
634+
struct j721e_pcie *pcie = dev_get_drvdata(dev);
635+
636+
if (pcie->mode == PCI_MODE_RC) {
637+
gpiod_set_value_cansleep(pcie->reset_gpio, 0);
638+
clk_disable_unprepare(pcie->refclk);
639+
}
640+
641+
cdns_pcie_disable_phy(pcie->cdns_pcie);
642+
643+
return 0;
644+
}
645+
646+
static int j721e_pcie_resume_noirq(struct device *dev)
647+
{
648+
struct j721e_pcie *pcie = dev_get_drvdata(dev);
649+
struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
650+
int ret;
651+
652+
ret = j721e_pcie_ctrl_init(pcie);
653+
if (ret < 0)
654+
return ret;
655+
656+
j721e_pcie_config_link_irq(pcie);
657+
658+
/*
659+
* This is not called explicitly in the probe, it is called by
660+
* cdns_pcie_init_phy().
661+
*/
662+
ret = cdns_pcie_enable_phy(pcie->cdns_pcie);
663+
if (ret < 0)
664+
return ret;
665+
666+
if (pcie->mode == PCI_MODE_RC) {
667+
struct cdns_pcie_rc *rc = cdns_pcie_to_rc(cdns_pcie);
668+
669+
ret = clk_prepare_enable(pcie->refclk);
670+
if (ret < 0)
671+
return ret;
672+
673+
/*
674+
* The "Power Sequencing and Reset Signal Timings" table of the
675+
* PCI Express Card Electromechanical Specification, Revision
676+
* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST#
677+
* should be deasserted after minimum of 100us once REFCLK is
678+
* stable. The REFCLK to the connector in RC mode is selected
679+
* while enabling the PHY. So deassert PERST# after 100 us.
680+
*/
681+
if (pcie->reset_gpio) {
682+
fsleep(PCIE_T_PERST_CLK_US);
683+
gpiod_set_value_cansleep(pcie->reset_gpio, 1);
684+
}
685+
686+
ret = cdns_pcie_host_link_setup(rc);
687+
if (ret < 0) {
688+
clk_disable_unprepare(pcie->refclk);
689+
return ret;
690+
}
691+
692+
/*
693+
* Reset internal status of BARs to force reinitialization in
694+
* cdns_pcie_host_init().
695+
*/
696+
for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
697+
rc->avail_ib_bar[bar] = true;
698+
699+
ret = cdns_pcie_host_init(rc);
700+
if (ret) {
701+
clk_disable_unprepare(pcie->refclk);
702+
return ret;
703+
}
704+
}
705+
706+
return 0;
707+
}
708+
709+
static DEFINE_NOIRQ_DEV_PM_OPS(j721e_pcie_pm_ops,
710+
j721e_pcie_suspend_noirq,
711+
j721e_pcie_resume_noirq);
712+
592713
static struct platform_driver j721e_pcie_driver = {
593714
.probe = j721e_pcie_probe,
594715
.remove_new = j721e_pcie_remove,
595716
.driver = {
596717
.name = "j721e-pcie",
597718
.of_match_table = of_j721e_pcie_match,
598719
.suppress_bind_attrs = true,
720+
.pm = pm_sleep_ptr(&j721e_pcie_pm_ops),
599721
},
600722
};
601723
builtin_platform_driver(j721e_pcie_driver);

drivers/pci/controller/cadence/pcie-cadence-host.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
485485
return cdns_pcie_host_map_dma_ranges(rc);
486486
}
487487

488-
static int cdns_pcie_host_init(struct device *dev,
489-
struct cdns_pcie_rc *rc)
488+
int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
490489
{
491490
int err;
492491

@@ -497,6 +496,30 @@ static int cdns_pcie_host_init(struct device *dev,
497496
return cdns_pcie_host_init_address_translation(rc);
498497
}
499498

499+
int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
500+
{
501+
struct cdns_pcie *pcie = &rc->pcie;
502+
struct device *dev = rc->pcie.dev;
503+
int ret;
504+
505+
if (rc->quirk_detect_quiet_flag)
506+
cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
507+
508+
cdns_pcie_host_enable_ptm_response(pcie);
509+
510+
ret = cdns_pcie_start_link(pcie);
511+
if (ret) {
512+
dev_err(dev, "Failed to start link\n");
513+
return ret;
514+
}
515+
516+
ret = cdns_pcie_host_start_link(rc);
517+
if (ret)
518+
dev_dbg(dev, "PCIe link never came up\n");
519+
520+
return 0;
521+
}
522+
500523
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
501524
{
502525
struct device *dev = rc->pcie.dev;
@@ -533,25 +556,14 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
533556
return PTR_ERR(rc->cfg_base);
534557
rc->cfg_res = res;
535558

536-
if (rc->quirk_detect_quiet_flag)
537-
cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
538-
539-
cdns_pcie_host_enable_ptm_response(pcie);
540-
541-
ret = cdns_pcie_start_link(pcie);
542-
if (ret) {
543-
dev_err(dev, "Failed to start link\n");
544-
return ret;
545-
}
546-
547-
ret = cdns_pcie_host_start_link(rc);
559+
ret = cdns_pcie_host_link_setup(rc);
548560
if (ret)
549-
dev_dbg(dev, "PCIe link never came up\n");
561+
return ret;
550562

551563
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
552564
rc->avail_ib_bar[bar] = true;
553565

554-
ret = cdns_pcie_host_init(dev, rc);
566+
ret = cdns_pcie_host_init(rc);
555567
if (ret)
556568
return ret;
557569

drivers/pci/controller/cadence/pcie-cadence.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,22 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
520520
}
521521

522522
#ifdef CONFIG_PCIE_CADENCE_HOST
523+
int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
524+
int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
523525
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
524526
void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
525527
int where);
526528
#else
529+
static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
530+
{
531+
return 0;
532+
}
533+
534+
static inline int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
535+
{
536+
return 0;
537+
}
538+
527539
static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
528540
{
529541
return 0;

0 commit comments

Comments
 (0)