[PATCH v2 1/7] pci: pcie_dw_rockchip: Configure number of lanes and link width speed

Kever Yang kever.yang at rock-chips.com
Wed Sep 27 04:45:25 CEST 2023


On 2023/8/3 03:04, Jonas Karlman wrote:
> Set number of lanes and link width speed control register based on the
> num-lanes property.
>
> Code imported almost 1:1 from dw_pcie_setup in mainline linux.
>
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
> v2:
> - No change
>
>   drivers/pci/pcie_dw_rockchip.c | 58 +++++++++++++++++++++++++++++-----
>   1 file changed, 50 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c
> index 1a35fae5c3a8..bc4635f67136 100644
> --- a/drivers/pci/pcie_dw_rockchip.c
> +++ b/drivers/pci/pcie_dw_rockchip.c
> @@ -18,6 +18,7 @@
>   #include <asm/io.h>
>   #include <asm-generic/gpio.h>
>   #include <dm/device_compat.h>
> +#include <linux/bitfield.h>
>   #include <linux/iopoll.h>
>   #include <linux/delay.h>
>   #include <power/regulator.h>
> @@ -43,6 +44,7 @@ struct rk_pcie {
>   	struct reset_ctl_bulk	rsts;
>   	struct gpio_desc	rst_gpio;
>   	u32		gen;
> +	u32		num_lanes;
>   };
>   
>   /* Parameters for the waiting for iATU enabled routine */
> @@ -152,12 +154,13 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg,
>    * rk_pcie_configure() - Configure link capabilities and speed
>    *
>    * @rk_pcie: Pointer to the PCI controller state
> - * @cap_speed: The capabilities and speed to configure
>    *
>    * Configure the link capabilities and speed in the PCIe root complex.
>    */
> -static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed)
> +static void rk_pcie_configure(struct rk_pcie *pci)
>   {
> +	u32 val;
> +
>   	dw_pcie_dbi_write_enable(&pci->dw, true);
>   
>   	/* Disable BAR 0 and BAR 1 */
> @@ -167,11 +170,49 @@ static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed)
>   	       PCI_BASE_ADDRESS_1);
>   
>   	clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CAPABILITY,
> -			TARGET_LINK_SPEED_MASK, cap_speed);
> +			TARGET_LINK_SPEED_MASK, pci->gen);
>   
>   	clrsetbits_le32(pci->dw.dbi_base + PCIE_LINK_CTL_2,
> -			TARGET_LINK_SPEED_MASK, cap_speed);
> +			TARGET_LINK_SPEED_MASK, pci->gen);
> +
> +	/* Set the number of lanes */
> +	val = readl(pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
> +	val &= ~PORT_LINK_FAST_LINK_MODE;
> +	val |= PORT_LINK_DLL_LINK_EN;
> +	val &= ~PORT_LINK_MODE_MASK;
> +	switch (pci->num_lanes) {
> +	case 1:
> +		val |= PORT_LINK_MODE_1_LANES;
> +		break;
> +	case 2:
> +		val |= PORT_LINK_MODE_2_LANES;
> +		break;
> +	case 4:
> +		val |= PORT_LINK_MODE_4_LANES;
> +		break;
> +	default:
> +		dev_err(pci->dw.dev, "num-lanes %u: invalid value\n", pci->num_lanes);
> +		goto out;
> +	}
> +	writel(val, pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
> +
> +	/* Set link width speed control register */
> +	val = readl(pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
> +	val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
> +	switch (pci->num_lanes) {
> +	case 1:
> +		val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
> +		break;
> +	case 2:
> +		val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
> +		break;
> +	case 4:
> +		val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
> +		break;
> +	}
> +	writel(val, pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
>   
> +out:
>   	dw_pcie_dbi_write_enable(&pci->dw, false);
>   }
>   
> @@ -231,11 +272,10 @@ static int is_link_up(struct rk_pcie *priv)
>    * rk_pcie_link_up() - Wait for the link to come up
>    *
>    * @rk_pcie: Pointer to the PCI controller state
> - * @cap_speed: Desired link speed
>    *
>    * Return: 1 (true) for active line and negetive (false) for no link (timeout)
>    */
> -static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed)
> +static int rk_pcie_link_up(struct rk_pcie *priv)
>   {
>   	int retries;
>   
> @@ -245,7 +285,7 @@ static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed)
>   	}
>   
>   	/* DW pre link configurations */
> -	rk_pcie_configure(priv, cap_speed);
> +	rk_pcie_configure(priv);
>   
>   	rk_pcie_disable_ltssm(priv);
>   	rk_pcie_link_status_clear(priv);
> @@ -341,7 +381,7 @@ static int rockchip_pcie_init_port(struct udevice *dev)
>   	rk_pcie_writel_apb(priv, 0x0, 0xf00040);
>   	pcie_dw_setup_host(&priv->dw);
>   
> -	ret = rk_pcie_link_up(priv, priv->gen);
> +	ret = rk_pcie_link_up(priv);
>   	if (ret < 0)
>   		goto err_link_up;
>   
> @@ -419,6 +459,8 @@ static int rockchip_pcie_parse_dt(struct udevice *dev)
>   	priv->gen = dev_read_u32_default(dev, "max-link-speed",
>   					 LINK_SPEED_GEN_3);
>   
> +	priv->num_lanes = dev_read_u32_default(dev, "num-lanes", 1);
> +
>   	return 0;
>   
>   rockchip_pcie_parse_dt_err_phy_get_by_index:


More information about the U-Boot mailing list