0001
0002
0003
0004
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
0068
0069
0070
0071
0072
0073
0074
0075
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
0094
0095
0096
0097
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
0128
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
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) {
0144
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) {
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
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
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
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
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 {
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
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
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) {
0201
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
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
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");