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