@@ -550,16 +550,13 @@ static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port,
550550 return readl_relaxed (port_rid2sid_addr (port , idx ));
551551}
552552
553- static int apple_pcie_setup_port (struct apple_pcie * pcie ,
553+ static int apple_pcie_setup_link (struct apple_pcie * pcie ,
554+ struct apple_pcie_port * port ,
554555 struct device_node * np )
555556{
556- struct platform_device * platform = to_platform_device (pcie -> dev );
557- struct apple_pcie_port * port ;
558557 struct gpio_desc * reset , * pwren = NULL ;
559- struct resource * res ;
560- char name [16 ];
561- u32 stat , idx ;
562- int ret , i ;
558+ u32 stat ;
559+ int ret ;
563560
564561 reset = devm_fwnode_gpiod_get (pcie -> dev , of_fwnode_handle (np ), "reset" ,
565562 GPIOD_OUT_LOW , "PERST#" );
@@ -575,6 +572,54 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
575572 return PTR_ERR (pwren );
576573 }
577574
575+ rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
576+
577+ /* Assert PERST# before setting up the clock */
578+ gpiod_set_value_cansleep (reset , 1 );
579+
580+ /* Power on the device if required */
581+ gpiod_set_value_cansleep (pwren , 1 );
582+
583+ ret = apple_pcie_setup_refclk (pcie , port );
584+ if (ret < 0 )
585+ return ret ;
586+
587+ /*
588+ * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
589+ * If powering up, the minimal Tpvperl is 100ms
590+ */
591+ if (pwren )
592+ msleep (100 );
593+ else
594+ usleep_range (100 , 200 );
595+
596+ /* Deassert PERST# */
597+ rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
598+ gpiod_set_value_cansleep (reset , 0 );
599+
600+ /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
601+ msleep (100 );
602+
603+ ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
604+ stat & PORT_STATUS_READY , 100 , 250000 );
605+ if (ret < 0 ) {
606+ dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
607+ return ret ;
608+ }
609+
610+ return 0 ;
611+ }
612+
613+ static int apple_pcie_setup_port (struct apple_pcie * pcie ,
614+ struct device_node * np )
615+ {
616+ struct platform_device * platform = to_platform_device (pcie -> dev );
617+ struct apple_pcie_port * port ;
618+ struct resource * res ;
619+ char name [16 ];
620+ u32 link_stat , idx ;
621+ int ret , i ;
622+
578623 port = devm_kzalloc (pcie -> dev , sizeof (* port ), GFP_KERNEL );
579624 if (!port )
580625 return - ENOMEM ;
@@ -610,39 +655,12 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
610655 else
611656 port -> phy = pcie -> base + CORE_PHY_DEFAULT_BASE (port -> idx );
612657
613- rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
614-
615- /* Assert PERST# before setting up the clock */
616- gpiod_set_value_cansleep (reset , 1 );
617-
618- /* Power on the device if required */
619- gpiod_set_value_cansleep (pwren , 1 );
620-
621- ret = apple_pcie_setup_refclk (pcie , port );
622- if (ret < 0 )
623- return ret ;
624-
625- /*
626- * The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2)
627- * If powering up, the minimal Tpvperl is 100ms
628- */
629- if (pwren )
630- msleep (100 );
631- else
632- usleep_range (100 , 200 );
633-
634- /* Deassert PERST# */
635- rmw_set (PORT_PERST_OFF , port -> base + pcie -> hw -> port_perst );
636- gpiod_set_value_cansleep (reset , 0 );
637-
638- /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
639- msleep (100 );
640-
641- ret = readl_relaxed_poll_timeout (port -> base + PORT_STATUS , stat ,
642- stat & PORT_STATUS_READY , 100 , 250000 );
643- if (ret < 0 ) {
644- dev_err (pcie -> dev , "port %pOF ready wait timeout\n" , np );
645- return ret ;
658+ /* link might be already brought up by u-boot, skip setup then */
659+ link_stat = readl_relaxed (port -> base + PORT_LINKSTS );
660+ if (!(link_stat & PORT_LINKSTS_UP )) {
661+ ret = apple_pcie_setup_link (pcie , port , np );
662+ if (ret )
663+ return ret ;
646664 }
647665
648666 if (pcie -> hw -> port_refclk )
@@ -676,6 +694,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
676694 ret = apple_pcie_port_register_irqs (port );
677695 WARN_ON (ret );
678696
697+ if (link_stat & PORT_LINKSTS_UP )
698+ return 0 ;
699+
700+ /* start link training */
679701 writel_relaxed (PORT_LTSSMCTL_START , port -> base + PORT_LTSSMCTL );
680702
681703 if (!wait_for_completion_timeout (& pcie -> event , HZ / 10 ))
0 commit comments