Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Mediatek MT7621 PCI PHY Driver
0004  * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
0005  */
0006 
0007 #include <dt-bindings/phy/phy.h>
0008 #include <linux/clk.h>
0009 #include <linux/bitfield.h>
0010 #include <linux/bitops.h>
0011 #include <linux/module.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_device.h>
0014 #include <linux/phy/phy.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/regmap.h>
0017 #include <linux/sys_soc.h>
0018 
0019 #define RG_PE1_PIPE_REG             0x02c
0020 #define RG_PE1_PIPE_RST             BIT(12)
0021 #define RG_PE1_PIPE_CMD_FRC         BIT(4)
0022 
0023 #define RG_P0_TO_P1_WIDTH           0x100
0024 #define RG_PE1_H_LCDDS_REG          0x49c
0025 #define RG_PE1_H_LCDDS_PCW          GENMASK(30, 0)
0026 
0027 #define RG_PE1_FRC_H_XTAL_REG           0x400
0028 #define RG_PE1_FRC_H_XTAL_TYPE          BIT(8)
0029 #define RG_PE1_H_XTAL_TYPE          GENMASK(10, 9)
0030 
0031 #define RG_PE1_FRC_PHY_REG          0x000
0032 #define RG_PE1_FRC_PHY_EN           BIT(4)
0033 #define RG_PE1_PHY_EN               BIT(5)
0034 
0035 #define RG_PE1_H_PLL_REG            0x490
0036 #define RG_PE1_H_PLL_BC             GENMASK(23, 22)
0037 #define RG_PE1_H_PLL_BP             GENMASK(21, 18)
0038 #define RG_PE1_H_PLL_IR             GENMASK(15, 12)
0039 #define RG_PE1_H_PLL_IC             GENMASK(11, 8)
0040 #define RG_PE1_H_PLL_PREDIV         GENMASK(7, 6)
0041 #define RG_PE1_PLL_DIVEN            GENMASK(3, 1)
0042 
0043 #define RG_PE1_H_PLL_FBKSEL_REG         0x4bc
0044 #define RG_PE1_H_PLL_FBKSEL         GENMASK(5, 4)
0045 
0046 #define RG_PE1_H_LCDDS_SSC_PRD_REG      0x4a4
0047 #define RG_PE1_H_LCDDS_SSC_PRD          GENMASK(15, 0)
0048 
0049 #define RG_PE1_H_LCDDS_SSC_DELTA_REG        0x4a8
0050 #define RG_PE1_H_LCDDS_SSC_DELTA        GENMASK(11, 0)
0051 #define RG_PE1_H_LCDDS_SSC_DELTA1       GENMASK(27, 16)
0052 
0053 #define RG_PE1_LCDDS_CLK_PH_INV_REG     0x4a0
0054 #define RG_PE1_LCDDS_CLK_PH_INV         BIT(5)
0055 
0056 #define RG_PE1_H_PLL_BR_REG         0x4ac
0057 #define RG_PE1_H_PLL_BR             GENMASK(18, 16)
0058 
0059 #define RG_PE1_MSTCKDIV_REG         0x414
0060 #define RG_PE1_MSTCKDIV             GENMASK(7, 6)
0061 
0062 #define RG_PE1_FRC_MSTCKDIV         BIT(5)
0063 
0064 #define MAX_PHYS    2
0065 
0066 /**
0067  * struct mt7621_pci_phy - Mt7621 Pcie PHY core
0068  * @dev: pointer to device
0069  * @regmap: kernel regmap pointer
0070  * @phy: pointer to the kernel PHY device
0071  * @sys_clk: pointer to the system XTAL clock
0072  * @port_base: base register
0073  * @has_dual_port: if the phy has dual ports.
0074  * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst'
0075  * needs to be executed. Depends on chip revision.
0076  */
0077 struct mt7621_pci_phy {
0078     struct device *dev;
0079     struct regmap *regmap;
0080     struct phy *phy;
0081     struct clk *sys_clk;
0082     void __iomem *port_base;
0083     bool has_dual_port;
0084     bool bypass_pipe_rst;
0085 };
0086 
0087 static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy,
0088                   u32 reg, u32 clr, u32 set)
0089 {
0090     u32 val;
0091 
0092     /*
0093      * We cannot use 'regmap_write_bits' here because internally
0094      * 'set' is masked before is set to the value that will be
0095      * written to the register. That way results in no reliable
0096      * pci setup. Avoid to mask 'set' before set value to 'val'
0097      * completely avoid the problem.
0098      */
0099     regmap_read(phy->regmap, reg, &val);
0100     val &= ~clr;
0101     val |= set;
0102     regmap_write(phy->regmap, reg, val);
0103 }
0104 
0105 static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
0106 {
0107     mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST);
0108     mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC);
0109 
0110     if (phy->has_dual_port) {
0111         mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
0112                    0, RG_PE1_PIPE_RST);
0113         mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
0114                    0, RG_PE1_PIPE_CMD_FRC);
0115     }
0116 }
0117 
0118 static int mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
0119 {
0120     struct device *dev = phy->dev;
0121     unsigned long clk_rate;
0122 
0123     clk_rate = clk_get_rate(phy->sys_clk);
0124     if (!clk_rate)
0125         return -EINVAL;
0126 
0127     /* Set PCIe Port PHY to disable SSC */
0128     /* Debug Xtal Type */
0129     mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
0130                RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE,
0131                RG_PE1_FRC_H_XTAL_TYPE |
0132                FIELD_PREP(RG_PE1_H_XTAL_TYPE, 0x00));
0133 
0134     /* disable port */
0135     mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, RG_PE1_PHY_EN,
0136                RG_PE1_FRC_PHY_EN);
0137 
0138     if (phy->has_dual_port) {
0139         mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
0140                    RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
0141     }
0142 
0143     if (clk_rate == 40000000) { /* 40MHz Xtal */
0144         /* Set Pre-divider ratio (for host mode) */
0145         mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
0146                    FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x01));
0147 
0148         dev_dbg(dev, "Xtal is 40MHz\n");
0149     } else if (clk_rate == 25000000) { /* 25MHz Xal */
0150         mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
0151                    FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00));
0152 
0153         /* Select feedback clock */
0154         mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG,
0155                    RG_PE1_H_PLL_FBKSEL,
0156                    FIELD_PREP(RG_PE1_H_PLL_FBKSEL, 0x01));
0157 
0158         /* DDS NCPO PCW (for host mode) */
0159         mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
0160                    RG_PE1_H_LCDDS_SSC_PRD,
0161                    FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x00));
0162 
0163         /* DDS SSC dither period control */
0164         mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
0165                    RG_PE1_H_LCDDS_SSC_PRD,
0166                    FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x18d));
0167 
0168         /* DDS SSC dither amplitude control */
0169         mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG,
0170                    RG_PE1_H_LCDDS_SSC_DELTA |
0171                    RG_PE1_H_LCDDS_SSC_DELTA1,
0172                    FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA, 0x4a) |
0173                    FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA1, 0x4a));
0174 
0175         dev_dbg(dev, "Xtal is 25MHz\n");
0176     } else { /* 20MHz Xtal */
0177         mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
0178                    FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00));
0179 
0180         dev_dbg(dev, "Xtal is 20MHz\n");
0181     }
0182 
0183     /* DDS clock inversion */
0184     mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG,
0185                RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV);
0186 
0187     /* Set PLL bits */
0188     mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
0189                RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
0190                RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN,
0191                FIELD_PREP(RG_PE1_H_PLL_BC, 0x02) |
0192                FIELD_PREP(RG_PE1_H_PLL_BP, 0x06) |
0193                FIELD_PREP(RG_PE1_H_PLL_IR, 0x02) |
0194                FIELD_PREP(RG_PE1_H_PLL_IC, 0x01) |
0195                FIELD_PREP(RG_PE1_PLL_DIVEN, 0x02));
0196 
0197     mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, RG_PE1_H_PLL_BR,
0198                FIELD_PREP(RG_PE1_H_PLL_BR, 0x00));
0199 
0200     if (clk_rate == 40000000) { /* 40MHz Xtal */
0201         /* set force mode enable of da_pe1_mstckdiv */
0202         mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
0203                    RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
0204                    FIELD_PREP(RG_PE1_MSTCKDIV, 0x01) |
0205                    RG_PE1_FRC_MSTCKDIV);
0206     }
0207 
0208     return 0;
0209 }
0210 
0211 static int mt7621_pci_phy_init(struct phy *phy)
0212 {
0213     struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
0214 
0215     if (mphy->bypass_pipe_rst)
0216         mt7621_bypass_pipe_rst(mphy);
0217 
0218     return mt7621_set_phy_for_ssc(mphy);
0219 }
0220 
0221 static int mt7621_pci_phy_power_on(struct phy *phy)
0222 {
0223     struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
0224 
0225     /* Enable PHY and disable force mode */
0226     mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
0227                RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
0228 
0229     if (mphy->has_dual_port) {
0230         mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
0231                    RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
0232     }
0233 
0234     return 0;
0235 }
0236 
0237 static int mt7621_pci_phy_power_off(struct phy *phy)
0238 {
0239     struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
0240 
0241     /* Disable PHY */
0242     mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
0243                RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
0244 
0245     if (mphy->has_dual_port) {
0246         mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
0247                    RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
0248     }
0249 
0250     return 0;
0251 }
0252 
0253 static int mt7621_pci_phy_exit(struct phy *phy)
0254 {
0255     return 0;
0256 }
0257 
0258 static const struct phy_ops mt7621_pci_phy_ops = {
0259     .init       = mt7621_pci_phy_init,
0260     .exit       = mt7621_pci_phy_exit,
0261     .power_on   = mt7621_pci_phy_power_on,
0262     .power_off  = mt7621_pci_phy_power_off,
0263     .owner      = THIS_MODULE,
0264 };
0265 
0266 static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
0267                         struct of_phandle_args *args)
0268 {
0269     struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
0270 
0271     if (WARN_ON(args->args[0] >= MAX_PHYS))
0272         return ERR_PTR(-ENODEV);
0273 
0274     mt7621_phy->has_dual_port = args->args[0];
0275 
0276     dev_dbg(dev, "PHY for 0x%px (dual port = %d)\n",
0277         mt7621_phy->port_base, mt7621_phy->has_dual_port);
0278 
0279     return mt7621_phy->phy;
0280 }
0281 
0282 static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
0283     { .soc_id = "mt7621", .revision = "E2" }
0284 };
0285 
0286 static const struct regmap_config mt7621_pci_phy_regmap_config = {
0287     .reg_bits = 32,
0288     .val_bits = 32,
0289     .reg_stride = 4,
0290     .max_register = 0x700,
0291 };
0292 
0293 static int mt7621_pci_phy_probe(struct platform_device *pdev)
0294 {
0295     struct device *dev = &pdev->dev;
0296     const struct soc_device_attribute *attr;
0297     struct phy_provider *provider;
0298     struct mt7621_pci_phy *phy;
0299 
0300     phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
0301     if (!phy)
0302         return -ENOMEM;
0303 
0304     attr = soc_device_match(mt7621_pci_quirks_match);
0305     if (attr)
0306         phy->bypass_pipe_rst = true;
0307 
0308     phy->dev = dev;
0309     platform_set_drvdata(pdev, phy);
0310 
0311     phy->port_base = devm_platform_ioremap_resource(pdev, 0);
0312     if (IS_ERR(phy->port_base)) {
0313         dev_err(dev, "failed to remap phy regs\n");
0314         return PTR_ERR(phy->port_base);
0315     }
0316 
0317     phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base,
0318                         &mt7621_pci_phy_regmap_config);
0319     if (IS_ERR(phy->regmap))
0320         return PTR_ERR(phy->regmap);
0321 
0322     phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
0323     if (IS_ERR(phy->phy)) {
0324         dev_err(dev, "failed to create phy\n");
0325         return PTR_ERR(phy->phy);
0326     }
0327 
0328     phy->sys_clk = devm_clk_get(dev, NULL);
0329     if (IS_ERR(phy->sys_clk)) {
0330         dev_err(dev, "failed to get phy clock\n");
0331         return PTR_ERR(phy->sys_clk);
0332     }
0333 
0334     phy_set_drvdata(phy->phy, phy);
0335 
0336     provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate);
0337 
0338     return PTR_ERR_OR_ZERO(provider);
0339 }
0340 
0341 static const struct of_device_id mt7621_pci_phy_ids[] = {
0342     { .compatible = "mediatek,mt7621-pci-phy" },
0343     {},
0344 };
0345 MODULE_DEVICE_TABLE(of, mt7621_pci_phy_ids);
0346 
0347 static struct platform_driver mt7621_pci_phy_driver = {
0348     .probe = mt7621_pci_phy_probe,
0349     .driver = {
0350         .name = "mt7621-pci-phy",
0351         .of_match_table = mt7621_pci_phy_ids,
0352     },
0353 };
0354 
0355 builtin_platform_driver(mt7621_pci_phy_driver);
0356 
0357 MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>");
0358 MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver");
0359 MODULE_LICENSE("GPL v2");