18
18
* Author: Marc Zyngier <[email protected] >
19
19
*/
20
20
21
+ #include <linux/bitfield.h>
21
22
#include <linux/gpio/consumer.h>
22
23
#include <linux/kernel.h>
23
24
#include <linux/iopoll.h>
29
30
#include <linux/of_irq.h>
30
31
#include <linux/pci-ecam.h>
31
32
33
+ /* T8103 (original M1) and related SoCs */
32
34
#define CORE_RC_PHYIF_CTL 0x00024
33
35
#define CORE_RC_PHYIF_CTL_RUN BIT(0)
34
36
#define CORE_RC_PHYIF_STAT 0x00028
104
106
#define PORT_REFCLK_CGDIS BIT(8)
105
107
#define PORT_PERST 0x00814
106
108
#define PORT_PERST_OFF BIT(0)
107
- #define PORT_RID2SID ( i16 ) ( 0x00828 + 4 * (i16))
109
+ #define PORT_RID2SID 0x00828
108
110
#define PORT_RID2SID_VALID BIT(31)
109
111
#define PORT_RID2SID_SID_SHIFT 16
110
112
#define PORT_RID2SID_BUS_SHIFT 8
122
124
#define PORT_TUNSTAT_PERST_ACK_PEND BIT(1)
123
125
#define PORT_PREFMEM_ENABLE 0x00994
124
126
125
- #define MAX_RID2SID 64
127
+ #define PORT_MSIMAP_ENABLE BIT(31)
128
+ #define PORT_MSIMAP_TARGET GENMASK(7, 0)
126
129
127
130
/*
128
131
* The doorbell address is set to 0xfffff000, which by convention
133
136
*/
134
137
#define DOORBELL_ADDR CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR
135
138
139
+ struct hw_info {
140
+ u32 phy_lane_ctl ;
141
+ u32 port_msiaddr ;
142
+ u32 port_msiaddr_hi ;
143
+ u32 port_refclk ;
144
+ u32 port_perst ;
145
+ u32 port_rid2sid ;
146
+ u32 port_msimap ;
147
+ u32 max_rid2sid ;
148
+ };
149
+
150
+ static const struct hw_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
+ };
160
+
136
161
struct apple_pcie {
137
162
struct mutex lock ;
138
163
struct device * dev ;
139
164
void __iomem * base ;
165
+ const struct hw_info * hw ;
140
166
struct irq_domain * domain ;
141
167
unsigned long * bitmap ;
142
168
struct list_head ports ;
@@ -380,7 +406,9 @@ static void apple_port_irq_handler(struct irq_desc *desc)
380
406
static int apple_pcie_port_setup_irq (struct apple_pcie_port * port )
381
407
{
382
408
struct fwnode_handle * fwnode = & port -> np -> fwnode ;
409
+ struct apple_pcie * pcie = port -> pcie ;
383
410
unsigned int irq ;
411
+ u32 val = 0 ;
384
412
385
413
/* FIXME: consider moving each interrupt under each port */
386
414
irq = irq_of_parse_and_map (to_of_node (dev_fwnode (port -> pcie -> dev )),
@@ -402,13 +430,23 @@ static int apple_pcie_port_setup_irq(struct apple_pcie_port *port)
402
430
403
431
/* Configure MSI base address */
404
432
BUILD_BUG_ON (upper_32_bits (DOORBELL_ADDR ));
405
- writel_relaxed (lower_32_bits (DOORBELL_ADDR ), port -> base + PORT_MSIADDR );
433
+ writel_relaxed (lower_32_bits (DOORBELL_ADDR ),
434
+ port -> base + pcie -> hw -> port_msiaddr );
435
+ if (pcie -> hw -> port_msiaddr_hi )
436
+ writel_relaxed (0 , port -> base + pcie -> hw -> port_msiaddr_hi );
406
437
407
438
/* Enable MSIs, shared between all ports */
408
- writel_relaxed (0 , port -> base + PORT_MSIBASE );
409
- writel_relaxed ((ilog2 (port -> pcie -> nvecs ) << PORT_MSICFG_L2MSINUM_SHIFT ) |
410
- PORT_MSICFG_EN , port -> base + PORT_MSICFG );
439
+ if (pcie -> hw -> port_msimap ) {
440
+ for (int i = 0 ; i < pcie -> nvecs ; i ++ )
441
+ writel_relaxed (FIELD_PREP (PORT_MSIMAP_TARGET , i ) |
442
+ PORT_MSIMAP_ENABLE ,
443
+ port -> base + pcie -> hw -> port_msimap + 4 * i );
444
+ } else {
445
+ writel_relaxed (0 , port -> base + PORT_MSIBASE );
446
+ val = ilog2 (pcie -> nvecs ) << PORT_MSICFG_L2MSINUM_SHIFT ;
447
+ }
411
448
449
+ writel_relaxed (val | PORT_MSICFG_EN , port -> base + PORT_MSICFG );
412
450
return 0 ;
413
451
}
414
452
@@ -475,7 +513,9 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie,
475
513
u32 stat ;
476
514
int res ;
477
515
478
- rmw_set (PHY_LANE_CTL_CFGACC , port -> phy + PHY_LANE_CTL );
516
+ if (pcie -> hw -> phy_lane_ctl )
517
+ rmw_set (PHY_LANE_CTL_CFGACC , port -> phy + pcie -> hw -> phy_lane_ctl );
518
+
479
519
rmw_set (PHY_LANE_CFG_REFCLK0REQ , port -> phy + PHY_LANE_CFG );
480
520
481
521
res = readl_relaxed_poll_timeout (port -> phy + PHY_LANE_CFG ,
@@ -492,20 +532,28 @@ static int apple_pcie_setup_refclk(struct apple_pcie *pcie,
492
532
if (res < 0 )
493
533
return res ;
494
534
495
- rmw_clear (PHY_LANE_CTL_CFGACC , port -> phy + PHY_LANE_CTL );
535
+ if (pcie -> hw -> phy_lane_ctl )
536
+ rmw_clear (PHY_LANE_CTL_CFGACC , port -> phy + pcie -> hw -> phy_lane_ctl );
496
537
497
538
rmw_set (PHY_LANE_CFG_REFCLKEN , port -> phy + PHY_LANE_CFG );
498
- rmw_set (PORT_REFCLK_EN , port -> base + PORT_REFCLK );
539
+
540
+ if (pcie -> hw -> port_refclk )
541
+ rmw_set (PORT_REFCLK_EN , port -> base + pcie -> hw -> port_refclk );
499
542
500
543
return 0 ;
501
544
}
502
545
546
+ static void __iomem * port_rid2sid_addr (struct apple_pcie_port * port , int idx )
547
+ {
548
+ return port -> base + port -> pcie -> hw -> port_rid2sid + 4 * idx ;
549
+ }
550
+
503
551
static u32 apple_pcie_rid2sid_write (struct apple_pcie_port * port ,
504
552
int idx , u32 val )
505
553
{
506
- writel_relaxed (val , port -> base + PORT_RID2SID ( idx ));
554
+ writel_relaxed (val , port_rid2sid_addr ( port , idx ));
507
555
/* Read back to ensure completion of the write */
508
- return readl_relaxed (port -> base + PORT_RID2SID ( idx ));
556
+ return readl_relaxed (port_rid2sid_addr ( port , idx ));
509
557
}
510
558
511
559
static int apple_pcie_setup_port (struct apple_pcie * pcie ,
@@ -528,7 +576,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
528
576
if (!port )
529
577
return - ENOMEM ;
530
578
531
- port -> sid_map = devm_bitmap_zalloc (pcie -> dev , MAX_RID2SID , GFP_KERNEL );
579
+ port -> sid_map = devm_bitmap_zalloc (pcie -> dev , pcie -> hw -> max_rid2sid , GFP_KERNEL );
532
580
if (!port -> sid_map )
533
581
return - ENOMEM ;
534
582
@@ -572,7 +620,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
572
620
usleep_range (100 , 200 );
573
621
574
622
/* Deassert PERST# */
575
- rmw_set (PORT_PERST_OFF , port -> base + PORT_PERST );
623
+ rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
576
624
gpiod_set_value_cansleep (reset , 0 );
577
625
578
626
/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
@@ -585,15 +633,19 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
585
633
return ret ;
586
634
}
587
635
588
- rmw_clear (PORT_REFCLK_CGDIS , port -> base + PORT_REFCLK );
636
+ if (pcie -> hw -> port_refclk )
637
+ rmw_clear (PORT_REFCLK_CGDIS , port -> base + pcie -> hw -> port_refclk );
638
+ else
639
+ rmw_set (PHY_LANE_CFG_REFCLKCGEN , port -> phy + PHY_LANE_CFG );
640
+
589
641
rmw_clear (PORT_APPCLK_CGDIS , port -> base + PORT_APPCLK );
590
642
591
643
ret = apple_pcie_port_setup_irq (port );
592
644
if (ret )
593
645
return ret ;
594
646
595
647
/* Reset all RID/SID mappings, and check for RAZ/WI registers */
596
- for (i = 0 ; i < MAX_RID2SID ; i ++ ) {
648
+ for (i = 0 ; i < pcie -> hw -> max_rid2sid ; i ++ ) {
597
649
if (apple_pcie_rid2sid_write (port , i , 0xbad1d ) != 0xbad1d )
598
650
break ;
599
651
apple_pcie_rid2sid_write (port , i , 0 );
@@ -741,7 +793,7 @@ static void apple_pcie_disable_device(struct pci_host_bridge *bridge, struct pci
741
793
for_each_set_bit (idx , port -> sid_map , port -> sid_map_sz ) {
742
794
u32 val ;
743
795
744
- val = readl_relaxed (port -> base + PORT_RID2SID ( idx ));
796
+ val = readl_relaxed (port_rid2sid_addr ( port , idx ));
745
797
if ((val & 0xffff ) == rid ) {
746
798
apple_pcie_rid2sid_write (port , idx , 0 );
747
799
bitmap_release_region (port -> sid_map , idx , 0 );
@@ -792,6 +844,9 @@ static int apple_pcie_probe(struct platform_device *pdev)
792
844
return - ENOMEM ;
793
845
794
846
pcie -> dev = dev ;
847
+ pcie -> hw = of_device_get_match_data (dev );
848
+ if (!pcie -> hw )
849
+ return - ENODEV ;
795
850
pcie -> base = devm_platform_ioremap_resource (pdev , 1 );
796
851
if (IS_ERR (pcie -> base ))
797
852
return PTR_ERR (pcie -> base );
@@ -808,7 +863,7 @@ static int apple_pcie_probe(struct platform_device *pdev)
808
863
}
809
864
810
865
static const struct of_device_id apple_pcie_of_match [] = {
811
- { .compatible = "apple,pcie" },
866
+ { .compatible = "apple,pcie" , . data = & t8103_hw },
812
867
{ }
813
868
};
814
869
MODULE_DEVICE_TABLE (of , apple_pcie_of_match );
0 commit comments