5
5
6
6
#include <linux/delay.h>
7
7
#include <linux/kernel.h>
8
+ #include <linux/module.h>
8
9
#include <linux/list_sort.h>
9
10
#include <linux/of_address.h>
10
11
#include <linux/of_pci.h>
@@ -72,6 +73,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
72
73
73
74
return rc -> cfg_base + (where & 0xfff );
74
75
}
76
+ EXPORT_SYMBOL_GPL (cdns_pci_map_bus );
75
77
76
78
static struct pci_ops cdns_pcie_host_ops = {
77
79
.map_bus = cdns_pci_map_bus ,
@@ -150,6 +152,14 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
150
152
return ret ;
151
153
}
152
154
155
+ static void cdns_pcie_host_disable_ptm_response (struct cdns_pcie * pcie )
156
+ {
157
+ u32 val ;
158
+
159
+ val = cdns_pcie_readl (pcie , CDNS_PCIE_LM_PTM_CTRL );
160
+ cdns_pcie_writel (pcie , CDNS_PCIE_LM_PTM_CTRL , val & ~CDNS_PCIE_LM_TPM_CTRL_PTMRSEN );
161
+ }
162
+
153
163
static void cdns_pcie_host_enable_ptm_response (struct cdns_pcie * pcie )
154
164
{
155
165
u32 val ;
@@ -175,6 +185,26 @@ static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc)
175
185
return ret ;
176
186
}
177
187
188
+ static void cdns_pcie_host_deinit_root_port (struct cdns_pcie_rc * rc )
189
+ {
190
+ struct cdns_pcie * pcie = & rc -> pcie ;
191
+ u32 value , ctrl ;
192
+
193
+ cdns_pcie_rp_writew (pcie , PCI_CLASS_DEVICE , 0xffff );
194
+ cdns_pcie_rp_writeb (pcie , PCI_CLASS_PROG , 0xff );
195
+ cdns_pcie_rp_writeb (pcie , PCI_CLASS_REVISION , 0xff );
196
+ cdns_pcie_writel (pcie , CDNS_PCIE_LM_ID , 0xffffffff );
197
+ cdns_pcie_rp_writew (pcie , PCI_DEVICE_ID , 0xffff );
198
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED ;
199
+ value = ~(CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL (ctrl ) |
200
+ CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL (ctrl ) |
201
+ CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE |
202
+ CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS |
203
+ CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE |
204
+ CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS );
205
+ cdns_pcie_writel (pcie , CDNS_PCIE_LM_RC_BAR_CFG , value );
206
+ }
207
+
178
208
static int cdns_pcie_host_init_root_port (struct cdns_pcie_rc * rc )
179
209
{
180
210
struct cdns_pcie * pcie = & rc -> pcie ;
@@ -391,6 +421,32 @@ static int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
391
421
return resource_size (entry2 -> res ) - resource_size (entry1 -> res );
392
422
}
393
423
424
+ static void cdns_pcie_host_unmap_dma_ranges (struct cdns_pcie_rc * rc )
425
+ {
426
+ struct cdns_pcie * pcie = & rc -> pcie ;
427
+ enum cdns_pcie_rp_bar bar ;
428
+ u32 value ;
429
+
430
+ /* Reset inbound configuration for all BARs which were being used */
431
+ for (bar = RP_BAR0 ; bar <= RP_NO_BAR ; bar ++ ) {
432
+ if (rc -> avail_ib_bar [bar ])
433
+ continue ;
434
+
435
+ cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_RP_BAR_ADDR0 (bar ), 0 );
436
+ cdns_pcie_writel (pcie , CDNS_PCIE_AT_IB_RP_BAR_ADDR1 (bar ), 0 );
437
+
438
+ if (bar == RP_NO_BAR )
439
+ continue ;
440
+
441
+ value = ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS (bar ) |
442
+ LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS (bar ) |
443
+ LM_RC_BAR_CFG_CTRL_MEM_32BITS (bar ) |
444
+ LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS (bar ) |
445
+ LM_RC_BAR_CFG_APERTURE (bar , bar_aperture_mask [bar ] + 2 ));
446
+ cdns_pcie_writel (pcie , CDNS_PCIE_LM_RC_BAR_CFG , value );
447
+ }
448
+ }
449
+
394
450
static int cdns_pcie_host_map_dma_ranges (struct cdns_pcie_rc * rc )
395
451
{
396
452
struct cdns_pcie * pcie = & rc -> pcie ;
@@ -428,6 +484,29 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
428
484
return 0 ;
429
485
}
430
486
487
+ static void cdns_pcie_host_deinit_address_translation (struct cdns_pcie_rc * rc )
488
+ {
489
+ struct cdns_pcie * pcie = & rc -> pcie ;
490
+ struct pci_host_bridge * bridge = pci_host_bridge_from_priv (rc );
491
+ struct resource_entry * entry ;
492
+ int r ;
493
+
494
+ cdns_pcie_host_unmap_dma_ranges (rc );
495
+
496
+ /*
497
+ * Reset outbound region 0 which was reserved for configuration space
498
+ * accesses.
499
+ */
500
+ cdns_pcie_reset_outbound_region (pcie , 0 );
501
+
502
+ /* Reset rest of the outbound regions */
503
+ r = 1 ;
504
+ resource_list_for_each_entry (entry , & bridge -> windows ) {
505
+ cdns_pcie_reset_outbound_region (pcie , r );
506
+ r ++ ;
507
+ }
508
+ }
509
+
431
510
static int cdns_pcie_host_init_address_translation (struct cdns_pcie_rc * rc )
432
511
{
433
512
struct cdns_pcie * pcie = & rc -> pcie ;
@@ -485,6 +564,12 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
485
564
return cdns_pcie_host_map_dma_ranges (rc );
486
565
}
487
566
567
+ static void cdns_pcie_host_deinit (struct cdns_pcie_rc * rc )
568
+ {
569
+ cdns_pcie_host_deinit_address_translation (rc );
570
+ cdns_pcie_host_deinit_root_port (rc );
571
+ }
572
+
488
573
int cdns_pcie_host_init (struct cdns_pcie_rc * rc )
489
574
{
490
575
int err ;
@@ -495,6 +580,15 @@ int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
495
580
496
581
return cdns_pcie_host_init_address_translation (rc );
497
582
}
583
+ EXPORT_SYMBOL_GPL (cdns_pcie_host_init );
584
+
585
+ static void cdns_pcie_host_link_disable (struct cdns_pcie_rc * rc )
586
+ {
587
+ struct cdns_pcie * pcie = & rc -> pcie ;
588
+
589
+ cdns_pcie_stop_link (pcie );
590
+ cdns_pcie_host_disable_ptm_response (pcie );
591
+ }
498
592
499
593
int cdns_pcie_host_link_setup (struct cdns_pcie_rc * rc )
500
594
{
@@ -519,6 +613,20 @@ int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
519
613
520
614
return 0 ;
521
615
}
616
+ EXPORT_SYMBOL_GPL (cdns_pcie_host_link_setup );
617
+
618
+ void cdns_pcie_host_disable (struct cdns_pcie_rc * rc )
619
+ {
620
+ struct pci_host_bridge * bridge ;
621
+
622
+ bridge = pci_host_bridge_from_priv (rc );
623
+ pci_stop_root_bus (bridge -> bus );
624
+ pci_remove_root_bus (bridge -> bus );
625
+
626
+ cdns_pcie_host_deinit (rc );
627
+ cdns_pcie_host_link_disable (rc );
628
+ }
629
+ EXPORT_SYMBOL_GPL (cdns_pcie_host_disable );
522
630
523
631
int cdns_pcie_host_setup (struct cdns_pcie_rc * rc )
524
632
{
@@ -570,14 +678,10 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
570
678
if (!bridge -> ops )
571
679
bridge -> ops = & cdns_pcie_host_ops ;
572
680
573
- ret = pci_host_probe (bridge );
574
- if (ret < 0 )
575
- goto err_init ;
576
-
577
- return 0 ;
578
-
579
- err_init :
580
- pm_runtime_put_sync (dev );
581
-
582
- return ret ;
681
+ return pci_host_probe (bridge );
583
682
}
683
+ EXPORT_SYMBOL_GPL (cdns_pcie_host_setup );
684
+
685
+ MODULE_LICENSE ("GPL" );
686
+ MODULE_DESCRIPTION ("Cadence PCIe host controller driver" );
687
+ MODULE_AUTHOR (
"Cyrille Pitchen <[email protected] >" );
0 commit comments