Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: tegra: Add PCIe PIPE2UPHY support for Tegra234

Synopsys DesignWare core based PCIe controllers in Tegra234 SoC
interface with Universal PHY (UPHY) module through a PIPE2UPHY (P2U)
module. For each PCIe lane of a controller, there is a P2U unit
instantiated at hardware level. This driver provides support for the
programming required for each P2U that is going to be used for a PCIe
controller.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Link: https://lore.kernel.org/r/20220629060435.25297-9-vidyas@nvidia.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Vidya Sagar and committed by
Vinod Koul
de602668 93134b0a

+47 -1
+47 -1
drivers/phy/tegra/phy-tegra194-p2u.c
··· 2 2 /* 3 3 * P2U (PIPE to UPHY) driver for Tegra T194 SoC 4 4 * 5 - * Copyright (C) 2019 NVIDIA Corporation. 5 + * Copyright (C) 2019-2022 NVIDIA Corporation. 6 6 * 7 7 * Author: Vidya Sagar <vidyas@nvidia.com> 8 8 */ ··· 14 14 #include <linux/of_platform.h> 15 15 #include <linux/phy/phy.h> 16 16 17 + #define P2U_CONTROL_CMN 0x74 18 + #define P2U_CONTROL_CMN_SKP_SIZE_PROTECTION_EN BIT(20) 19 + 17 20 #define P2U_PERIODIC_EQ_CTRL_GEN3 0xc0 18 21 #define P2U_PERIODIC_EQ_CTRL_GEN3_PERIODIC_EQ_EN BIT(0) 19 22 #define P2U_PERIODIC_EQ_CTRL_GEN3_INIT_PRESET_EQ_TRAIN_EN BIT(1) ··· 27 24 #define P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_MASK 0xffff 28 25 #define P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_VAL 160 29 26 27 + #define P2U_DIR_SEARCH_CTRL 0xd4 28 + #define P2U_DIR_SEARCH_CTRL_GEN4_FINE_GRAIN_SEARCH_TWICE BIT(18) 29 + 30 + struct tegra_p2u_of_data { 31 + bool one_dir_search; 32 + }; 33 + 30 34 struct tegra_p2u { 31 35 void __iomem *base; 36 + bool skip_sz_protection_en; /* Needed to support two retimers */ 37 + struct tegra_p2u_of_data *of_data; 32 38 }; 33 39 34 40 static inline void p2u_writel(struct tegra_p2u *phy, const u32 value, ··· 56 44 struct tegra_p2u *phy = phy_get_drvdata(x); 57 45 u32 val; 58 46 47 + if (phy->skip_sz_protection_en) { 48 + val = p2u_readl(phy, P2U_CONTROL_CMN); 49 + val |= P2U_CONTROL_CMN_SKP_SIZE_PROTECTION_EN; 50 + p2u_writel(phy, val, P2U_CONTROL_CMN); 51 + } 52 + 59 53 val = p2u_readl(phy, P2U_PERIODIC_EQ_CTRL_GEN3); 60 54 val &= ~P2U_PERIODIC_EQ_CTRL_GEN3_PERIODIC_EQ_EN; 61 55 val |= P2U_PERIODIC_EQ_CTRL_GEN3_INIT_PRESET_EQ_TRAIN_EN; ··· 75 57 val &= ~P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_MASK; 76 58 val |= P2U_RX_DEBOUNCE_TIME_DEBOUNCE_TIMER_VAL; 77 59 p2u_writel(phy, val, P2U_RX_DEBOUNCE_TIME); 60 + 61 + if (phy->of_data->one_dir_search) { 62 + val = p2u_readl(phy, P2U_DIR_SEARCH_CTRL); 63 + val &= ~P2U_DIR_SEARCH_CTRL_GEN4_FINE_GRAIN_SEARCH_TWICE; 64 + p2u_writel(phy, val, P2U_DIR_SEARCH_CTRL); 65 + } 78 66 79 67 return 0; 80 68 } ··· 101 77 if (!phy) 102 78 return -ENOMEM; 103 79 80 + phy->of_data = 81 + (struct tegra_p2u_of_data *)of_device_get_match_data(dev); 82 + if (!phy->of_data) 83 + return -EINVAL; 84 + 104 85 phy->base = devm_platform_ioremap_resource_byname(pdev, "ctl"); 105 86 if (IS_ERR(phy->base)) 106 87 return PTR_ERR(phy->base); 88 + 89 + phy->skip_sz_protection_en = 90 + of_property_read_bool(dev->of_node, 91 + "nvidia,skip-sz-protect-en"); 107 92 108 93 platform_set_drvdata(pdev, phy); 109 94 ··· 129 96 return 0; 130 97 } 131 98 99 + static const struct tegra_p2u_of_data tegra194_p2u_of_data = { 100 + .one_dir_search = false, 101 + }; 102 + 103 + static const struct tegra_p2u_of_data tegra234_p2u_of_data = { 104 + .one_dir_search = true, 105 + }; 106 + 132 107 static const struct of_device_id tegra_p2u_id_table[] = { 133 108 { 134 109 .compatible = "nvidia,tegra194-p2u", 110 + .data = &tegra194_p2u_of_data, 111 + }, 112 + { 113 + .compatible = "nvidia,tegra234-p2u", 114 + .data = &tegra234_p2u_of_data, 135 115 }, 136 116 {} 137 117 };