diff options
author | Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com> | 2021-02-19 18:59:29 -0800 |
---|---|---|
committer | Adrian Schmutzler <freifunk@adrianschmutzler.de> | 2021-03-06 11:24:12 +0100 |
commit | eda836e390af2e9f08618dde8e06af851e732a47 (patch) | |
tree | 112baa14e8058067d164a92b81b279a10d1974ce /target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch | |
parent | a9966793e81e1c0f48478ac42ea5bf284927c817 (diff) | |
download | upstream-eda836e390af2e9f08618dde8e06af851e732a47.tar.gz upstream-eda836e390af2e9f08618dde8e06af851e732a47.tar.bz2 upstream-eda836e390af2e9f08618dde8e06af851e732a47.zip |
ramips: 5.10: copy patches from 5.4
Strict copy, no changes made.
Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
Diffstat (limited to 'target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch')
-rw-r--r-- | target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch b/target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch new file mode 100644 index 0000000000..6d84bfdd5b --- /dev/null +++ b/target/linux/ramips/patches-5.10/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch @@ -0,0 +1,272 @@ +From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos <sergio.paracuellos@gmail.com> +Date: Fri, 20 Mar 2020 12:01:19 +0100 +Subject: [PATCH] staging: mt7621-pci-phy: avoid to create to different phys + for a dual port one + +This soc has two phy's for the pcie one of them using just a different +register for settig it up but sharing all the rest of the config. Until +now we was presenting this schema as three different phy's in the device +tree using the 'phy-cells' node property to discriminate an index and +setting up a complete phy for the dual port index. This sometimes worked +properly but reconfiguring the same registers twice presents sometimes +some unstable pcie links and the ports was not properly being detected. +The problems only appears on hard resets and soft resets was properly +working. Instead of having this schema just set two phy's in the device +ree and use the 'phy-cells' property to say if the port has or not a dual +port. Doing this configuration and set up becomes easier, LOC is decreased +and the behaviour also gets deterministic with properly and stable pcie +links in both hard and soft resets. + +Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> +Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 144 ++++++++++-------------- + 1 file changed, 59 insertions(+), 85 deletions(-) + +--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c ++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c +@@ -78,31 +78,21 @@ + #define MAX_PHYS 2 + + /** +- * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device +- * @phy: pointer to the kernel PHY device +- * @port_base: base register +- * @index: internal ID to identify the Mt7621 PCIe PHY +- */ +-struct mt7621_pci_phy_instance { +- struct phy *phy; +- void __iomem *port_base; +- u32 index; +-}; +- +-/** + * struct mt7621_pci_phy - Mt7621 Pcie PHY core + * @dev: pointer to device + * @regmap: kernel regmap pointer +- * @phys: pointer to Mt7621 PHY device +- * @nphys: number of PHY devices for this core ++ * @phy: pointer to the kernel PHY device ++ * @port_base: base register ++ * @has_dual_port: if the phy has dual ports. + * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst' + * needs to be executed. Depends on chip revision. + */ + struct mt7621_pci_phy { + struct device *dev; + struct regmap *regmap; +- struct mt7621_pci_phy_instance **phys; +- int nphys; ++ struct phy *phy; ++ void __iomem *port_base; ++ bool has_dual_port; + bool bypass_pipe_rst; + }; + +@@ -130,23 +120,23 @@ static inline void mt7621_phy_rmw(struct + phy_write(phy, val, reg); + } + +-static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy, +- struct mt7621_pci_phy_instance *instance) ++static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy) + { +- u32 offset = (instance->index != 1) ? +- RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; ++ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST); ++ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC); + +- mt7621_phy_rmw(phy, offset, +- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC, +- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); ++ if (phy->has_dual_port) { ++ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, ++ 0, RG_PE1_PIPE_RST); ++ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, ++ 0, RG_PE1_PIPE_CMD_FRC); ++ } + } + +-static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy, +- struct mt7621_pci_phy_instance *instance) ++static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy) + { + struct device *dev = phy->dev; + u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); +- u32 offset; + + reg = (reg >> 6) & 0x7; + /* Set PCIe Port PHY to disable SSC */ +@@ -156,10 +146,13 @@ static void mt7621_set_phy_for_ssc(struc + RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00)); + + /* disable port */ +- offset = (instance->index != 1) ? +- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; +- mt7621_phy_rmw(phy, offset, +- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); ++ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, ++ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); ++ ++ if (phy->has_dual_port) { ++ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, ++ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); ++ } + + if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ + /* Set Pre-divider ratio (for host mode) */ +@@ -223,43 +216,44 @@ static void mt7621_set_phy_for_ssc(struc + + static int mt7621_pci_phy_init(struct phy *phy) + { +- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); +- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); ++ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + if (mphy->bypass_pipe_rst) +- mt7621_bypass_pipe_rst(mphy, instance); ++ mt7621_bypass_pipe_rst(mphy); + +- mt7621_set_phy_for_ssc(mphy, instance); ++ mt7621_set_phy_for_ssc(mphy); + + return 0; + } + + static int mt7621_pci_phy_power_on(struct phy *phy) + { +- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); +- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); +- u32 offset = (instance->index != 1) ? +- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; ++ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + /* Enable PHY and disable force mode */ +- mt7621_phy_rmw(mphy, offset, +- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, +- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); ++ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, ++ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); ++ ++ if (mphy->has_dual_port) { ++ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, ++ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); ++ } + + return 0; + } + + static int mt7621_pci_phy_power_off(struct phy *phy) + { +- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); +- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); +- u32 offset = (instance->index != 1) ? +- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; ++ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + /* Disable PHY */ +- mt7621_phy_rmw(mphy, offset, +- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, +- RG_PE1_FRC_PHY_EN); ++ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, ++ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); ++ ++ if (mphy->has_dual_port) { ++ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, ++ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); ++ } + + return 0; + } +@@ -282,13 +276,15 @@ static struct phy *mt7621_pcie_phy_of_xl + { + struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev); + +- if (args->args_count == 0) +- return mt7621_phy->phys[0]->phy; +- + if (WARN_ON(args->args[0] >= MAX_PHYS)) + return ERR_PTR(-ENODEV); + +- return mt7621_phy->phys[args->args[0]]->phy; ++ mt7621_phy->has_dual_port = args->args[0]; ++ ++ dev_info(dev, "PHY for 0x%08x (dual port = %d)\n", ++ (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port); ++ ++ return mt7621_phy->phy; + } + + static const struct soc_device_attribute mt7621_pci_quirks_match[] = { +@@ -309,19 +305,11 @@ static int mt7621_pci_phy_probe(struct p + struct phy_provider *provider; + struct mt7621_pci_phy *phy; + struct resource *res; +- int port; +- void __iomem *port_base; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + +- phy->nphys = MAX_PHYS; +- phy->phys = devm_kcalloc(dev, phy->nphys, +- sizeof(*phy->phys), GFP_KERNEL); +- if (!phy->phys) +- return -ENOMEM; +- + attr = soc_device_match(mt7621_pci_quirks_match); + if (attr) + phy->bypass_pipe_rst = true; +@@ -335,39 +323,25 @@ static int mt7621_pci_phy_probe(struct p + return -ENXIO; + } + +- port_base = devm_ioremap_resource(dev, res); +- if (IS_ERR(port_base)) { ++ phy->port_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(phy->port_base)) { + dev_err(dev, "failed to remap phy regs\n"); +- return PTR_ERR(port_base); ++ return PTR_ERR(phy->port_base); + } + +- phy->regmap = devm_regmap_init_mmio(phy->dev, port_base, ++ phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base, + &mt7621_pci_phy_regmap_config); + if (IS_ERR(phy->regmap)) + return PTR_ERR(phy->regmap); + +- for (port = 0; port < MAX_PHYS; port++) { +- struct mt7621_pci_phy_instance *instance; +- struct phy *pphy; +- +- instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); +- if (!instance) +- return -ENOMEM; +- +- phy->phys[port] = instance; +- +- pphy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); +- if (IS_ERR(phy)) { +- dev_err(dev, "failed to create phy\n"); +- return PTR_ERR(phy); +- } +- +- instance->port_base = port_base; +- instance->phy = pphy; +- instance->index = port; +- phy_set_drvdata(pphy, instance); ++ phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "failed to create phy\n"); ++ return PTR_ERR(phy); + } + ++ phy_set_drvdata(phy->phy, phy); ++ + provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate); + + return PTR_ERR_OR_ZERO(provider); |