@@ -576,16 +576,13 @@ static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port,
576576 return readl_relaxed (port_rid2sid_addr (port , idx ));
577577}
578578
579- static int apple_pcie_setup_port (struct apple_pcie * pcie ,
579+ static int apple_pcie_setup_link (struct apple_pcie * pcie ,
580+ struct apple_pcie_port * port ,
580581 struct device_node * np )
581582{
582- struct platform_device * platform = to_platform_device (pcie -> dev );
583- struct apple_pcie_port * port ;
584583 struct gpio_desc * reset , * pwren = NULL ;
585- struct resource * res ;
586- char name [16 ];
587- u32 stat , idx ;
588- int ret , i ;
584+ u32 stat ;
585+ int ret ;
589586
590587 reset = devm_fwnode_gpiod_get (pcie -> dev , of_fwnode_handle (np ), "reset" ,
591588 GPIOD_OUT_LOW , "PERST#" );
@@ -601,6 +598,54 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
601598 return PTR_ERR (pwren );
602599 }
603600
601+ rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
602+
603+ /* Assert PERST# before setting up the clock */
604+ gpiod_set_value_cansleep (reset , 1 );
605+
606+ /* Power on the device if required */
607+ gpiod_set_value_cansleep (pwren , 1 );
608+
609+ ret = apple_pcie_setup_refclk (pcie , port );
610+ if (ret < 0 )
611+ return ret ;
612+
613+ /*
614+ * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
615+ * If powering up, the minimal Tpvperl is 100ms
616+ */
617+ if (pwren )
618+ msleep (100 );
619+ else
620+ usleep_range (100 , 200 );
621+
622+ /* Deassert PERST# */
623+ rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
624+ gpiod_set_value_cansleep (reset , 0 );
625+
626+ /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
627+ msleep (100 );
628+
629+ ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
630+ stat & PORT_STATUS_READY , 100 , 250000 );
631+ if (ret < 0 ) {
632+ dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
633+ return ret ;
634+ }
635+
636+ return 0 ;
637+ }
638+
639+ static int apple_pcie_setup_port (struct apple_pcie * pcie ,
640+ struct device_node * np )
641+ {
642+ struct platform_device * platform = to_platform_device (pcie -> dev );
643+ struct apple_pcie_port * port ;
644+ struct resource * res ;
645+ char name [16 ];
646+ u32 link_stat , idx ;
647+ int ret , i ;
648+
604649 port = devm_kzalloc (pcie -> dev , sizeof (* port ), GFP_KERNEL );
605650 if (!port )
606651 return - ENOMEM ;
@@ -636,39 +681,12 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
636681 else
637682 port -> phy = pcie -> base + CORE_PHY_DEFAULT_BASE (port -> idx );
638683
639- rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
640-
641- /* Assert PERST# before setting up the clock */
642- gpiod_set_value_cansleep (reset , 1 );
643-
644- /* Power on the device if required */
645- gpiod_set_value_cansleep (pwren , 1 );
646-
647- ret = apple_pcie_setup_refclk (pcie , port );
648- if (ret < 0 )
649- return ret ;
650-
651- /*
652- * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
653- * If powering up, the minimal Tpvperl is 100ms
654- */
655- if (pwren )
656- msleep (100 );
657- else
658- usleep_range (100 , 200 );
659-
660- /* Deassert PERST# */
661- rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
662- gpiod_set_value_cansleep (reset , 0 );
663-
664- /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
665- msleep (100 );
666-
667- ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
668- stat & PORT_STATUS_READY , 100 , 250000 );
669- if (ret < 0 ) {
670- dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
671- return ret ;
684+ /* link might be already brought up by u-boot, skip setup then */
685+ link_stat = readl_relaxed (port -> base + PORT_LINKSTS );
686+ if (!(link_stat & PORT_LINKSTS_UP )) {
687+ ret = apple_pcie_setup_link (pcie , port , np );
688+ if (ret )
689+ return ret ;
672690 }
673691
674692 if (pcie -> hw -> port_refclk )
@@ -702,6 +720,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
702720 ret = apple_pcie_port_register_irqs (port );
703721 WARN_ON (ret );
704722
723+ if (link_stat & PORT_LINKSTS_UP )
724+ return 0 ;
725+
726+ /* start link training */
705727 writel_relaxed (PORT_LTSSMCTL_START , port -> base + PORT_LTSSMCTL );
706728
707729 if (!wait_for_completion_timeout (& pcie -> event , HZ / 10 ))
0 commit comments