Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
0004  * Copyright (C) 2018,2019 Lubomir Rintel <lkundrak@v3.sk>
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/phy/phy.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/soc/mmp/cputype.h>
0013 
0014 #define USB2_PLL_REG0       0x4
0015 #define USB2_PLL_REG1       0x8
0016 #define USB2_TX_REG0        0x10
0017 #define USB2_TX_REG1        0x14
0018 #define USB2_TX_REG2        0x18
0019 #define USB2_RX_REG0        0x20
0020 #define USB2_RX_REG1        0x24
0021 #define USB2_RX_REG2        0x28
0022 #define USB2_ANA_REG0       0x30
0023 #define USB2_ANA_REG1       0x34
0024 #define USB2_ANA_REG2       0x38
0025 #define USB2_DIG_REG0       0x3C
0026 #define USB2_DIG_REG1       0x40
0027 #define USB2_DIG_REG2       0x44
0028 #define USB2_DIG_REG3       0x48
0029 #define USB2_TEST_REG0      0x4C
0030 #define USB2_TEST_REG1      0x50
0031 #define USB2_TEST_REG2      0x54
0032 #define USB2_CHARGER_REG0   0x58
0033 #define USB2_OTG_REG0       0x5C
0034 #define USB2_PHY_MON0       0x60
0035 #define USB2_RESETVE_REG0   0x64
0036 #define USB2_ICID_REG0      0x78
0037 #define USB2_ICID_REG1      0x7C
0038 
0039 /* USB2_PLL_REG0 */
0040 
0041 /* This is for Ax stepping */
0042 #define USB2_PLL_FBDIV_SHIFT_MMP3       0
0043 #define USB2_PLL_FBDIV_MASK_MMP3        (0xFF << 0)
0044 
0045 #define USB2_PLL_REFDIV_SHIFT_MMP3      8
0046 #define USB2_PLL_REFDIV_MASK_MMP3       (0xF << 8)
0047 
0048 #define USB2_PLL_VDD12_SHIFT_MMP3       12
0049 #define USB2_PLL_VDD18_SHIFT_MMP3       14
0050 
0051 /* This is for B0 stepping */
0052 #define USB2_PLL_FBDIV_SHIFT_MMP3_B0        0
0053 #define USB2_PLL_REFDIV_SHIFT_MMP3_B0       9
0054 #define USB2_PLL_VDD18_SHIFT_MMP3_B0        14
0055 #define USB2_PLL_FBDIV_MASK_MMP3_B0     0x01FF
0056 #define USB2_PLL_REFDIV_MASK_MMP3_B0        0x3E00
0057 
0058 #define USB2_PLL_CAL12_SHIFT_MMP3       0
0059 #define USB2_PLL_CALI12_MASK_MMP3       (0x3 << 0)
0060 
0061 #define USB2_PLL_VCOCAL_START_SHIFT_MMP3    2
0062 
0063 #define USB2_PLL_KVCO_SHIFT_MMP3        4
0064 #define USB2_PLL_KVCO_MASK_MMP3         (0x7<<4)
0065 
0066 #define USB2_PLL_ICP_SHIFT_MMP3         8
0067 #define USB2_PLL_ICP_MASK_MMP3          (0x7<<8)
0068 
0069 #define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3     12
0070 
0071 #define USB2_PLL_PU_PLL_SHIFT_MMP3      13
0072 #define USB2_PLL_PU_PLL_MASK            (0x1 << 13)
0073 
0074 #define USB2_PLL_READY_MASK_MMP3        (0x1 << 15)
0075 
0076 /* USB2_TX_REG0 */
0077 #define USB2_TX_IMPCAL_VTH_SHIFT_MMP3       8
0078 #define USB2_TX_IMPCAL_VTH_MASK_MMP3        (0x7 << 8)
0079 
0080 #define USB2_TX_RCAL_START_SHIFT_MMP3       13
0081 
0082 /* USB2_TX_REG1 */
0083 #define USB2_TX_CK60_PHSEL_SHIFT_MMP3       0
0084 #define USB2_TX_CK60_PHSEL_MASK_MMP3        (0xf << 0)
0085 
0086 #define USB2_TX_AMP_SHIFT_MMP3          4
0087 #define USB2_TX_AMP_MASK_MMP3           (0x7 << 4)
0088 
0089 #define USB2_TX_VDD12_SHIFT_MMP3        8
0090 #define USB2_TX_VDD12_MASK_MMP3         (0x3 << 8)
0091 
0092 /* USB2_TX_REG2 */
0093 #define USB2_TX_DRV_SLEWRATE_SHIFT      10
0094 
0095 /* USB2_RX_REG0 */
0096 #define USB2_RX_SQ_THRESH_SHIFT_MMP3        4
0097 #define USB2_RX_SQ_THRESH_MASK_MMP3     (0xf << 4)
0098 
0099 #define USB2_RX_SQ_LENGTH_SHIFT_MMP3        10
0100 #define USB2_RX_SQ_LENGTH_MASK_MMP3     (0x3 << 10)
0101 
0102 /* USB2_ANA_REG1*/
0103 #define USB2_ANA_PU_ANA_SHIFT_MMP3      14
0104 
0105 /* USB2_OTG_REG0 */
0106 #define USB2_OTG_PU_OTG_SHIFT_MMP3      3
0107 
0108 struct mmp3_usb_phy {
0109     struct phy *phy;
0110     void __iomem *base;
0111 };
0112 
0113 static unsigned int u2o_get(void __iomem *base, unsigned int offset)
0114 {
0115     return readl_relaxed(base + offset);
0116 }
0117 
0118 static void u2o_set(void __iomem *base, unsigned int offset,
0119         unsigned int value)
0120 {
0121     u32 reg;
0122 
0123     reg = readl_relaxed(base + offset);
0124     reg |= value;
0125     writel_relaxed(reg, base + offset);
0126     readl_relaxed(base + offset);
0127 }
0128 
0129 static void u2o_clear(void __iomem *base, unsigned int offset,
0130         unsigned int value)
0131 {
0132     u32 reg;
0133 
0134     reg = readl_relaxed(base + offset);
0135     reg &= ~value;
0136     writel_relaxed(reg, base + offset);
0137     readl_relaxed(base + offset);
0138 }
0139 
0140 static int mmp3_usb_phy_init(struct phy *phy)
0141 {
0142     struct mmp3_usb_phy *mmp3_usb_phy = phy_get_drvdata(phy);
0143     void __iomem *base = mmp3_usb_phy->base;
0144 
0145     if (cpu_is_mmp3_a0()) {
0146         u2o_clear(base, USB2_PLL_REG0, (USB2_PLL_FBDIV_MASK_MMP3
0147             | USB2_PLL_REFDIV_MASK_MMP3));
0148         u2o_set(base, USB2_PLL_REG0,
0149             0xd << USB2_PLL_REFDIV_SHIFT_MMP3
0150             | 0xf0 << USB2_PLL_FBDIV_SHIFT_MMP3);
0151     } else if (cpu_is_mmp3_b0()) {
0152         u2o_clear(base, USB2_PLL_REG0, USB2_PLL_REFDIV_MASK_MMP3_B0
0153             | USB2_PLL_FBDIV_MASK_MMP3_B0);
0154         u2o_set(base, USB2_PLL_REG0,
0155             0xd << USB2_PLL_REFDIV_SHIFT_MMP3_B0
0156             | 0xf0 << USB2_PLL_FBDIV_SHIFT_MMP3_B0);
0157     } else {
0158         dev_err(&phy->dev, "unsupported silicon revision\n");
0159         return -ENODEV;
0160     }
0161 
0162     u2o_clear(base, USB2_PLL_REG1, USB2_PLL_PU_PLL_MASK
0163         | USB2_PLL_ICP_MASK_MMP3
0164         | USB2_PLL_KVCO_MASK_MMP3
0165         | USB2_PLL_CALI12_MASK_MMP3);
0166     u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_PU_PLL_SHIFT_MMP3
0167         | 1 << USB2_PLL_LOCK_BYPASS_SHIFT_MMP3
0168         | 3 << USB2_PLL_ICP_SHIFT_MMP3
0169         | 3 << USB2_PLL_KVCO_SHIFT_MMP3
0170         | 3 << USB2_PLL_CAL12_SHIFT_MMP3);
0171 
0172     u2o_clear(base, USB2_TX_REG0, USB2_TX_IMPCAL_VTH_MASK_MMP3);
0173     u2o_set(base, USB2_TX_REG0, 2 << USB2_TX_IMPCAL_VTH_SHIFT_MMP3);
0174 
0175     u2o_clear(base, USB2_TX_REG1, USB2_TX_VDD12_MASK_MMP3
0176         | USB2_TX_AMP_MASK_MMP3
0177         | USB2_TX_CK60_PHSEL_MASK_MMP3);
0178     u2o_set(base, USB2_TX_REG1, 3 << USB2_TX_VDD12_SHIFT_MMP3
0179         | 4 << USB2_TX_AMP_SHIFT_MMP3
0180         | 4 << USB2_TX_CK60_PHSEL_SHIFT_MMP3);
0181 
0182     u2o_clear(base, USB2_TX_REG2, 3 << USB2_TX_DRV_SLEWRATE_SHIFT);
0183     u2o_set(base, USB2_TX_REG2, 2 << USB2_TX_DRV_SLEWRATE_SHIFT);
0184 
0185     u2o_clear(base, USB2_RX_REG0, USB2_RX_SQ_THRESH_MASK_MMP3);
0186     u2o_set(base, USB2_RX_REG0, 0xa << USB2_RX_SQ_THRESH_SHIFT_MMP3);
0187 
0188     u2o_set(base, USB2_ANA_REG1, 0x1 << USB2_ANA_PU_ANA_SHIFT_MMP3);
0189 
0190     u2o_set(base, USB2_OTG_REG0, 0x1 << USB2_OTG_PU_OTG_SHIFT_MMP3);
0191 
0192     return 0;
0193 }
0194 
0195 static int mmp3_usb_phy_calibrate(struct phy *phy)
0196 {
0197     struct mmp3_usb_phy *mmp3_usb_phy = phy_get_drvdata(phy);
0198     void __iomem *base = mmp3_usb_phy->base;
0199     int loops;
0200 
0201     /*
0202      * PLL VCO and TX Impedance Calibration Timing:
0203      *
0204      *                _____________________________________
0205      * PU  __________|
0206      *                        _____________________________
0207      * VCOCAL START _________|
0208      *                                 ___
0209      * REG_RCAL_START ________________|   |________|_______
0210      *               | 200us | 400us  | 40| 400us  | USB PHY READY
0211      */
0212 
0213     udelay(200);
0214     u2o_set(base, USB2_PLL_REG1, 1 << USB2_PLL_VCOCAL_START_SHIFT_MMP3);
0215     udelay(400);
0216     u2o_set(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
0217     udelay(40);
0218     u2o_clear(base, USB2_TX_REG0, 1 << USB2_TX_RCAL_START_SHIFT_MMP3);
0219     udelay(400);
0220 
0221     loops = 0;
0222     while ((u2o_get(base, USB2_PLL_REG1) & USB2_PLL_READY_MASK_MMP3) == 0) {
0223         mdelay(1);
0224         loops++;
0225         if (loops > 100) {
0226             dev_err(&phy->dev, "PLL_READY not set after 100mS.\n");
0227             return -ETIMEDOUT;
0228         }
0229     }
0230 
0231     return 0;
0232 }
0233 
0234 static const struct phy_ops mmp3_usb_phy_ops = {
0235     .init       = mmp3_usb_phy_init,
0236     .calibrate  = mmp3_usb_phy_calibrate,
0237     .owner      = THIS_MODULE,
0238 };
0239 
0240 static const struct of_device_id mmp3_usb_phy_of_match[] = {
0241     { .compatible = "marvell,mmp3-usb-phy", },
0242     { },
0243 };
0244 MODULE_DEVICE_TABLE(of, mmp3_usb_phy_of_match);
0245 
0246 static int mmp3_usb_phy_probe(struct platform_device *pdev)
0247 {
0248     struct device *dev = &pdev->dev;
0249     struct mmp3_usb_phy *mmp3_usb_phy;
0250     struct phy_provider *provider;
0251 
0252     mmp3_usb_phy = devm_kzalloc(dev, sizeof(*mmp3_usb_phy), GFP_KERNEL);
0253     if (!mmp3_usb_phy)
0254         return -ENOMEM;
0255 
0256     mmp3_usb_phy->base = devm_platform_ioremap_resource(pdev, 0);
0257     if (IS_ERR(mmp3_usb_phy->base)) {
0258         dev_err(dev, "failed to remap PHY regs\n");
0259         return PTR_ERR(mmp3_usb_phy->base);
0260     }
0261 
0262     mmp3_usb_phy->phy = devm_phy_create(dev, NULL, &mmp3_usb_phy_ops);
0263     if (IS_ERR(mmp3_usb_phy->phy)) {
0264         dev_err(dev, "failed to create PHY\n");
0265         return PTR_ERR(mmp3_usb_phy->phy);
0266     }
0267 
0268     phy_set_drvdata(mmp3_usb_phy->phy, mmp3_usb_phy);
0269     provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0270     if (IS_ERR(provider)) {
0271         dev_err(dev, "failed to register PHY provider\n");
0272         return PTR_ERR(provider);
0273     }
0274 
0275     return 0;
0276 }
0277 
0278 static struct platform_driver mmp3_usb_phy_driver = {
0279     .probe      = mmp3_usb_phy_probe,
0280     .driver     = {
0281         .name   = "mmp3-usb-phy",
0282         .of_match_table = mmp3_usb_phy_of_match,
0283     },
0284 };
0285 module_platform_driver(mmp3_usb_phy_driver);
0286 
0287 MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
0288 MODULE_DESCRIPTION("Marvell MMP3 USB PHY Driver");
0289 MODULE_LICENSE("GPL v2");