66 * Description: Altera PCIe host controller driver
77 */
88
9+ #include <linux/bitfield.h>
910#include <linux/delay.h>
1011#include <linux/interrupt.h>
1112#include <linux/irqchip/chained_irq.h>
7778#define S10_TLP_FMTTYPE_CFGWR0 0x45
7879#define S10_TLP_FMTTYPE_CFGWR1 0x44
7980
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+
8096enum altera_pcie_version {
8197 ALTERA_PCIE_V1 = 0 ,
8298 ALTERA_PCIE_V2 ,
99+ ALTERA_PCIE_V3 ,
83100};
84101
85102struct altera_pcie {
@@ -102,6 +119,11 @@ struct altera_pcie_ops {
102119 int size , u32 * value );
103120 int (* rp_write_cfg )(struct altera_pcie * pcie , u8 busno ,
104121 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 );
105127};
106128
107129struct altera_pcie_data {
@@ -112,6 +134,9 @@ struct altera_pcie_data {
112134 u32 cfgrd1 ;
113135 u32 cfgwr0 ;
114136 u32 cfgwr1 ;
137+ u32 port_conf_offset ;
138+ u32 port_irq_status_offset ;
139+ u32 port_irq_enable_offset ;
115140};
116141
117142struct tlp_rp_regpair_t {
@@ -131,6 +156,28 @@ static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg)
131156 return readl_relaxed (pcie -> cra_base + reg );
132157}
133158
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+
134181static bool altera_pcie_link_up (struct altera_pcie * pcie )
135182{
136183 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)
145192 return !!(readw (addr ) & PCI_EXP_LNKSTA_DLLLA );
146193}
147194
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+
148204/*
149205 * Altera PCIe port uses BAR0 of RC's configuration space as the translation
150206 * 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,
425481 return PCIBIOS_SUCCESSFUL ;
426482}
427483
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+
428581static int _altera_pcie_cfg_read (struct altera_pcie * pcie , u8 busno ,
429582 unsigned int devfn , int where , int size ,
430583 u32 * value )
@@ -437,6 +590,10 @@ static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
437590 return pcie -> pcie_data -> ops -> rp_read_cfg (pcie , where ,
438591 size , value );
439592
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+
440597 switch (size ) {
441598 case 1 :
442599 byte_en = 1 << (where & 3 );
@@ -481,6 +638,10 @@ static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno,
481638 return pcie -> pcie_data -> ops -> rp_write_cfg (pcie , busno ,
482639 where , size , value );
483640
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+
484645 switch (size ) {
485646 case 1 :
486647 data32 = (value & 0xff ) << shift ;
@@ -659,7 +820,32 @@ static void altera_pcie_isr(struct irq_desc *desc)
659820 dev_err_ratelimited (dev , "unexpected IRQ, INT%d\n" , bit );
660821 }
661822 }
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 );
662840
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+ }
663849 chained_irq_exit (chip , desc );
664850}
665851
@@ -694,9 +880,9 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
694880 if (IS_ERR (pcie -> cra_base ))
695881 return PTR_ERR (pcie -> cra_base );
696882
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" );
700886 if (IS_ERR (pcie -> hip_base ))
701887 return PTR_ERR (pcie -> hip_base );
702888 }
@@ -706,7 +892,7 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
706892 if (pcie -> irq < 0 )
707893 return pcie -> irq ;
708894
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 );
710896 return 0 ;
711897}
712898
@@ -719,6 +905,7 @@ static const struct altera_pcie_ops altera_pcie_ops_1_0 = {
719905 .tlp_read_pkt = tlp_read_packet ,
720906 .tlp_write_pkt = tlp_write_packet ,
721907 .get_link_status = altera_pcie_link_up ,
908+ .rp_isr = altera_pcie_isr ,
722909};
723910
724911static 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 = {
727914 .get_link_status = s10_altera_pcie_link_up ,
728915 .rp_read_cfg = s10_rp_read_cfg ,
729916 .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 ,
730927};
731928
732929static 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 = {
749946 .cfgwr1 = S10_TLP_FMTTYPE_CFGWR1 ,
750947};
751948
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+
752976static const struct of_device_id altera_pcie_of_match [] = {
753977 {.compatible = "altr,pcie-root-port-1.0" ,
754978 .data = & altera_pcie_1_0_data },
755979 {.compatible = "altr,pcie-root-port-2.0" ,
756980 .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 },
757987 {},
758988};
759989
@@ -791,11 +1021,18 @@ static int altera_pcie_probe(struct platform_device *pdev)
7911021 return ret ;
7921022 }
7931023
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+ }
7991036
8001037 bridge -> sysdata = pcie ;
8011038 bridge -> busnr = pcie -> root_bus_nr ;
0 commit comments