@@ -605,15 +605,13 @@ static int apple_pcie_probe_port(struct device_node *np)
605605 return 0 ;
606606}
607607
608- static int apple_pcie_setup_port (struct apple_pcie * pcie ,
608+ static int apple_pcie_setup_link (struct apple_pcie * pcie ,
609+ struct apple_pcie_port * port ,
609610 struct device_node * np )
610611{
611- struct platform_device * platform = to_platform_device (pcie -> dev );
612- struct apple_pcie_port * port ;
613- struct gpio_desc * reset , * pwren = NULL ;
614- u32 stat , idx ;
615- int ret , i ;
616- char name [16 ];
612+ struct gpio_desc * reset , * pwren ;
613+ u32 stat ;
614+ int ret ;
617615
618616 reset = devm_fwnode_gpiod_get (pcie -> dev , of_fwnode_handle (np ), "reset" ,
619617 GPIOD_OUT_LOW , "PERST#" );
@@ -629,32 +627,6 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
629627 return PTR_ERR (pwren );
630628 }
631629
632- port = devm_kzalloc (pcie -> dev , sizeof (* port ), GFP_KERNEL );
633- if (!port )
634- return - ENOMEM ;
635-
636- ret = of_property_read_u32_index (np , "reg" , 0 , & idx );
637- if (ret )
638- return ret ;
639-
640- /* Use the first reg entry to work out the port index */
641- port -> idx = idx >> 11 ;
642- port -> pcie = pcie ;
643- port -> np = np ;
644-
645- snprintf (name , sizeof (name ), "port%d" , port -> idx );
646- port -> base = devm_platform_ioremap_resource_byname (platform , name );
647- if (IS_ERR (port -> base ))
648- port -> base = devm_platform_ioremap_resource (platform , port -> idx + 2 );
649- if (IS_ERR (port -> base )) {
650- return PTR_ERR (port -> base );
651- }
652-
653- snprintf (name , sizeof (name ), "phy%d" , port -> idx );
654- port -> phy = devm_platform_ioremap_resource_byname (platform , name );
655- if (IS_ERR (port -> phy ))
656- port -> phy = pcie -> base + CORE_PHY_DEFAULT_BASE (port -> idx );
657-
658630 rmw_set (PORT_APPCLK_EN , port -> base + PORT_APPCLK );
659631
660632 /* Assert PERST# before setting up the clock */
@@ -690,6 +662,52 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
690662 return ret ;
691663 }
692664
665+ return 0 ;
666+ }
667+
668+ static int apple_pcie_setup_port (struct apple_pcie * pcie ,
669+ struct device_node * np )
670+ {
671+ struct platform_device * platform = to_platform_device (pcie -> dev );
672+ struct apple_pcie_port * port ;
673+ u32 link_stat , idx ;
674+ int ret , i ;
675+ char name [16 ];
676+
677+ port = devm_kzalloc (pcie -> dev , sizeof (* port ), GFP_KERNEL );
678+ if (!port )
679+ return - ENOMEM ;
680+
681+ ret = of_property_read_u32_index (np , "reg" , 0 , & idx );
682+ if (ret )
683+ return ret ;
684+
685+ /* Use the first reg entry to work out the port index */
686+ port -> idx = idx >> 11 ;
687+ port -> pcie = pcie ;
688+ port -> np = np ;
689+
690+ snprintf (name , sizeof (name ), "port%d" , port -> idx );
691+ port -> base = devm_platform_ioremap_resource_byname (platform , name );
692+ if (IS_ERR (port -> base ))
693+ port -> base = devm_platform_ioremap_resource (platform , port -> idx + 2 );
694+ if (IS_ERR (port -> base )) {
695+ return PTR_ERR (port -> base );
696+ }
697+
698+ snprintf (name , sizeof (name ), "phy%d" , port -> idx );
699+ port -> phy = devm_platform_ioremap_resource_byname (platform , name );
700+ if (IS_ERR (port -> phy ))
701+ port -> phy = pcie -> base + CORE_PHY_DEFAULT_BASE (port -> idx );
702+
703+ /* link might be already brought up by u-boot, skip setup then */
704+ link_stat = readl_relaxed (port -> base + PORT_LINKSTS );
705+ if (!(link_stat & PORT_LINKSTS_UP )) {
706+ ret = apple_pcie_setup_link (pcie , port , np );
707+ if (ret )
708+ return ret ;
709+ }
710+
693711 ret = apple_pcie_port_setup_irq (port );
694712 if (ret )
695713 return ret ;
@@ -714,6 +732,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
714732 ret = apple_pcie_port_register_irqs (port );
715733 WARN_ON (ret );
716734
735+ if (link_stat & PORT_LINKSTS_UP )
736+ return 0 ;
737+
738+ /* start link training */
717739 writel_relaxed (PORT_LTSSMCTL_START , port -> base + PORT_LTSSMCTL );
718740
719741 if (!wait_for_completion_timeout (& pcie -> event , HZ / 10 ))
0 commit comments