2727#include <linux/module.h>
2828#include <linux/msi.h>
2929#include <linux/notifier.h>
30+ #include <linux/of_device.h>
3031#include <linux/of_irq.h>
3132#include <linux/pci-ecam.h>
3233
105106#define PORT_REFCLK_CGDIS BIT(8)
106107#define PORT_PERST 0x00814
107108#define PORT_PERST_OFF BIT(0)
108- #define PORT_RID2SID ( i16 ) ( 0x00828 + 4 * (i16))
109+ #define PORT_RID2SID 0x00828
109110#define PORT_RID2SID_VALID BIT(31)
110111#define PORT_RID2SID_SID_SHIFT 16
111112#define PORT_RID2SID_BUS_SHIFT 8
123124#define PORT_TUNSTAT_PERST_ACK_PEND BIT(1)
124125#define PORT_PREFMEM_ENABLE 0x00994
125126
126- #define MAX_RID2SID 64
127+ #define MAX_RID2SID 512
127128
128129/*
129130 * The doorbell address is set to 0xfffff000, which by convention
134135 */
135136#define DOORBELL_ADDR CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR
136137
138+ struct reg_info {
139+ u32 phy_lane_ctl ;
140+ u32 port_msiaddr ;
141+ u32 port_msiaddr_hi ;
142+ u32 port_refclk ;
143+ u32 port_perst ;
144+ u32 port_rid2sid ;
145+ u32 port_msimap ;
146+ u32 max_rid2sid ;
147+ u32 max_msimap ;
148+ };
149+
150+ const struct reg_info t8103_hw = {
151+ .phy_lane_ctl = PHY_LANE_CTL ,
152+ .port_msiaddr = PORT_MSIADDR ,
153+ .port_msiaddr_hi = 0 ,
154+ .port_refclk = PORT_REFCLK ,
155+ .port_perst = PORT_PERST ,
156+ .port_rid2sid = PORT_RID2SID ,
157+ .port_msimap = 0 ,
158+ .max_rid2sid = 64 ,
159+ .max_msimap = 0 ,
160+ };
161+
162+ #define PORT_T602X_MSIADDR 0x016c
163+ #define PORT_T602X_MSIADDR_HI 0x0170
164+ #define PORT_T602X_PERST 0x082c
165+ #define PORT_T602X_RID2SID 0x3000
166+ #define PORT_T602X_MSIMAP 0x3800
167+
168+ #define PORT_MSIMAP_ENABLE BIT(31)
169+ #define PORT_MSIMAP_TARGET GENMASK(7, 0)
170+
171+ const struct reg_info t602x_hw = {
172+ .phy_lane_ctl = 0 ,
173+ .port_msiaddr = PORT_T602X_MSIADDR ,
174+ .port_msiaddr_hi = PORT_T602X_MSIADDR_HI ,
175+ .port_refclk = 0 ,
176+ .port_perst = PORT_T602X_PERST ,
177+ .port_rid2sid = PORT_T602X_RID2SID ,
178+ .port_msimap = PORT_T602X_MSIMAP ,
179+ .max_rid2sid = 512 , /* 16 on t602x, guess for autodetect on future HW */
180+ .max_msimap = 512 , /* 96 on t602x, guess for autodetect on future HW */
181+ };
182+
183+ static const struct of_device_id apple_pcie_of_match_hw [] = {
184+ { .compatible = "apple,t6020-pcie" , .data = & t602x_hw },
185+ { .compatible = "apple,pcie" , .data = & t8103_hw },
186+ { }
187+ };
188+
137189struct apple_pcie {
138190 struct mutex lock ;
139191 struct device * dev ;
@@ -144,6 +196,7 @@ struct apple_pcie {
144196 struct completion event ;
145197 struct irq_fwspec fwspec ;
146198 u32 nvecs ;
199+ const struct reg_info * hw ;
147200};
148201
149202struct apple_pcie_port {
@@ -267,14 +320,14 @@ static void apple_port_irq_mask(struct irq_data *data)
267320{
268321 struct apple_pcie_port * port = irq_data_get_irq_chip_data (data );
269322
270- writel_relaxed (BIT (data -> hwirq ), port -> base + PORT_INTMSKSET );
323+ rmw_set (BIT (data -> hwirq ), port -> base + PORT_INTMSK );
271324}
272325
273326static void apple_port_irq_unmask (struct irq_data * data )
274327{
275328 struct apple_pcie_port * port = irq_data_get_irq_chip_data (data );
276329
277- writel_relaxed (BIT (data -> hwirq ), port -> base + PORT_INTMSKCLR );
330+ rmw_clear (BIT (data -> hwirq ), port -> base + PORT_INTMSK );
278331}
279332
280333static bool hwirq_is_intx (unsigned int hwirq )
@@ -378,6 +431,7 @@ static void apple_port_irq_handler(struct irq_desc *desc)
378431static int apple_pcie_port_setup_irq (struct apple_pcie_port * port )
379432{
380433 struct fwnode_handle * fwnode = & port -> np -> fwnode ;
434+ struct apple_pcie * pcie = port -> pcie ;
381435 unsigned int irq ;
382436
383437 /* FIXME: consider moving each interrupt under each port */
@@ -393,19 +447,35 @@ static int apple_pcie_port_setup_irq(struct apple_pcie_port *port)
393447 return - ENOMEM ;
394448
395449 /* Disable all interrupts */
396- writel_relaxed (~0 , port -> base + PORT_INTMSKSET );
450+ writel_relaxed (~0 , port -> base + PORT_INTMSK );
397451 writel_relaxed (~0 , port -> base + PORT_INTSTAT );
452+ writel_relaxed (~0 , port -> base + PORT_LINKCMDSTS );
398453
399454 irq_set_chained_handler_and_data (irq , apple_port_irq_handler , port );
400455
401456 /* Configure MSI base address */
402- BUILD_BUG_ON (upper_32_bits (DOORBELL_ADDR ));
403- writel_relaxed (lower_32_bits (DOORBELL_ADDR ), port -> base + PORT_MSIADDR );
457+ BUG_ON (upper_32_bits (DOORBELL_ADDR ));
458+ writel_relaxed (lower_32_bits (DOORBELL_ADDR ),
459+ port -> base + pcie -> hw -> port_msiaddr );
460+ if (pcie -> hw -> port_msiaddr_hi )
461+ writel_relaxed (0 , port -> base + pcie -> hw -> port_msiaddr_hi );
404462
405463 /* Enable MSIs, shared between all ports */
406- writel_relaxed (0 , port -> base + PORT_MSIBASE );
407- writel_relaxed ((ilog2 (port -> pcie -> nvecs ) << PORT_MSICFG_L2MSINUM_SHIFT ) |
408- PORT_MSICFG_EN , port -> base + PORT_MSICFG );
464+ if (pcie -> hw -> port_msimap ) {
465+ int i ;
466+
467+ for (i = 0 ; i < pcie -> nvecs ; i ++ ) {
468+ writel_relaxed (FIELD_PREP (PORT_MSIMAP_TARGET , i ) |
469+ PORT_MSIMAP_ENABLE ,
470+ port -> base + pcie -> hw -> port_msimap + 4 * i );
471+ }
472+
473+ writel_relaxed (PORT_MSICFG_EN , port -> base + PORT_MSICFG );
474+ } else {
475+ writel_relaxed (0 , port -> base + PORT_MSIBASE );
476+ writel_relaxed ((ilog2 (pcie -> nvecs ) << PORT_MSICFG_L2MSINUM_SHIFT ) |
477+ PORT_MSICFG_EN , port -> base + PORT_MSICFG );
478+ }
409479
410480 return 0 ;
411481}
@@ -473,7 +543,9 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie,
473543 u32 stat ;
474544 int res ;
475545
476- rmw_set (PHY_LANE_CTL_CFGACC , port -> phy + PHY_LANE_CTL );
546+ if (pcie -> hw -> phy_lane_ctl )
547+ rmw_set (PHY_LANE_CTL_CFGACC , port -> phy + pcie -> hw -> phy_lane_ctl );
548+
477549 rmw_set (PHY_LANE_CFG_REFCLK0REQ , port -> phy + PHY_LANE_CFG );
478550
479551 res = readl_relaxed_poll_timeout (port -> phy + PHY_LANE_CFG ,
@@ -490,20 +562,23 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie,
490562 if (res < 0 )
491563 return res ;
492564
493- rmw_clear (PHY_LANE_CTL_CFGACC , port -> phy + PHY_LANE_CTL );
565+ if (pcie -> hw -> phy_lane_ctl )
566+ rmw_clear (PHY_LANE_CTL_CFGACC , port -> phy + pcie -> hw -> phy_lane_ctl );
494567
495568 rmw_set (PHY_LANE_CFG_REFCLKEN , port -> phy + PHY_LANE_CFG );
496- rmw_set (PORT_REFCLK_EN , port -> base + PORT_REFCLK );
569+
570+ if (pcie -> hw -> port_refclk )
571+ rmw_set (PORT_REFCLK_EN , port -> base + pcie -> hw -> port_refclk );
497572
498573 return 0 ;
499574}
500575
501576static u32 apple_pcie_rid2sid_write (struct apple_pcie_port * port ,
502577 int idx , u32 val )
503578{
504- writel_relaxed (val , port -> base + PORT_RID2SID ( idx ) );
579+ writel_relaxed (val , port -> base + port -> pcie -> hw -> port_rid2sid + 4 * idx );
505580 /* Read back to ensure completion of the write */
506- return readl_relaxed (port -> base + PORT_RID2SID ( idx ) );
581+ return readl_relaxed (port -> base + port -> pcie -> hw -> port_rid2sid + 4 * idx );
507582}
508583
509584static int apple_pcie_probe_port (struct device_node * np )
@@ -603,7 +678,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
603678 usleep_range (100 , 200 );
604679
605680 /* Deassert PERST# */
606- rmw_set (PORT_PERST_OFF , port -> base + PORT_PERST );
681+ rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
607682 gpiod_set_value_cansleep (reset , 0 );
608683
609684 /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
@@ -616,15 +691,12 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
616691 return ret ;
617692 }
618693
619- rmw_clear (PORT_REFCLK_CGDIS , port -> base + PORT_REFCLK );
620- rmw_clear (PORT_APPCLK_CGDIS , port -> base + PORT_APPCLK );
621-
622694 ret = apple_pcie_port_setup_irq (port );
623695 if (ret )
624696 return ret ;
625697
626698 /* Reset all RID/SID mappings, and check for RAZ/WI registers */
627- for (i = 0 ; i < MAX_RID2SID ; i ++ ) {
699+ for (i = 0 ; i < pcie -> hw -> max_rid2sid ; i ++ ) {
628700 if (apple_pcie_rid2sid_write (port , i , 0xbad1d ) != 0xbad1d )
629701 break ;
630702 apple_pcie_rid2sid_write (port , i , 0 );
@@ -648,6 +720,12 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
648720 if (!wait_for_completion_timeout (& pcie -> event , HZ / 10 ))
649721 dev_warn (pcie -> dev , "%pOF link didn't come up\n" , np );
650722
723+ if (pcie -> hw -> port_refclk )
724+ rmw_clear (PORT_REFCLK_CGDIS , port -> base + PORT_REFCLK );
725+ else
726+ rmw_set (PHY_LANE_CFG_REFCLKCGEN , port -> phy + PHY_LANE_CFG );
727+ rmw_clear (PORT_APPCLK_CGDIS , port -> base + PORT_APPCLK );
728+
651729 return 0 ;
652730}
653731
@@ -764,7 +842,7 @@ static void apple_pcie_release_device(struct apple_pcie_port *port,
764842 for_each_set_bit (idx , port -> sid_map , port -> sid_map_sz ) {
765843 u32 val ;
766844
767- val = readl_relaxed (port -> base + PORT_RID2SID ( idx ) );
845+ val = readl_relaxed (port -> base + port -> pcie -> hw -> port_rid2sid + 4 * idx );
768846 if ((val & 0xffff ) == rid ) {
769847 apple_pcie_rid2sid_write (port , idx , 0 );
770848 bitmap_release_region (port -> sid_map , idx , 0 );
@@ -821,13 +899,19 @@ static int apple_pcie_init(struct pci_config_window *cfg)
821899 struct platform_device * platform = to_platform_device (dev );
822900 struct device_node * of_port ;
823901 struct apple_pcie * pcie ;
902+ const struct of_device_id * match ;
824903 int ret ;
825904
905+ match = of_match_device (apple_pcie_of_match_hw , dev );
906+ if (!match )
907+ return - ENODEV ;
908+
826909 pcie = devm_kzalloc (dev , sizeof (* pcie ), GFP_KERNEL );
827910 if (!pcie )
828911 return - ENOMEM ;
829912
830913 pcie -> dev = dev ;
914+ pcie -> hw = match -> data ;
831915
832916 mutex_init (& pcie -> lock );
833917
@@ -890,6 +974,7 @@ static const struct pci_ecam_ops apple_pcie_cfg_ecam_ops = {
890974};
891975
892976static const struct of_device_id apple_pcie_of_match [] = {
977+ { .compatible = "apple,t6020-pcie" , .data = & apple_pcie_cfg_ecam_ops },
893978 { .compatible = "apple,pcie" , .data = & apple_pcie_cfg_ecam_ops },
894979 { }
895980};
0 commit comments