10
10
*/
11
11
12
12
#include <linux/clk.h>
13
+ #include <linux/debugfs.h>
13
14
#include <linux/delay.h>
14
15
#include <linux/gpio/consumer.h>
15
16
#include <linux/mfd/syscon.h>
45
46
#define PARF_ATU_BASE_ADDR 0x634
46
47
#define PARF_ATU_BASE_ADDR_HI 0x638
47
48
#define PARF_SRIS_MODE 0x644
49
+ #define PARF_DEBUG_CNT_PM_LINKST_IN_L2 0xc04
50
+ #define PARF_DEBUG_CNT_PM_LINKST_IN_L1 0xc0c
51
+ #define PARF_DEBUG_CNT_PM_LINKST_IN_L0S 0xc10
52
+ #define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1 0xc84
53
+ #define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 0xc88
48
54
#define PARF_DEVICE_TYPE 0x1000
49
55
#define PARF_BDF_TO_SID_CFG 0x2c00
50
56
@@ -135,12 +141,14 @@ enum qcom_pcie_ep_link_status {
135
141
* @pci: Designware PCIe controller struct
136
142
* @parf: Qualcomm PCIe specific PARF register base
137
143
* @elbi: Designware PCIe specific ELBI register base
144
+ * @mmio: MMIO register base
138
145
* @perst_map: PERST regmap
139
146
* @mmio_res: MMIO region resource
140
147
* @core_reset: PCIe Endpoint core reset
141
148
* @reset: PERST# GPIO
142
149
* @wake: WAKE# GPIO
143
150
* @phy: PHY controller block
151
+ * @debugfs: PCIe Endpoint Debugfs directory
144
152
* @clks: PCIe clocks
145
153
* @num_clks: PCIe clocks count
146
154
* @perst_en: Flag for PERST enable
@@ -154,13 +162,15 @@ struct qcom_pcie_ep {
154
162
155
163
void __iomem * parf ;
156
164
void __iomem * elbi ;
165
+ void __iomem * mmio ;
157
166
struct regmap * perst_map ;
158
167
struct resource * mmio_res ;
159
168
160
169
struct reset_control * core_reset ;
161
170
struct gpio_desc * reset ;
162
171
struct gpio_desc * wake ;
163
172
struct phy * phy ;
173
+ struct dentry * debugfs ;
164
174
165
175
struct clk_bulk_data * clks ;
166
176
int num_clks ;
@@ -446,6 +456,9 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,
446
456
447
457
pcie_ep -> mmio_res = platform_get_resource_byname (pdev , IORESOURCE_MEM ,
448
458
"mmio" );
459
+ pcie_ep -> mmio = devm_pci_remap_cfg_resource (dev , pcie_ep -> mmio_res );
460
+ if (IS_ERR (pcie_ep -> mmio ))
461
+ return PTR_ERR (pcie_ep -> mmio );
449
462
450
463
syscon = of_parse_phandle (dev -> of_node , "qcom,perst-regs" , 0 );
451
464
if (!syscon ) {
@@ -627,6 +640,37 @@ static int qcom_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
627
640
}
628
641
}
629
642
643
+ static int qcom_pcie_ep_link_transition_count (struct seq_file * s , void * data )
644
+ {
645
+ struct qcom_pcie_ep * pcie_ep = (struct qcom_pcie_ep * )
646
+ dev_get_drvdata (s -> private );
647
+
648
+ seq_printf (s , "L0s transition count: %u\n" ,
649
+ readl_relaxed (pcie_ep -> mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L0S ));
650
+
651
+ seq_printf (s , "L1 transition count: %u\n" ,
652
+ readl_relaxed (pcie_ep -> mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L1 ));
653
+
654
+ seq_printf (s , "L1.1 transition count: %u\n" ,
655
+ readl_relaxed (pcie_ep -> mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1 ));
656
+
657
+ seq_printf (s , "L1.2 transition count: %u\n" ,
658
+ readl_relaxed (pcie_ep -> mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 ));
659
+
660
+ seq_printf (s , "L2 transition count: %u\n" ,
661
+ readl_relaxed (pcie_ep -> mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L2 ));
662
+
663
+ return 0 ;
664
+ }
665
+
666
+ static void qcom_pcie_ep_init_debugfs (struct qcom_pcie_ep * pcie_ep )
667
+ {
668
+ struct dw_pcie * pci = & pcie_ep -> pci ;
669
+
670
+ debugfs_create_devm_seqfile (pci -> dev , "link_transition_count" , pcie_ep -> debugfs ,
671
+ qcom_pcie_ep_link_transition_count );
672
+ }
673
+
630
674
static const struct pci_epc_features qcom_pcie_epc_features = {
631
675
.linkup_notifier = true,
632
676
.core_init_notifier = true,
@@ -659,6 +703,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
659
703
{
660
704
struct device * dev = & pdev -> dev ;
661
705
struct qcom_pcie_ep * pcie_ep ;
706
+ char * name ;
662
707
int ret ;
663
708
664
709
pcie_ep = devm_kzalloc (dev , sizeof (* pcie_ep ), GFP_KERNEL );
@@ -690,8 +735,21 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
690
735
if (ret )
691
736
goto err_disable_resources ;
692
737
738
+ name = devm_kasprintf (dev , GFP_KERNEL , "%pOFP" , dev -> of_node );
739
+ if (!name ) {
740
+ ret = - ENOMEM ;
741
+ goto err_disable_irqs ;
742
+ }
743
+
744
+ pcie_ep -> debugfs = debugfs_create_dir (name , NULL );
745
+ qcom_pcie_ep_init_debugfs (pcie_ep );
746
+
693
747
return 0 ;
694
748
749
+ err_disable_irqs :
750
+ disable_irq (pcie_ep -> global_irq );
751
+ disable_irq (pcie_ep -> perst_irq );
752
+
695
753
err_disable_resources :
696
754
qcom_pcie_disable_resources (pcie_ep );
697
755
@@ -705,6 +763,8 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
705
763
disable_irq (pcie_ep -> global_irq );
706
764
disable_irq (pcie_ep -> perst_irq );
707
765
766
+ debugfs_remove_recursive (pcie_ep -> debugfs );
767
+
708
768
if (pcie_ep -> link_status == QCOM_PCIE_EP_LINK_DISABLED )
709
769
return 0 ;
710
770
0 commit comments