7
7
*/
8
8
9
9
#include <linux/clk.h>
10
+ #include <linux/clk-provider.h>
11
+ #include <linux/container_of.h>
10
12
#include <linux/delay.h>
11
13
#include <linux/gpio/consumer.h>
12
14
#include <linux/io.h>
22
24
#include "../../pci.h"
23
25
#include "pcie-cadence.h"
24
26
27
+ #define cdns_pcie_to_rc (p ) container_of(p, struct cdns_pcie_rc, pcie)
28
+
25
29
#define ENABLE_REG_SYS_2 0x108
26
30
#define STATUS_REG_SYS_2 0x508
27
31
#define STATUS_CLR_REG_SYS_2 0x708
@@ -44,6 +48,7 @@ enum link_status {
44
48
#define J721E_MODE_RC BIT(7)
45
49
#define LANE_COUNT (n ) ((n) << 8)
46
50
51
+ #define ACSPCIE_PAD_DISABLE_MASK GENMASK(1, 0)
47
52
#define GENERATION_SEL_MASK GENMASK(1, 0)
48
53
49
54
struct j721e_pcie {
@@ -52,6 +57,7 @@ struct j721e_pcie {
52
57
u32 mode ;
53
58
u32 num_lanes ;
54
59
u32 max_lanes ;
60
+ struct gpio_desc * reset_gpio ;
55
61
void __iomem * user_cfg_base ;
56
62
void __iomem * intd_cfg_base ;
57
63
u32 linkdown_irq_regfield ;
@@ -220,6 +226,36 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
220
226
return ret ;
221
227
}
222
228
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
+
223
259
static int j721e_pcie_ctrl_init (struct j721e_pcie * pcie )
224
260
{
225
261
struct device * dev = pcie -> cdns_pcie -> dev ;
@@ -259,7 +295,13 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
259
295
return ret ;
260
296
}
261
297
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 );
263
305
}
264
306
265
307
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)
482
524
pm_runtime_enable (dev );
483
525
ret = pm_runtime_get_sync (dev );
484
526
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" );
486
528
goto err_get_sync ;
487
529
}
488
530
489
531
ret = j721e_pcie_ctrl_init (pcie );
490
532
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" );
492
534
goto err_get_sync ;
493
535
}
494
536
495
537
ret = devm_request_irq (dev , irq , j721e_pcie_link_irq_handler , 0 ,
496
538
"j721e-pcie-link-down-irq" , pcie );
497
539
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 );
499
541
goto err_get_sync ;
500
542
}
501
543
@@ -505,42 +547,40 @@ static int j721e_pcie_probe(struct platform_device *pdev)
505
547
case PCI_MODE_RC :
506
548
gpiod = devm_gpiod_get_optional (dev , "reset" , GPIOD_OUT_LOW );
507
549
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" );
511
551
goto err_get_sync ;
512
552
}
553
+ pcie -> reset_gpio = gpiod ;
513
554
514
555
ret = cdns_pcie_init_phy (dev , cdns_pcie );
515
556
if (ret ) {
516
- dev_err (dev , "Failed to init phy\n" );
557
+ dev_err_probe (dev , ret , "Failed to init phy\n" );
517
558
goto err_get_sync ;
518
559
}
519
560
520
561
clk = devm_clk_get_optional (dev , "pcie_refclk" );
521
562
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" );
524
564
goto err_pcie_setup ;
525
565
}
526
566
527
567
ret = clk_prepare_enable (clk );
528
568
if (ret ) {
529
- dev_err (dev , "failed to enable pcie_refclk\n" );
569
+ dev_err_probe (dev , ret , "failed to enable pcie_refclk\n" );
530
570
goto err_pcie_setup ;
531
571
}
532
572
pcie -> refclk = clk ;
533
573
534
574
/*
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.
541
581
*/
542
582
if (gpiod ) {
543
- usleep_range ( 100 , 200 );
583
+ fsleep ( PCIE_T_PERST_CLK_US );
544
584
gpiod_set_value_cansleep (gpiod , 1 );
545
585
}
546
586
@@ -554,7 +594,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
554
594
case PCI_MODE_EP :
555
595
ret = cdns_pcie_init_phy (dev , cdns_pcie );
556
596
if (ret ) {
557
- dev_err (dev , "Failed to init phy\n" );
597
+ dev_err_probe (dev , ret , "Failed to init phy\n" );
558
598
goto err_get_sync ;
559
599
}
560
600
@@ -589,13 +629,95 @@ static void j721e_pcie_remove(struct platform_device *pdev)
589
629
pm_runtime_disable (dev );
590
630
}
591
631
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
+
592
713
static struct platform_driver j721e_pcie_driver = {
593
714
.probe = j721e_pcie_probe ,
594
715
.remove_new = j721e_pcie_remove ,
595
716
.driver = {
596
717
.name = "j721e-pcie" ,
597
718
.of_match_table = of_j721e_pcie_match ,
598
719
.suppress_bind_attrs = true,
720
+ .pm = pm_sleep_ptr (& j721e_pcie_pm_ops ),
599
721
},
600
722
};
601
723
builtin_platform_driver (j721e_pcie_driver );
0 commit comments