6
6
* Description: Altera PCIe host controller driver
7
7
*/
8
8
9
+ #include <linux/bitfield.h>
9
10
#include <linux/delay.h>
10
11
#include <linux/interrupt.h>
11
12
#include <linux/irqchip/chained_irq.h>
77
78
#define S10_TLP_FMTTYPE_CFGWR0 0x45
78
79
#define S10_TLP_FMTTYPE_CFGWR1 0x44
79
80
81
+ #define AGLX_RP_CFG_ADDR (pcie , reg ) (((pcie)->hip_base) + (reg))
82
+ #define AGLX_RP_SECONDARY (pcie ) \
83
+ readb(AGLX_RP_CFG_ADDR(pcie, PCI_SECONDARY_BUS))
84
+
85
+ #define AGLX_BDF_REG 0x00002004
86
+ #define AGLX_ROOT_PORT_IRQ_STATUS 0x14c
87
+ #define AGLX_ROOT_PORT_IRQ_ENABLE 0x150
88
+ #define CFG_AER BIT(4)
89
+
90
+ #define AGLX_CFG_TARGET GENMASK(13, 12)
91
+ #define AGLX_CFG_TARGET_TYPE0 0
92
+ #define AGLX_CFG_TARGET_TYPE1 1
93
+ #define AGLX_CFG_TARGET_LOCAL_2000 2
94
+ #define AGLX_CFG_TARGET_LOCAL_3000 3
95
+
80
96
enum altera_pcie_version {
81
97
ALTERA_PCIE_V1 = 0 ,
82
98
ALTERA_PCIE_V2 ,
99
+ ALTERA_PCIE_V3 ,
83
100
};
84
101
85
102
struct altera_pcie {
@@ -102,6 +119,11 @@ struct altera_pcie_ops {
102
119
int size , u32 * value );
103
120
int (* rp_write_cfg )(struct altera_pcie * pcie , u8 busno ,
104
121
int where , int size , u32 value );
122
+ int (* ep_read_cfg )(struct altera_pcie * pcie , u8 busno ,
123
+ unsigned int devfn , int where , int size , u32 * value );
124
+ int (* ep_write_cfg )(struct altera_pcie * pcie , u8 busno ,
125
+ unsigned int devfn , int where , int size , u32 value );
126
+ void (* rp_isr )(struct irq_desc * desc );
105
127
};
106
128
107
129
struct altera_pcie_data {
@@ -112,6 +134,9 @@ struct altera_pcie_data {
112
134
u32 cfgrd1 ;
113
135
u32 cfgwr0 ;
114
136
u32 cfgwr1 ;
137
+ u32 port_conf_offset ;
138
+ u32 port_irq_status_offset ;
139
+ u32 port_irq_enable_offset ;
115
140
};
116
141
117
142
struct tlp_rp_regpair_t {
@@ -131,6 +156,28 @@ static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg)
131
156
return readl_relaxed (pcie -> cra_base + reg );
132
157
}
133
158
159
+ static inline void cra_writew (struct altera_pcie * pcie , const u32 value ,
160
+ const u32 reg )
161
+ {
162
+ writew_relaxed (value , pcie -> cra_base + reg );
163
+ }
164
+
165
+ static inline u32 cra_readw (struct altera_pcie * pcie , const u32 reg )
166
+ {
167
+ return readw_relaxed (pcie -> cra_base + reg );
168
+ }
169
+
170
+ static inline void cra_writeb (struct altera_pcie * pcie , const u32 value ,
171
+ const u32 reg )
172
+ {
173
+ writeb_relaxed (value , pcie -> cra_base + reg );
174
+ }
175
+
176
+ static inline u32 cra_readb (struct altera_pcie * pcie , const u32 reg )
177
+ {
178
+ return readb_relaxed (pcie -> cra_base + reg );
179
+ }
180
+
134
181
static bool altera_pcie_link_up (struct altera_pcie * pcie )
135
182
{
136
183
return !!((cra_readl (pcie , RP_LTSSM ) & RP_LTSSM_MASK ) == LTSSM_L0 );
@@ -145,6 +192,15 @@ static bool s10_altera_pcie_link_up(struct altera_pcie *pcie)
145
192
return !!(readw (addr ) & PCI_EXP_LNKSTA_DLLLA );
146
193
}
147
194
195
+ static bool aglx_altera_pcie_link_up (struct altera_pcie * pcie )
196
+ {
197
+ void __iomem * addr = AGLX_RP_CFG_ADDR (pcie ,
198
+ pcie -> pcie_data -> cap_offset +
199
+ PCI_EXP_LNKSTA );
200
+
201
+ return (readw_relaxed (addr ) & PCI_EXP_LNKSTA_DLLLA );
202
+ }
203
+
148
204
/*
149
205
* Altera PCIe port uses BAR0 of RC's configuration space as the translation
150
206
* from PCI bus to native BUS. Entire DDR region is mapped into PCIe space
@@ -425,6 +481,103 @@ static int s10_rp_write_cfg(struct altera_pcie *pcie, u8 busno,
425
481
return PCIBIOS_SUCCESSFUL ;
426
482
}
427
483
484
+ static int aglx_rp_read_cfg (struct altera_pcie * pcie , int where ,
485
+ int size , u32 * value )
486
+ {
487
+ void __iomem * addr = AGLX_RP_CFG_ADDR (pcie , where );
488
+
489
+ switch (size ) {
490
+ case 1 :
491
+ * value = readb_relaxed (addr );
492
+ break ;
493
+ case 2 :
494
+ * value = readw_relaxed (addr );
495
+ break ;
496
+ default :
497
+ * value = readl_relaxed (addr );
498
+ break ;
499
+ }
500
+
501
+ /* Interrupt PIN not programmed in hardware, set to INTA. */
502
+ if (where == PCI_INTERRUPT_PIN && size == 1 && !(* value ))
503
+ * value = 0x01 ;
504
+ else if (where == PCI_INTERRUPT_LINE && !(* value & 0xff00 ))
505
+ * value |= 0x0100 ;
506
+
507
+ return PCIBIOS_SUCCESSFUL ;
508
+ }
509
+
510
+ static int aglx_rp_write_cfg (struct altera_pcie * pcie , u8 busno ,
511
+ int where , int size , u32 value )
512
+ {
513
+ void __iomem * addr = AGLX_RP_CFG_ADDR (pcie , where );
514
+
515
+ switch (size ) {
516
+ case 1 :
517
+ writeb_relaxed (value , addr );
518
+ break ;
519
+ case 2 :
520
+ writew_relaxed (value , addr );
521
+ break ;
522
+ default :
523
+ writel_relaxed (value , addr );
524
+ break ;
525
+ }
526
+
527
+ /*
528
+ * Monitor changes to PCI_PRIMARY_BUS register on Root Port
529
+ * and update local copy of root bus number accordingly.
530
+ */
531
+ if (busno == pcie -> root_bus_nr && where == PCI_PRIMARY_BUS )
532
+ pcie -> root_bus_nr = value & 0xff ;
533
+
534
+ return PCIBIOS_SUCCESSFUL ;
535
+ }
536
+
537
+ static int aglx_ep_write_cfg (struct altera_pcie * pcie , u8 busno ,
538
+ unsigned int devfn , int where , int size , u32 value )
539
+ {
540
+ cra_writel (pcie , ((busno << 8 ) | devfn ), AGLX_BDF_REG );
541
+ if (busno > AGLX_RP_SECONDARY (pcie ))
542
+ where |= FIELD_PREP (AGLX_CFG_TARGET , AGLX_CFG_TARGET_TYPE1 );
543
+
544
+ switch (size ) {
545
+ case 1 :
546
+ cra_writeb (pcie , value , where );
547
+ break ;
548
+ case 2 :
549
+ cra_writew (pcie , value , where );
550
+ break ;
551
+ default :
552
+ cra_writel (pcie , value , where );
553
+ break ;
554
+ }
555
+
556
+ return PCIBIOS_SUCCESSFUL ;
557
+ }
558
+
559
+ static int aglx_ep_read_cfg (struct altera_pcie * pcie , u8 busno ,
560
+ unsigned int devfn , int where , int size , u32 * value )
561
+ {
562
+ cra_writel (pcie , ((busno << 8 ) | devfn ), AGLX_BDF_REG );
563
+ if (busno > AGLX_RP_SECONDARY (pcie ))
564
+ where |= FIELD_PREP (AGLX_CFG_TARGET , AGLX_CFG_TARGET_TYPE1 );
565
+
566
+ switch (size ) {
567
+ case 1 :
568
+ * value = cra_readb (pcie , where );
569
+ break ;
570
+ case 2 :
571
+ * value = cra_readw (pcie , where );
572
+ break ;
573
+ default :
574
+ * value = cra_readl (pcie , where );
575
+ break ;
576
+ }
577
+
578
+ return PCIBIOS_SUCCESSFUL ;
579
+ }
580
+
428
581
static int _altera_pcie_cfg_read (struct altera_pcie * pcie , u8 busno ,
429
582
unsigned int devfn , int where , int size ,
430
583
u32 * value )
@@ -437,6 +590,10 @@ static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
437
590
return pcie -> pcie_data -> ops -> rp_read_cfg (pcie , where ,
438
591
size , value );
439
592
593
+ if (pcie -> pcie_data -> ops -> ep_read_cfg )
594
+ return pcie -> pcie_data -> ops -> ep_read_cfg (pcie , busno , devfn ,
595
+ where , size , value );
596
+
440
597
switch (size ) {
441
598
case 1 :
442
599
byte_en = 1 << (where & 3 );
@@ -481,6 +638,10 @@ static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno,
481
638
return pcie -> pcie_data -> ops -> rp_write_cfg (pcie , busno ,
482
639
where , size , value );
483
640
641
+ if (pcie -> pcie_data -> ops -> ep_write_cfg )
642
+ return pcie -> pcie_data -> ops -> ep_write_cfg (pcie , busno , devfn ,
643
+ where , size , value );
644
+
484
645
switch (size ) {
485
646
case 1 :
486
647
data32 = (value & 0xff ) << shift ;
@@ -659,7 +820,32 @@ static void altera_pcie_isr(struct irq_desc *desc)
659
820
dev_err_ratelimited (dev , "unexpected IRQ, INT%d\n" , bit );
660
821
}
661
822
}
823
+ chained_irq_exit (chip , desc );
824
+ }
825
+
826
+ static void aglx_isr (struct irq_desc * desc )
827
+ {
828
+ struct irq_chip * chip = irq_desc_get_chip (desc );
829
+ struct altera_pcie * pcie ;
830
+ struct device * dev ;
831
+ u32 status ;
832
+ int ret ;
833
+
834
+ chained_irq_enter (chip , desc );
835
+ pcie = irq_desc_get_handler_data (desc );
836
+ dev = & pcie -> pdev -> dev ;
837
+
838
+ status = readl (pcie -> hip_base + pcie -> pcie_data -> port_conf_offset +
839
+ pcie -> pcie_data -> port_irq_status_offset );
662
840
841
+ if (status & CFG_AER ) {
842
+ writel (CFG_AER , (pcie -> hip_base + pcie -> pcie_data -> port_conf_offset +
843
+ pcie -> pcie_data -> port_irq_status_offset ));
844
+
845
+ ret = generic_handle_domain_irq (pcie -> irq_domain , 0 );
846
+ if (ret )
847
+ dev_err_ratelimited (dev , "unexpected IRQ %d\n" , pcie -> irq );
848
+ }
663
849
chained_irq_exit (chip , desc );
664
850
}
665
851
@@ -694,9 +880,9 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
694
880
if (IS_ERR (pcie -> cra_base ))
695
881
return PTR_ERR (pcie -> cra_base );
696
882
697
- if (pcie -> pcie_data -> version == ALTERA_PCIE_V2 ) {
698
- pcie -> hip_base =
699
- devm_platform_ioremap_resource_byname (pdev , "Hip" );
883
+ if (pcie -> pcie_data -> version == ALTERA_PCIE_V2 ||
884
+ pcie -> pcie_data -> version == ALTERA_PCIE_V3 ) {
885
+ pcie -> hip_base = devm_platform_ioremap_resource_byname (pdev , "Hip" );
700
886
if (IS_ERR (pcie -> hip_base ))
701
887
return PTR_ERR (pcie -> hip_base );
702
888
}
@@ -706,7 +892,7 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
706
892
if (pcie -> irq < 0 )
707
893
return pcie -> irq ;
708
894
709
- irq_set_chained_handler_and_data (pcie -> irq , altera_pcie_isr , pcie );
895
+ irq_set_chained_handler_and_data (pcie -> irq , pcie -> pcie_data -> ops -> rp_isr , pcie );
710
896
return 0 ;
711
897
}
712
898
@@ -719,6 +905,7 @@ static const struct altera_pcie_ops altera_pcie_ops_1_0 = {
719
905
.tlp_read_pkt = tlp_read_packet ,
720
906
.tlp_write_pkt = tlp_write_packet ,
721
907
.get_link_status = altera_pcie_link_up ,
908
+ .rp_isr = altera_pcie_isr ,
722
909
};
723
910
724
911
static const struct altera_pcie_ops altera_pcie_ops_2_0 = {
@@ -727,6 +914,16 @@ static const struct altera_pcie_ops altera_pcie_ops_2_0 = {
727
914
.get_link_status = s10_altera_pcie_link_up ,
728
915
.rp_read_cfg = s10_rp_read_cfg ,
729
916
.rp_write_cfg = s10_rp_write_cfg ,
917
+ .rp_isr = altera_pcie_isr ,
918
+ };
919
+
920
+ static const struct altera_pcie_ops altera_pcie_ops_3_0 = {
921
+ .rp_read_cfg = aglx_rp_read_cfg ,
922
+ .rp_write_cfg = aglx_rp_write_cfg ,
923
+ .get_link_status = aglx_altera_pcie_link_up ,
924
+ .ep_read_cfg = aglx_ep_read_cfg ,
925
+ .ep_write_cfg = aglx_ep_write_cfg ,
926
+ .rp_isr = aglx_isr ,
730
927
};
731
928
732
929
static const struct altera_pcie_data altera_pcie_1_0_data = {
@@ -749,11 +946,44 @@ static const struct altera_pcie_data altera_pcie_2_0_data = {
749
946
.cfgwr1 = S10_TLP_FMTTYPE_CFGWR1 ,
750
947
};
751
948
949
+ static const struct altera_pcie_data altera_pcie_3_0_f_tile_data = {
950
+ .ops = & altera_pcie_ops_3_0 ,
951
+ .version = ALTERA_PCIE_V3 ,
952
+ .cap_offset = 0x70 ,
953
+ .port_conf_offset = 0x14000 ,
954
+ .port_irq_status_offset = AGLX_ROOT_PORT_IRQ_STATUS ,
955
+ .port_irq_enable_offset = AGLX_ROOT_PORT_IRQ_ENABLE ,
956
+ };
957
+
958
+ static const struct altera_pcie_data altera_pcie_3_0_p_tile_data = {
959
+ .ops = & altera_pcie_ops_3_0 ,
960
+ .version = ALTERA_PCIE_V3 ,
961
+ .cap_offset = 0x70 ,
962
+ .port_conf_offset = 0x104000 ,
963
+ .port_irq_status_offset = AGLX_ROOT_PORT_IRQ_STATUS ,
964
+ .port_irq_enable_offset = AGLX_ROOT_PORT_IRQ_ENABLE ,
965
+ };
966
+
967
+ static const struct altera_pcie_data altera_pcie_3_0_r_tile_data = {
968
+ .ops = & altera_pcie_ops_3_0 ,
969
+ .version = ALTERA_PCIE_V3 ,
970
+ .cap_offset = 0x70 ,
971
+ .port_conf_offset = 0x1300 ,
972
+ .port_irq_status_offset = 0x0 ,
973
+ .port_irq_enable_offset = 0x4 ,
974
+ };
975
+
752
976
static const struct of_device_id altera_pcie_of_match [] = {
753
977
{.compatible = "altr,pcie-root-port-1.0" ,
754
978
.data = & altera_pcie_1_0_data },
755
979
{.compatible = "altr,pcie-root-port-2.0" ,
756
980
.data = & altera_pcie_2_0_data },
981
+ {.compatible = "altr,pcie-root-port-3.0-f-tile" ,
982
+ .data = & altera_pcie_3_0_f_tile_data },
983
+ {.compatible = "altr,pcie-root-port-3.0-p-tile" ,
984
+ .data = & altera_pcie_3_0_p_tile_data },
985
+ {.compatible = "altr,pcie-root-port-3.0-r-tile" ,
986
+ .data = & altera_pcie_3_0_r_tile_data },
757
987
{},
758
988
};
759
989
@@ -791,11 +1021,18 @@ static int altera_pcie_probe(struct platform_device *pdev)
791
1021
return ret ;
792
1022
}
793
1023
794
- /* clear all interrupts */
795
- cra_writel (pcie , P2A_INT_STS_ALL , P2A_INT_STATUS );
796
- /* enable all interrupts */
797
- cra_writel (pcie , P2A_INT_ENA_ALL , P2A_INT_ENABLE );
798
- altera_pcie_host_init (pcie );
1024
+ if (pcie -> pcie_data -> version == ALTERA_PCIE_V1 ||
1025
+ pcie -> pcie_data -> version == ALTERA_PCIE_V2 ) {
1026
+ /* clear all interrupts */
1027
+ cra_writel (pcie , P2A_INT_STS_ALL , P2A_INT_STATUS );
1028
+ /* enable all interrupts */
1029
+ cra_writel (pcie , P2A_INT_ENA_ALL , P2A_INT_ENABLE );
1030
+ altera_pcie_host_init (pcie );
1031
+ } else if (pcie -> pcie_data -> version == ALTERA_PCIE_V3 ) {
1032
+ writel (CFG_AER ,
1033
+ pcie -> hip_base + pcie -> pcie_data -> port_conf_offset +
1034
+ pcie -> pcie_data -> port_irq_enable_offset );
1035
+ }
799
1036
800
1037
bridge -> sysdata = pcie ;
801
1038
bridge -> busnr = pcie -> root_bus_nr ;
0 commit comments