@@ -554,16 +554,13 @@ static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port,
554554 return readl_relaxed (port_rid2sid_addr (port , idx ));
555555}
556556
557- static int apple_pcie_setup_port (struct apple_pcie * pcie ,
557+ static int apple_pcie_setup_link (struct apple_pcie * pcie ,
558+ struct apple_pcie_port * port ,
558559 struct device_node * np )
559560{
560- struct platform_device * platform = to_platform_device (pcie -> dev );
561- struct apple_pcie_port * port ;
562561 struct gpio_desc * reset , * pwren = NULL ;
563- struct resource * res ;
564- char name [16 ];
565- u32 stat , idx ;
566- int ret , i ;
562+ u32 stat ;
563+ int ret ;
567564
568565 reset = devm_fwnode_gpiod_get (pcie -> dev , of_fwnode_handle (np ), "reset" ,
569566 GPIOD_OUT_LOW , "PERST#" );
@@ -579,6 +576,54 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
579576 return PTR_ERR (pwren );
580577 }
581578
579+ rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
580+
581+ /* Assert PERST# before setting up the clock */
582+ gpiod_set_value_cansleep (reset , 1 );
583+
584+ /* Power on the device if required */
585+ gpiod_set_value_cansleep (pwren , 1 );
586+
587+ ret = apple_pcie_setup_refclk (pcie , port );
588+ if (ret < 0 )
589+ return ret ;
590+
591+ /*
592+ * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
593+ * If powering up, the minimal Tpvperl is 100ms
594+ */
595+ if (pwren )
596+ msleep (100 );
597+ else
598+ usleep_range (100 , 200 );
599+
600+ /* Deassert PERST# */
601+ rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
602+ gpiod_set_value_cansleep (reset , 0 );
603+
604+ /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
605+ msleep (100 );
606+
607+ ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
608+ stat & PORT_STATUS_READY , 100 , 250000 );
609+ if (ret < 0 ) {
610+ dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
611+ return ret ;
612+ }
613+
614+ return 0 ;
615+ }
616+
617+ static int apple_pcie_setup_port (struct apple_pcie * pcie ,
618+ struct device_node * np )
619+ {
620+ struct platform_device * platform = to_platform_device (pcie -> dev );
621+ struct apple_pcie_port * port ;
622+ struct resource * res ;
623+ char name [16 ];
624+ u32 link_stat , idx ;
625+ int ret , i ;
626+
582627 port = devm_kzalloc (pcie -> dev , sizeof (* port ), GFP_KERNEL );
583628 if (!port )
584629 return - ENOMEM ;
@@ -614,39 +659,12 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
614659 else
615660 port -> phy = pcie -> base + CORE_PHY_DEFAULT_BASE (port -> idx );
616661
617- rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
618-
619- /* Assert PERST# before setting up the clock */
620- gpiod_set_value_cansleep (reset , 1 );
621-
622- /* Power on the device if required */
623- gpiod_set_value_cansleep (pwren , 1 );
624-
625- ret = apple_pcie_setup_refclk (pcie , port );
626- if (ret < 0 )
627- return ret ;
628-
629- /*
630- * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
631- * If powering up, the minimal Tpvperl is 100ms
632- */
633- if (pwren )
634- msleep (100 );
635- else
636- usleep_range (100 , 200 );
637-
638- /* Deassert PERST# */
639- rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
640- gpiod_set_value_cansleep (reset , 0 );
641-
642- /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
643- msleep (100 );
644-
645- ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
646- stat & PORT_STATUS_READY , 100 , 250000 );
647- if (ret < 0 ) {
648- dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
649- return ret ;
662+ /* link might be already brought up by u-boot, skip setup then */
663+ link_stat = readl_relaxed (port -> base + PORT_LINKSTS );
664+ if (!(link_stat & PORT_LINKSTS_UP )) {
665+ ret = apple_pcie_setup_link (pcie , port , np );
666+ if (ret )
667+ return ret ;
650668 }
651669
652670 if (pcie -> hw -> port_refclk )
@@ -680,6 +698,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
680698 ret = apple_pcie_port_register_irqs (port );
681699 WARN_ON (ret );
682700
701+ if (link_stat & PORT_LINKSTS_UP )
702+ return 0 ;
703+
704+ /* start link training */
683705 writel_relaxed (PORT_LTSSMCTL_START , port -> base + PORT_LTSSMCTL );
684706
685707 if (!wait_for_completion_timeout (& pcie -> event , HZ / 10 ))
0 commit comments