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>
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
4954struct 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+
223259static 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
265307static 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+
592713static 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};
601723builtin_platform_driver (j721e_pcie_driver );
0 commit comments